Skip to content

Commit

Permalink
MoveTables: remove option to specify source keyspace alias for multi-…
Browse files Browse the repository at this point in the history
…tenant migrations (#15712)

Signed-off-by: Rohit Nayak <[email protected]>
  • Loading branch information
rohit-nayak-ps authored Apr 16, 2024
1 parent ad0a508 commit 4519c8f
Show file tree
Hide file tree
Showing 11 changed files with 2,036 additions and 2,157 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ func registerCommands(root *cobra.Command) {
create.Flags().BoolVar(&createOptions.NoRoutingRules, "no-routing-rules", false, "(Advanced) Do not create routing rules while creating the workflow. See the reference documentation for limitations if you use this flag.")
create.Flags().BoolVar(&createOptions.AtomicCopy, "atomic-copy", false, "(EXPERIMENTAL) A single copy phase is run for all tables from the source. Use this, for example, if your source keyspace has tables which use foreign key constraints.")
create.Flags().StringVar(&createOptions.WorkflowOptions.TenantId, "tenant-id", "", "(EXPERIMENTAL) The tenant ID to use for the MoveTables workflow into a multi-tenant keyspace.")
create.Flags().StringVar(&createOptions.WorkflowOptions.SourceKeyspaceAlias, "source-keyspace-alias", "", "(EXPERIMENTAL) Used currently only for multi-tenant migrations. This value will be used instead of the source keyspace name in the keyspace routing rules.")
create.Flags().BoolVar(&createOptions.WorkflowOptions.StripShardedAutoIncrement, "remove-sharded-auto-increment", true, "If moving the table(s) to a sharded keyspace, remove any auto_increment clauses when copying the schema to the target as sharded keyspaces should rely on either user/application generated values or Vitess sequences to ensure uniqueness.")
base.AddCommand(create)

Expand Down
40 changes: 10 additions & 30 deletions go/test/endtoend/vreplication/multi_tenant_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,8 @@ const (
tenantMigrationStatusMigrating
tenantMigrationStatusMigrated

sourceKeyspaceTemplate = "s%d"
sourceAliasKeyspaceTemplate = "a%d"
targetKeyspaceName = "mt"
sourceKeyspaceTemplate = "s%d"
targetKeyspaceName = "mt"

numTenants = 10
numInitialRowsPerTenant = 10
Expand Down Expand Up @@ -130,7 +129,6 @@ func TestMultiTenantSimple(t *testing.T) {

tenantId := int64(1)
sourceKeyspace := getSourceKeyspace(tenantId)
sourceAliasKeyspace := getSourceAliasKeyspace(tenantId)
_, err = vc.AddKeyspace(t, []*Cell{vc.Cells["zone1"]}, sourceKeyspace, "0", stVSchema, stSchema, 1, 0, getInitialTabletIdForTenant(tenantId), nil)
require.NoError(t, err)

Expand Down Expand Up @@ -163,19 +161,16 @@ func TestMultiTenantSimple(t *testing.T) {
sourceKeyspace: sourceKeyspace,
createFlags: []string{
"--tenant-id", strconv.FormatInt(tenantId, 10),
"--source-keyspace-alias", sourceAliasKeyspace,
},
})

preSwitchRules := &vschemapb.KeyspaceRoutingRules{
Rules: []*vschemapb.KeyspaceRoutingRule{
{FromKeyspace: "a1", ToKeyspace: "s1"},
{FromKeyspace: "s1", ToKeyspace: "s1"},
},
}
postSwitchRules := &vschemapb.KeyspaceRoutingRules{
Rules: []*vschemapb.KeyspaceRoutingRule{
{FromKeyspace: "a1", ToKeyspace: "mt"},
{FromKeyspace: "s1", ToKeyspace: "mt"},
},
}
Expand All @@ -187,25 +182,21 @@ func TestMultiTenantSimple(t *testing.T) {
mt.Create()
validateKeyspaceRoutingRules(t, vc, primaries, rulesMap, false)
// Note: we cannot insert into the target keyspace since that is never routed to the source keyspace.
for _, ks := range []string{sourceKeyspace, sourceAliasKeyspace} {
lastIndex = insertRows(lastIndex, ks)
}
lastIndex = insertRows(lastIndex, sourceKeyspace)
waitForWorkflowState(t, vc, fmt.Sprintf("%s.%s", targetKeyspace, mt.workflowName), binlogdatapb.VReplicationWorkflowState_Running.String())
mt.SwitchReadsAndWrites()
validateKeyspaceRoutingRules(t, vc, primaries, rulesMap, true)
// Note: here we have already switched and we can insert into the target keyspace and it should get reverse
// replicated to the source keyspace. The source and alias are also routed to the target keyspace at this point.
for _, ks := range []string{sourceKeyspace, sourceAliasKeyspace, targetKeyspace} {
lastIndex = insertRows(lastIndex, ks)
}
// Note: here we have already switched, and we can insert into the target keyspace, and it should get reverse
// replicated to the source keyspace. The source keyspace is routed to the target keyspace at this point.
lastIndex = insertRows(lastIndex, sourceKeyspace)
mt.Complete()
require.Zero(t, len(getKeyspaceRoutingRules(t, vc).Rules))
actualRowsInserted := getRowCount(t, vtgateConn, fmt.Sprintf("%s.%s", targetKeyspace, "t1"))
log.Infof("Migration completed, total rows in target: %d", actualRowsInserted)
require.Equal(t, lastIndex, int64(actualRowsInserted))
}

// If switched queries with source/alias qualifiers should execute on target, else on source. Confirm that
// If switched, queries with source qualifiers should execute on target, else on source. Confirm that
// the routing rules are as expected and that the query executes on the expected tablet.
func validateKeyspaceRoutingRules(t *testing.T, vc *VitessCluster, primaries map[string]*cluster.VttabletProcess, rulesMap map[string]*vschemapb.KeyspaceRoutingRules, switched bool) {
currentRules := getKeyspaceRoutingRules(t, vc)
Expand All @@ -224,25 +215,19 @@ func validateKeyspaceRoutingRules(t *testing.T, vc *VitessCluster, primaries map
require.ElementsMatch(t, rulesMap["post"].Rules, currentRules.Rules)
validateQueryRoute("mt", "target")
validateQueryRoute("s1", "target")
validateQueryRoute("a1", "target")
} else {
require.ElementsMatch(t, rulesMap["pre"].Rules, currentRules.Rules)
// Note that with multi-tenant migration, we cannot redirect the target keyspace since
// there are multiple source keyspaces and the target has the aggregate of all the tenants.
validateQueryRoute("mt", "target")
validateQueryRoute("s1", "source")
validateQueryRoute("a1", "source")
}
}

func getSourceKeyspace(tenantId int64) string {
return fmt.Sprintf(sourceKeyspaceTemplate, tenantId)
}

func getSourceAliasKeyspace(tenantId int64) string {
return fmt.Sprintf(sourceAliasKeyspaceTemplate, tenantId)
}

func (mtm *multiTenantMigration) insertSomeData(t *testing.T, tenantId int64, keyspace string, numRows int64) {
vtgateConn, closeConn := getVTGateConn()
defer closeConn()
Expand Down Expand Up @@ -362,7 +347,7 @@ func (mtm *multiTenantMigration) getLastID(tenantId int64) int64 {
return mtm.lastIDs[tenantId]
}

func (mtm *multiTenantMigration) initTenantData(t *testing.T, tenantId int64, sourceAliasKeyspace string) {
func (mtm *multiTenantMigration) initTenantData(t *testing.T, tenantId int64) {
mtm.insertSomeData(t, tenantId, getSourceKeyspace(tenantId), numInitialRowsPerTenant)
}

Expand All @@ -374,16 +359,14 @@ func (mtm *multiTenantMigration) setup(tenantId int64) {
log.Infof("Creating MoveTables for tenant %d", tenantId)
mtm.setLastID(tenantId, 0)
sourceKeyspace := getSourceKeyspace(tenantId)
sourceAliasKeyspace := getSourceAliasKeyspace(tenantId)
_, err := vc.AddKeyspace(mtm.t, []*Cell{vc.Cells["zone1"]}, sourceKeyspace, "0", stVSchema, stSchema,
1, 0, getInitialTabletIdForTenant(tenantId), nil)
require.NoError(mtm.t, err)
mtm.initTenantData(mtm.t, tenantId, sourceAliasKeyspace)
mtm.initTenantData(mtm.t, tenantId)
}

func (mtm *multiTenantMigration) start(tenantId int64) {
sourceKeyspace := getSourceKeyspace(tenantId)
sourceAliasKeyspace := getSourceAliasKeyspace(tenantId)
mtm.setTenantMigrationStatus(tenantId, tenantMigrationStatusMigrating)
mt := newVtctldMoveTables(&moveTablesWorkflow{
workflowInfo: &workflowInfo{
Expand All @@ -395,7 +378,6 @@ func (mtm *multiTenantMigration) start(tenantId int64) {
tables: mtm.tables,
createFlags: []string{
"--tenant-id", strconv.FormatInt(tenantId, 10),
"--source-keyspace-alias", sourceAliasKeyspace,
},
})
mtm.setActiveMoveTables(tenantId, mt)
Expand All @@ -404,13 +386,11 @@ func (mtm *multiTenantMigration) start(tenantId int64) {

func (mtm *multiTenantMigration) switchTraffic(tenantId int64) {
t := mtm.t
sourceAliasKeyspace := getSourceAliasKeyspace(tenantId)
sourceKeyspaceName := getSourceKeyspace(tenantId)
mt := mtm.getActiveMoveTables(tenantId)
ksWorkflow := fmt.Sprintf("%s.%s", mtm.targetKeyspace, mt.workflowName)
waitForWorkflowState(t, vc, ksWorkflow, binlogdatapb.VReplicationWorkflowState_Running.String())
// we intentionally insert first into the source alias keyspace and then the source keyspace to test routing rules for both.
mtm.insertSomeData(t, tenantId, sourceAliasKeyspace, numAdditionalRowsPerTenant)
mtm.insertSomeData(t, tenantId, sourceKeyspaceName, numAdditionalRowsPerTenant)
mt.SwitchReadsAndWrites()
mtm.insertSomeData(t, tenantId, sourceKeyspaceName, numAdditionalRowsPerTenant)
}
Expand Down
Loading

0 comments on commit 4519c8f

Please sign in to comment.