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
- Check the target tablet's MySQL error log and the wrapped error for the root cause (connection lost, read-only, etc.)
- Verify the target MySQL server is writable and the vreplication user session is healthy; restart the workflow / RestoreData if the connection was lost
- If targeting MariaDB or an old MySQL flavor, confirm @@session.foreign_key_checks is a supported variable in that flavor
- 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
- Keep target tablets reachable and MySQL sessions free of external killers (proxies, DBA kill scripts)
- Ensure the target is not left in read_only/super_read_only during vreplication
- Verify binlog/flavor support for foreign_key_checks on MariaDB or older MySQL targets
- Monitor _vt.vreplication Message/State for stalled streams
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
- unable to select @@foreign_key_checks
- unable to select @@session.restrict_fk_on_non_standard_key
- partial row image encountered: ensure binlog_row_image is se
- can't get charset to request binlog stream: %v
- error in processing binlog event %v
AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01).
Data as JSON: /api/errors/08d4d69652b2e854.
Report an issue: GitHub.