-
Notifications
You must be signed in to change notification settings - Fork 2.1k
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
VReplication: Undo vschema changes on LookupVindex workflow creation fail #16810
Changes from 9 commits
bcd398a
53b4a77
c62d0d2
c99eb2c
7dd67a4
8b880ae
0367d05
32c29e1
5bd4b7e
2b0d2f3
345115e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -45,6 +45,7 @@ import ( | |
tabletmanagerdatapb "vitess.io/vitess/go/vt/proto/tabletmanagerdata" | ||
vschemapb "vitess.io/vitess/go/vt/proto/vschema" | ||
vtctldatapb "vitess.io/vitess/go/vt/proto/vtctldata" | ||
vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc" | ||
) | ||
|
||
const ( | ||
|
@@ -113,13 +114,11 @@ func (mz *materializer) createWorkflowStreams(req *tabletmanagerdatapb.CreateVRe | |
if err := validateNewWorkflow(mz.ctx, mz.ts, mz.tmc, mz.ms.TargetKeyspace, mz.ms.Workflow); err != nil { | ||
return err | ||
} | ||
|
||
err := mz.buildMaterializer() | ||
if err != nil { | ||
return err | ||
} | ||
if err := mz.deploySchema(); err != nil { | ||
return err | ||
} | ||
|
||
var workflowSubType binlogdatapb.VReplicationWorkflowSubType | ||
workflowSubType, err = mz.getWorkflowSubType() | ||
|
@@ -133,6 +132,10 @@ func (mz *materializer) createWorkflowStreams(req *tabletmanagerdatapb.CreateVRe | |
} | ||
req.Options = optionsJSON | ||
|
||
if err := mz.deploySchema(); err != nil { | ||
return err | ||
} | ||
|
||
Comment on lines
+134
to
+137
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 |
||
return mz.forAllTargets(func(target *topo.ShardInfo) error { | ||
targetPrimary, err := mz.ts.GetTablet(mz.ctx, target.PrimaryAlias) | ||
if err != nil { | ||
|
@@ -268,15 +271,15 @@ func (mz *materializer) deploySchema() error { | |
return forAllShards(mz.targetShards, func(target *topo.ShardInfo) error { | ||
allTables := []string{"/.*/"} | ||
|
||
hasTargetTable := map[string]bool{} | ||
req := &tabletmanagerdatapb.GetSchemaRequest{Tables: allTables} | ||
targetSchema, err := schematools.GetSchema(mz.ctx, mz.ts, mz.tmc, target.PrimaryAlias, req) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
hasTargetTable := make(map[string]*tabletmanagerdatapb.TableDefinition, len(targetSchema.TableDefinitions)) | ||
for _, td := range targetSchema.TableDefinitions { | ||
hasTargetTable[td.Name] = true | ||
hasTargetTable[td.Name] = td | ||
} | ||
|
||
targetTablet, err := mz.ts.GetTablet(mz.ctx, target.PrimaryAlias) | ||
|
@@ -286,12 +289,18 @@ func (mz *materializer) deploySchema() error { | |
|
||
var applyDDLs []string | ||
for _, ts := range mz.ms.TableSettings { | ||
if hasTargetTable[ts.TargetTable] { | ||
// Table already exists. | ||
if td := hasTargetTable[ts.TargetTable]; td != nil { | ||
// Table already exists. Let's be sure that it doesn't already have data. | ||
// We exclude multi-tenant migrations from this check as the target tables | ||
// are expected to frequently have data from previously migrated tenants. | ||
if !mz.IsMultiTenantMigration() && td.RowCount > 0 { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Which was why we were going for the approach in this PR: https://github.com/vitessio/vitess/pull/16826/files#diff-d3a320c7b03791f5d24189e3ae6d7fcac814f4fa1b3d7c02d496b3d8f0adf588R1040-R1043. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, the row count is an estimate. It can remain 0 for some time if you have not inserted/updated enough rows to go beyond the initial 16KiB page in the tablespace. I would guess that in your testing you only had a few very small rows in the table (e.g. I can remove the "table has existing data" code here in this PR then if you prefer the other approach. That was not the primary focus in this PR anyway. Sound good? Thanks! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. My tests were for a trivial number of rows, yes. But this was also reported by others recently for larger tables where the copy phase itself took minutes. They were using In any case, yes, let's handle the check for data in that other PR. Rest looks good. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK, I did that here: 345115e |
||
return vterrors.Errorf(vtrpcpb.Code_FAILED_PRECONDITION, | ||
"target table %s exists in the %s keyspace and is not empty", td.Name, target.Keyspace()) | ||
} | ||
continue | ||
} | ||
if ts.CreateDdl == "" { | ||
return fmt.Errorf("target table %v does not exist and there is no create ddl defined", ts.TargetTable) | ||
return fmt.Errorf("target table %s does not exist and there is no create ddl defined", ts.TargetTable) | ||
} | ||
|
||
var err error | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The changes in this file are not relevant here, but I wanted to add the same new capabilities to the test framework for future use (soon).