vitessio/vitess · error

CopySchemaShard: can't get replication position after schema

Error message

CopySchemaShard: can't get replication position after schema applied: %v

What it means

After applying the schema on the destination primary, CopySchemaShard reads the destination primary's replication position via wr.tmc.PrimaryPosition to record where the schema change landed. If that tabletmanager RPC fails, the copy itself may have succeeded but the operation aborts because it cannot capture the post-apply position needed for verification.

Source

Thrown at go/vt/wrangler/schema.go:247

	destTabletInfo, err := wr.ts.GetTablet(ctx, destShardInfo.PrimaryAlias)
	if err != nil {
		return fmt.Errorf("GetTablet(%v) failed: %v", destShardInfo.PrimaryAlias, err)
	}
	for _, createSQL := range createSQLstmts {
		err = wr.applySQLShard(ctx, destTabletInfo, createSQL)
		if err != nil {
			return fmt.Errorf("creating a table failed."+
				" Most likely some tables already exist on the destination and differ from the source."+
				" Please remove all to be copied tables from the destination manually and run this command again."+
				" Full error: %v", err)
		}
	}

	// Remember the replication position after all the above were applied.
	destPrimaryPos, err := wr.tmc.PrimaryPosition(ctx, destTabletInfo.Tablet)
	if err != nil {
		return fmt.Errorf("CopySchemaShard: can't get replication position after schema applied: %v", err)
	}

	// Although the copy was successful, we have to verify it to catch the case
	// where the database already existed on the destination, but with different
	// options e.g. a different character set.
	// In that case, MySQL would have skipped our CREATE DATABASE IF NOT EXISTS
	// statement.
	if !skipVerify {
		diffs, err = schematools.CompareSchemas(ctx, wr.ts, wr.tmc, sourceTabletAlias, destShardInfo.PrimaryAlias, tables, excludeTables, includeViews)
		if err != nil {
			return fmt.Errorf("CopySchemaShard failed because schemas could not be compared finally: %v", err)
		}
		if diffs != nil {
			return fmt.Errorf("CopySchemaShard was not successful because the schemas between the two tablets %v and %v differ: %v", sourceTabletAlias, destShardInfo.PrimaryAlias, diffs)
		}
	}

	// Notify Replicas to reload schema. This is best-effort.

View on GitHub (pinned to 01a25a7d17)

Solutions

  1. Verify the destination primary is alive and still primary (vtctldclient GetTablet <alias>), then retry CopySchemaShard.
  2. If a reparent happened, complete it, then rerun the copy against the current primary.
  3. Check tablet logs around the failure time for tabletmanager errors.
Defensive patterns

Strategy: retry

Validate before calling

if _, err := wr.ts.GetTablet(ctx, destPrimaryAlias); err != nil {
    return fmt.Errorf("destination primary unreachable before schema copy: %v", err)
}

Try / catch

err := wr.CopySchemaShard(ctx, src, dst, tables, excl, false)
if err != nil && strings.Contains(err.Error(), "replication position") {
    // wait for tablet/failover to settle, then retry
}

Prevention

When it happens

Trigger: The destination primary becomes unreachable or its tabletmanager fails between the ApplySchema calls and the PrimaryPosition call - the primary crashes, is reparented mid-copy, or a state change occurs after the 30s applySQLShard timeout window.

Common situations: Destination primary failover occurred mid-copy; tablet restarted; vtctld-to-tablet RPC timeouts under heavy load.

Related errors


AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01). Data as JSON: /api/errors/385e7f08cc152cec. Report an issue: GitHub.