vitessio/vitess · error

failed to set session foreign_key_checks: %w

Error message

failed to set session foreign_key_checks: %w

What it means

The vplayer wraps a failure to execute SET @@session.foreign_key_checks=<true|false> on the target MySQL session. VReplication toggles foreign key checks per row event (using the event's flags) so that replicated rows can be applied in dependency order without violating FK constraints on the target. If this session statement fails, the row event cannot be applied safely.

Source

Thrown at go/vt/vttablet/tabletmanager/vreplication/vplayer.go:242

		// the copy phase, i.e., for catchup and fastforward.
		mustUpdate = true
	} else if vp.vr.state == binlogdatapb.VReplicationWorkflowState_Running {
		// If the vreplication workflow is in Running state, we must update the foreign_key_checks
		// state for all workflow types.
		mustUpdate = true
	}
	if !mustUpdate {
		return nil
	}
	dbForeignKeyChecksEnabled := flags2&NoForeignKeyCheckFlagBitmask != NoForeignKeyCheckFlagBitmask

	if vp.foreignKeyChecksStateInitialized /* already set earlier */ &&
		dbForeignKeyChecksEnabled == vp.foreignKeyChecksEnabled /* no change in the state, no need to update */ {
		return nil
	}
	log.Info("Setting this session's foreign_key_checks to " + strconv.FormatBool(dbForeignKeyChecksEnabled))
	if _, err := vp.query(ctx, "set @@session.foreign_key_checks="+strconv.FormatBool(dbForeignKeyChecksEnabled)); err != nil {
		return fmt.Errorf("failed to set session foreign_key_checks: %w", err)
	}
	vp.foreignKeyChecksEnabled = dbForeignKeyChecksEnabled
	if !vp.foreignKeyChecksStateInitialized {
		log.Info("First foreign_key_checks update to: " + strconv.FormatBool(dbForeignKeyChecksEnabled))
		vp.foreignKeyChecksStateInitialized = true
	}
	return nil
}

// runWithRecover invokes fn and converts any panic into an error so the
// caller's child goroutine doesn't crash the entire vttablet process. The
// panic value and stack are logged with workflow context. Used to wrap
// fetchAndApply's child goroutine bodies (#20360) which would otherwise
// escape controller.runBlp's recover (that runs on a different goroutine).
func runWithRecover(workflow, where string, fn func() error) (err error) {
	defer func() {
		if x := recover(); x != nil {
			log.Error("caught panic",

View on GitHub (pinned to 01a25a7d17)

Solutions

  1. Check the target tablet's MySQL error log and the wrapped error for the root cause (connection lost, read-only, etc.)
  2. Verify the target MySQL server is writable and the vreplication user session is healthy; restart the workflow / RestoreData if the connection was lost
  3. If targeting MariaDB or an old MySQL flavor, confirm @@session.foreign_key_checks is a supported variable in that flavor
  4. Check for external session-killers (proxies, DBAs, max_execution_time) that terminate long-lived vreplication connections
Defensive patterns

Strategy: retry

Validate before calling

// Check the target is healthy and writable before starting the workflow
out, _ := exec.Command("mysql", "-h", targetHost, "-e", "SELECT @@foreign_key_checks, @@read_only").Output()
// Expect: 1, 0 — writable with FK checks supported

Try / catch

if err := applyRowEvent(ctx, ev); err != nil {
    var retryable = strings.Contains(err.Error(), "failed to set session foreign_key_checks")
    if retryable && isConnectionError(err) {
        // rely on vreplication's built-in retry/backoff; monitor via _vt.vreplication Message
    }
}

Prevention

When it happens

Trigger: vp.query(ctx, "set @@session.foreign_key_checks=...") returns an error during updateFKCheck, invoked from applyRowEvent for a row event whose flags indicate the FK state must change (or on the first event when state is uninitialized).

Common situations: Target MySQL/MariaDB connection dropped mid-stream; target database in a read-only or super_read_only state; an external process killing the vreplication session; restricted privileges on the replication user (though FK checks usually needs none, restricted setups may fail).

Related errors


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