Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multi-tenant migrations: add topo locking while updating keyspace routing rules #15807

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
d716243
Add keyspace routing rules lock. Use it while updating rules
rohit-nayak-ps Apr 27, 2024
bc1512d
More tests. Refactor
rohit-nayak-ps Apr 28, 2024
f5ae07c
Fix locking logic and related tests
rohit-nayak-ps Apr 28, 2024
50cc2b6
Refactor topo lock, remove unnecessary stuff
rohit-nayak-ps Apr 29, 2024
0c935d6
More cleanup
rohit-nayak-ps Apr 29, 2024
254aa1d
Single entry point for serializing all functionalities updating keysp…
rohit-nayak-ps Apr 30, 2024
cc8b452
Delete keyspace routing rules on Cancel
rohit-nayak-ps Apr 30, 2024
6f711b1
Add test to confirm that concurrent updates don't overwrite each other
rohit-nayak-ps May 1, 2024
a3b761f
Update reasons for generic locking
rohit-nayak-ps May 1, 2024
5f1e8ec
Reformat exports
rohit-nayak-ps May 1, 2024
682b00c
Add concurrency tests for a specific topo to confirm that it works fo…
rohit-nayak-ps May 2, 2024
5e27c79
Address review comments. Change the key paths where rules and locks a…
rohit-nayak-ps May 5, 2024
8047f35
Modify comments/logs to reflect the sentinel nomenclature
rohit-nayak-ps May 5, 2024
f639c60
Playing with some ideas
mattlord May 6, 2024
6119992
Fix unit tests
mattlord May 6, 2024
23dc487
Still working on tests
mattlord May 6, 2024
b0aef45
Revert matt's testing / investigation work
mattlord May 6, 2024
70b59d4
Address review comment: Remove space from name
rohit-nayak-ps May 8, 2024
74e16ed
Address review comment: remove export of global cell. Move key creati…
rohit-nayak-ps May 8, 2024
506475f
Address Review Comment: rename updateKeyspaceRoutingRule to updateKey…
rohit-nayak-ps May 8, 2024
c993e8c
Change the mechanism of updating keyspace routing rules under the loc…
rohit-nayak-ps May 8, 2024
7b90ed6
Change topo paths for keyspace routing rules
rohit-nayak-ps May 9, 2024
6452e4c
Change ApplyKeyspaceRoutingRules to return current and new rules. Add…
rohit-nayak-ps May 9, 2024
de3b3e9
Minor refactor of cli command
rohit-nayak-ps May 10, 2024
309f594
Minor refactor
rohit-nayak-ps May 10, 2024
5ecdafc
Add tests for krr
rohit-nayak-ps May 10, 2024
a9c4574
Confirm that we hold the lock while saving keyspace routing rules. Ad…
rohit-nayak-ps May 10, 2024
461a0b6
Delete map better!
rohit-nayak-ps May 10, 2024
f483725
Move setting response parameters to the vtctld server instead of on t…
rohit-nayak-ps May 11, 2024
8a22e7e
My suggestions
mattlord May 11, 2024
7f59799
Don't send old rules on ApplyKeyspaceRoutingRules
rohit-nayak-ps May 13, 2024
a696c1e
Merge remote-tracking branch 'planetscale/rohit/multi-tenant-routing-…
mattlord May 13, 2024
3b08add
Post merge fixups
mattlord May 13, 2024
0c84ec1
Another minor cleanup after merge + review
mattlord May 13, 2024
e65f861
Try to deflake unit test when code coverage is enabled
mattlord May 14, 2024
c468c8d
Skip TestConcurrentKeyspaceRoutingRulesUpdates in code coverage mode
rohit-nayak-ps May 14, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
24 changes: 11 additions & 13 deletions go/cmd/vtctldclient/command/keyspace_routing_rules.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,6 @@ var applyKeyspaceRoutingRulesOptions = struct {
func commandApplyKeyspaceRoutingRules(cmd *cobra.Command, args []string) error {
opts := applyKeyspaceRoutingRulesOptions
cli.FinishedParsing(cmd)

var rulesBytes []byte
if opts.RulesFilePath != "" {
data, err := os.ReadFile(opts.RulesFilePath)
Expand All @@ -86,13 +85,14 @@ func commandApplyKeyspaceRoutingRules(cmd *cobra.Command, args []string) error {
if err := json2.Unmarshal(rulesBytes, &krr); err != nil {
return err
}
// Round-trip so that when we display the result it's readable.
data, err := cli.MarshalJSON(krr)
if err != nil {
return err
}

if opts.DryRun {
// Round-trip so that when we display the result it's readable.
data, err := cli.MarshalJSON(krr)
if err != nil {
return err
}

fmt.Printf("[DRY RUN] Would have saved new KeyspaceRoutingRules object:\n%s\n", data)

if opts.SkipRebuild {
Expand All @@ -105,11 +105,10 @@ func commandApplyKeyspaceRoutingRules(cmd *cobra.Command, args []string) error {
fmt.Printf(" in the following cells: %s.\n", strings.Join(applyKeyspaceRoutingRulesOptions.Cells, ", "))
}
}

return nil
}

_, err = client.ApplyKeyspaceRoutingRules(commandCtx, &vtctldatapb.ApplyKeyspaceRoutingRulesRequest{
resp, err := client.ApplyKeyspaceRoutingRules(commandCtx, &vtctldatapb.ApplyKeyspaceRoutingRulesRequest{
rohit-nayak-ps marked this conversation as resolved.
Show resolved Hide resolved
KeyspaceRoutingRules: krr,
SkipRebuild: opts.SkipRebuild,
RebuildCells: opts.Cells,
Expand All @@ -118,12 +117,11 @@ func commandApplyKeyspaceRoutingRules(cmd *cobra.Command, args []string) error {
return err
}

fmt.Printf("New KeyspaceRoutingRules object:\n%s\nIf this is not what you expected, check the input data (as JSON parsing will skip unexpected fields).\n", data)

if opts.SkipRebuild {
fmt.Println("Skipping rebuild of VSchema graph as requested, you will need to run RebuildVSchemaGraph for the changes to take effect.")
respJSON, err := cli.MarshalJSON(resp)
if err != nil {
return err
}

fmt.Printf("%s\n", respJSON)
return nil
}

Expand Down
48 changes: 43 additions & 5 deletions go/test/endtoend/vreplication/multi_tenant_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,14 @@ import (
"testing"
"time"

"google.golang.org/protobuf/encoding/protojson"

"github.com/stretchr/testify/require"
"google.golang.org/protobuf/encoding/protojson"

"vitess.io/vitess/go/vt/log"
"vitess.io/vitess/go/vt/proto/vtctldata"

binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata"
vschemapb "vitess.io/vitess/go/vt/proto/vschema"
"vitess.io/vitess/go/vt/proto/vtctldata"
)

type tenantMigrationStatus int
Expand All @@ -71,6 +71,8 @@ var (
chNotSetup, chNotCreated, chInProgress, chSwitched, chCompleted chan int64
// counters to keep track of the number of tenants in each state
numSetup, numInProgress, numSwitched, numCompleted atomic.Int64

emptyKeyspaceRoutingRules = &vschemapb.KeyspaceRoutingRules{}
)

// multiTenantMigration manages the migration of multiple tenants to a single target keyspace.
Expand Down Expand Up @@ -193,6 +195,7 @@ func TestMultiTenantSimple(t *testing.T) {
}

require.Zero(t, len(getKeyspaceRoutingRules(t, vc).Rules))

mt.Create()
confirmKeyspacesRoutedTo(t, sourceKeyspace, "s1", "t1", nil)
validateKeyspaceRoutingRules(t, vc, initialRules)
Expand Down Expand Up @@ -223,6 +226,41 @@ func TestMultiTenantSimple(t *testing.T) {
log.Infof("Migration completed, total rows in target: %d", actualRowsInserted)
require.Equal(t, lastIndex, int64(actualRowsInserted))

t.Run("Test ApplyKeyspaceRoutingRules", func(t *testing.T) {
// First set of rules
applyKeyspaceRoutingRules(t, initialRules)

updatedRules := &vschemapb.KeyspaceRoutingRules{
Rules: []*vschemapb.KeyspaceRoutingRule{
{FromKeyspace: "s1", ToKeyspace: "mt"},
{FromKeyspace: "s1@rdonly", ToKeyspace: "mt"},
{FromKeyspace: "s1@replica", ToKeyspace: "mt"},
},
}
// Update the rules
applyKeyspaceRoutingRules(t, updatedRules)
// Update with the same rules
applyKeyspaceRoutingRules(t, updatedRules)
// Remove the rules
applyKeyspaceRoutingRules(t, emptyKeyspaceRoutingRules)
// Test setting empty rules again
applyKeyspaceRoutingRules(t, emptyKeyspaceRoutingRules)
})
}

func applyKeyspaceRoutingRules(t *testing.T, newRules *vschemapb.KeyspaceRoutingRules) {
var rulesJSON []byte
var err error
require.NotNil(t, newRules)
rulesJSON, err = json.Marshal(newRules)
require.NoError(t, err)
output, err := vc.VtctldClient.ExecuteCommandWithOutput("ApplyKeyspaceRoutingRules", "--rules", string(rulesJSON))
require.NoError(t, err)

response := &vtctldata.ApplyKeyspaceRoutingRulesResponse{}
err = json.Unmarshal([]byte(output), response)
require.NoError(t, err)
require.ElementsMatch(t, newRules.Rules, response.GetKeyspaceRoutingRules().Rules)
}

func confirmOnlyReadsSwitched(t *testing.T) {
Expand Down Expand Up @@ -251,10 +289,10 @@ func confirmOnlyWritesSwitched(t *testing.T) {
validateKeyspaceRoutingRules(t, vc, rules)
}

// TestMultiTenantSimpleSharded tests a single tenant migration to a sharded target. The aim is to test
// TestMultiTenantSharded tests a single tenant migration to a sharded target. The aim is to test
// the specification of the target shards in all the MoveTables subcommands, including creating only one stream
// for a tenant on the shard to which this tenant id will be routed, using the specified Vindex.
func TestMultiTenantSimpleSharded(t *testing.T) {
func TestMultiTenantSharded(t *testing.T) {
setSidecarDBName("_vt")
// Don't create RDONLY tablets to reduce number of tablets created to reduce resource requirements for the test.
origDefaultRdonly := defaultRdonly
Expand Down