vitessio/vitess · error

failed to get post copy actions for the %q table: %v

Error message

failed to get post copy actions for the %q table: %v

What it means

Before executing each post copy action, execPostCopyActions opens a transaction and re-selects the action rows for the table with FOR UPDATE to serialize execution between concurrent vreplicators (e.g. during shard merges). This error wraps any MySQL failure of that locked select, including the table name. Without this check, duplicate ALTERs by multiple controllers could race.

Source

Thrown at go/vt/vttablet/tabletmanager/vreplication/vreplicator.go:1123

		// the same action, then we skip executing it as an individual
		// action on a table should only be done by the last vreplicator
		// to finish. We use a transaction because we select matching
		// rows with FOR UPDATE in order to serialize the execution of
		// the post copy actions for the same workflow and table.
		// This ensures that the actions are only performed once after
		// all streams have completed the copy phase for the table.
		redundant := false
		_, err = dbClient.ExecuteFetch("start transaction", 1)
		if err != nil {
			return err
		}
		vrsq, err := sqlparser.ParseAndBind(sqlGetAndLockPostCopyActionsForTable, sqltypes.StringBindVariable(tableName))
		if err != nil {
			return err
		}
		vrsres, err := dbClient.ExecuteFetch(vrsq, -1)
		if err != nil {
			return fmt.Errorf("failed to get post copy actions for the %q table: %v", tableName, err)
		}
		if vrsres != nil && len(vrsres.Rows) > 1 {
			// We have more than one planned post copy action on the table.
			for _, row := range vrsres.Named().Rows {
				vrid, err := row["vrepl_id"].ToInt32()
				if err != nil {
					return err
				}
				ctlaction := row["action"].ToString()
				// Let's make sure that it's a different controller/vreplicator
				// and that the action is the same.
				if vrid != vr.id && strings.EqualFold(ctlaction, string(actionBytes)) {
					// We know that there's another controller/vreplicator yet
					// to finish its copy phase for the table and it will perform
					// the same action on the same table when it completes, so we
					// skip doing the action and simply delete our action record
					// to mark this controller/vreplicator's post copy action work
					// as being done for the table before it finishes the copy

View on GitHub (pinned to 01a25a7d17)

Solutions

  1. Inspect the wrapped MySQL error: for lock wait timeout, check for competing vreplication controllers/transactions on the same table and retry after they finish
  2. If the connection was killed (2013/EOF) during a workflow stop, simply restart the workflow — actions are retried on the new primary
  3. Check innodb_lock_wait_timeout is adequate if shard merges run many concurrent controllers
  4. Verify _vt.post_copy_action is healthy/consistent; clean orphaned rows with DBA access if needed
Defensive patterns

Strategy: retry

Validate before calling

// Before restarting, check for competing/stranded lock holders:
SHOW FULL PROCESSLIST; -- look for transactions holding locks on _vt.post_copy_action
SELECT @@innodb_lock_wait_timeout;

Try / catch

vrsres, err := dbClient.ExecuteFetch(vrsq, -1)
if err != nil {
    if sqlErr, ok := err.(*sqlerror.SQLError); ok && sqlErr.Number() == 1205 {
        // lock wait timeout: wait for competing vreplicator, then retry
    }
    return fmt.Errorf("failed to get post copy actions for the %q table: %v", tableName, err)
}

Prevention

When it happens

Trigger: The bound sqlGetAndLockPostCopyActionsForTable query fails on dbClient.ExecuteFetch — e.g. the connection was killed by the interruption goroutine (CRServerLost/EOF), a lock wait timeout on the row lock, or the tablet went read-only mid-transaction.

Common situations: Workflow cancelled/stopped while the FOR UPDATE select is blocked by another controller's transaction (innodb_lock_wait_timeout exceeded); connection killed during engine shutdown; shard-merge concurrency contention on _vt.post_copy_action.

Related errors


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