-
Notifications
You must be signed in to change notification settings - Fork 3.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This PR adds a MERGING index descriptor state. This state is similar to DELETE_AND_WRITE_ONLY, but all writes are handled via Put, even in cases where they would typically used CPut or InitPut. This change is in support of the mvcc-compatible index backfiller. As part of the backfill process, newly added indexes will be added in a BACKFILLING state in which they see no writes or deletes. However, this would allow for the following sequence of events. For simplicity, the delete-preserving temporary index state transitions have been elided: t0: `CREATE UNIQUE INDEX` creates "new index" in BACKFILLING state and a delete-preserving "temp index" t1: `INSERT INTO` with a = 1 (new index does not see this write) t2: Backfill starts at t1 (a=1 included in backfill, ends up in "new index") t3: UPDATE a = 2 where a = 1 (new index still in backfilling does not see these writes) t4: Backfilling completes t5: "new index" to DELETE-ONLY t6: "new index" to DELETE-AND-WRITE-ONLY t7: `INSERT INTO` into with a = 1 t8: a = 2 merged from "temp index" into "new index" Unfortunately, at t7 the user would encounter an erroneous duplicate key violation when they attempt their insert because the attempted CPut into "new index" would fail as there is an existing value (a=1). The correct value of a=2 will not be written into "new index" until a follow-up merge pass that occurs at t8. The MERGING phase is intended to solve this problem by allowing for the following sequence: t0: `CREATE UNIQUE INDEX` creates "new index" in BACKFILLING state and a delete-preserving "temp index" t1: `INSERT INTO` with a = 1 (new index does not see this write) t2: Backfill starts at t1 (a=1 included in backfill, ends up in "new index") t3: UPDATE a = 2 where a = 1 (new index still in backfilling does not see these writes) t4: Backfilling completes t5: "new index" to DELETE-ONLY t5: "new index" to MERGING t7: `INSERT INTO` into with a = 1 t8: a = 2 merged from "temp index" into "new index" t9: "new index" to DELETE-AND-WRITE-ONLY Note that while in the MERGING state, the new index may accumulate duplicate keys. This is OK because it will be checked for uniqueness before being brought online. The tests added here are nearly identical to the tests added for DeletePreservingEncoding but have been written using a small data-drive test that supports putting indexes into a mutated state. Release note: None
- Loading branch information
1 parent
c4f15d6
commit 0ee2977
Showing
11 changed files
with
456 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
// Copyright 2022 The Cockroach Authors. | ||
// | ||
// Use of this software is governed by the Business Source License | ||
// included in the file licenses/BSL.txt. | ||
// | ||
// As of the Change Date specified in that file, in accordance with | ||
// the Business Source License, use of this software will be governed | ||
// by the Apache License, Version 2.0, included in the file | ||
// licenses/APL.txt. | ||
|
||
package sql_test | ||
|
||
import ( | ||
"context" | ||
gosql "database/sql" | ||
"fmt" | ||
"strings" | ||
"testing" | ||
|
||
"github.com/cockroachdb/cockroach/pkg/jobs" | ||
"github.com/cockroachdb/cockroach/pkg/sql" | ||
"github.com/cockroachdb/cockroach/pkg/sql/catalog/descpb" | ||
"github.com/cockroachdb/cockroach/pkg/sql/catalog/desctestutils" | ||
"github.com/cockroachdb/cockroach/pkg/sql/catalog/lease" | ||
"github.com/cockroachdb/cockroach/pkg/sql/tests" | ||
"github.com/cockroachdb/cockroach/pkg/testutils" | ||
"github.com/cockroachdb/cockroach/pkg/testutils/serverutils" | ||
"github.com/cockroachdb/cockroach/pkg/util/leaktest" | ||
"github.com/cockroachdb/cockroach/pkg/util/log" | ||
"github.com/cockroachdb/datadriven" | ||
"github.com/stretchr/testify/require" | ||
) | ||
|
||
// TestMerginIndexKVOps is another poor-man's logictest that assert | ||
// that indexes in the MERGING state do not see CPuts or InitPuts. | ||
func TestMergingIndexKVOps(t *testing.T) { | ||
defer leaktest.AfterTest(t)() | ||
defer log.Scope(t).Close(t) | ||
ctx := context.Background() | ||
|
||
defer lease.TestingDisableTableLeases()() | ||
|
||
params, _ := tests.CreateTestServerParams() | ||
// Decrease the adopt loop interval so that retries happen quickly. | ||
params.Knobs.JobsTestingKnobs = jobs.NewTestingKnobsWithShortIntervals() | ||
s, sqlDB, kvDB := serverutils.StartServer(t, params) | ||
defer s.Stopper().Stop(ctx) | ||
|
||
_, err := sqlDB.Exec("CREATE DATABASE t; USE t") | ||
require.NoError(t, err) | ||
datadriven.Walk(t, testutils.TestDataPath(t, "index_mutations"), func(t *testing.T, path string) { | ||
datadriven.RunTest(t, path, func(t *testing.T, td *datadriven.TestData) string { | ||
switch td.Cmd { | ||
case "mutate-index": | ||
if len(td.CmdArgs) < 3 { | ||
td.Fatalf(t, "mutate-index requires at least an index name and a state") | ||
} | ||
tableName := td.CmdArgs[0].Key | ||
name := td.CmdArgs[1].Key | ||
stateStr := strings.ToUpper(td.CmdArgs[2].Key) | ||
state := descpb.DescriptorMutation_State(descpb.DescriptorMutation_State_value[stateStr]) | ||
|
||
codec := s.ExecutorConfig().(sql.ExecutorConfig).Codec | ||
tableDesc := desctestutils.TestingGetMutableExistingTableDescriptor(kvDB, codec, "t", tableName) | ||
err = mutateIndexByName(kvDB, codec, tableDesc, name, nil, state) | ||
require.NoError(t, err) | ||
case "statement": | ||
_, err := sqlDB.Exec(td.Input) | ||
require.NoError(t, err) | ||
case "kvtrace": | ||
_, err := sqlDB.Exec("SET TRACING=on,kv") | ||
require.NoError(t, err) | ||
_, err = sqlDB.Exec(td.Input) | ||
require.NoError(t, err) | ||
_, err = sqlDB.Exec("SET TRACING=off") | ||
require.NoError(t, err) | ||
return getKVTrace(t, sqlDB) | ||
default: | ||
td.Fatalf(t, "unknown directive: %s", td.Cmd) | ||
} | ||
return "" | ||
}) | ||
}) | ||
} | ||
|
||
func getKVTrace(t *testing.T, db *gosql.DB) string { | ||
// These are the same KVOps looked at by logictest. | ||
allowedKVOpTypes := []string{ | ||
"CPut", | ||
"Put", | ||
"InitPut", | ||
"Del", | ||
"DelRange", | ||
"ClearRange", | ||
"Get", | ||
"Scan", | ||
} | ||
var sb strings.Builder | ||
sb.WriteString("SELECT message FROM [SHOW KV TRACE FOR SESSION] WHERE ") | ||
for i, op := range allowedKVOpTypes { | ||
if i != 0 { | ||
sb.WriteString("OR ") | ||
} | ||
sb.WriteString(fmt.Sprintf("message like '%s%%'", op)) | ||
} | ||
traceMessagesQuery := sb.String() | ||
|
||
rows, err := db.Query(traceMessagesQuery) | ||
require.NoError(t, err) | ||
|
||
var trace strings.Builder | ||
for rows.Next() { | ||
var s string | ||
require.NoError(t, rows.Scan(&s)) | ||
trace.WriteString(s) | ||
trace.WriteRune('\n') | ||
} | ||
require.NoError(t, rows.Err()) | ||
return trace.String() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.