vitessio/vitess · error
no rpl_semi_sync_replica_status variable in mysql
Error message
no rpl_semi_sync_replica_status variable in mysql
What it means
SemiSyncReplicationStatus runs a SHOW query for rpl_semi_sync_replica_status and requires exactly one row. If the row is missing, the semi-sync plugin is not loaded (so the variable doesn't exist), and this error is returned with false. It is the replica-side counterpart of ErrNoSemiSync handling.
Source
Thrown at go/vt/mysqlctl/replication.go:1322
case mysql.SemiSyncTypeMaster:
primary = vars["Rpl_semi_sync_master_status"] == "ON"
replica = vars["Rpl_semi_sync_slave_status"] == "ON"
}
return primary, replica
}
// SemiSyncReplicationStatus returns whether semi-sync is currently used by replication.
func (mysqld *Mysqld) SemiSyncReplicationStatus(ctx context.Context) (bool, error) {
query, err := mysqld.semiSyncReplicationStatusQuery(ctx)
if err != nil {
return false, err
}
qr, err := mysqld.FetchSuperQuery(ctx, query)
if err != nil {
return false, err
}
if len(qr.Rows) != 1 {
return false, errors.New("no rpl_semi_sync_replica_status variable in mysql")
}
if qr.Rows[0][1].ToString() == "ON" {
return true, nil
}
return false, nil
}
// SemiSyncExtensionLoaded returns whether semi-sync plugins are loaded.
func (mysqld *Mysqld) SemiSyncExtensionLoaded(ctx context.Context) (mysql.SemiSyncType, error) {
conn, connErr := getPoolReconnect(ctx, mysqld.dbaPool)
if connErr != nil {
return mysql.SemiSyncTypeUnknown, connErr
}
defer conn.Recycle()
return conn.Conn.SemiSyncExtensionLoaded()
}
View on GitHub (pinned to 01a25a7d17)
Solutions
- Install and enable the semi-sync replica plugin: INSTALL PLUGIN rpl_semi_sync_replica SONAME 'semisync_replica.so'; SET GLOBAL rpl_semi_sync_replica_enabled=ON.
- Use SemiSyncExtensionLoaded/SemiSyncType to detect plugin absence first and skip the status check.
- On older MySQL (<8.0.26), the variable is rpl_semi_sync_slave_status — match the query to the server version.
- Handle the error as 'semi-sync inactive' rather than fatal if semi-sync is optional in your deployment.
Defensive patterns
Strategy: type-guard
Validate before calling
loaded, _ := mysqld.SemiSyncExtensionLoaded(ctx)
if !loaded {
// plugin not installed; SemiSyncReplicationStatus would fail
return
}
Type guard
func isSemiSyncMissing(err error) bool {
return errors.Is(err, mysqlctl.ErrNoSemiSync) || strings.Contains(err.Error(), "rpl_semi_sync_replica_status")
} Try / catch
on, err := mysqld.SemiSyncReplicationStatus(ctx)
if err != nil {
if strings.Contains(err.Error(), "rpl_semi_sync_replica_status") {
log.Warn("semi-sync replica plugin not loaded; semi-sync inactive")
return nil
}
return vterrors.Wrapf(err, "semi-sync replica status")
} Prevention
- Install semisync_replica.so (or semisync_slave.so pre-8.0.26) on every replica.
- Match variable names to the server's MySQL version (replica vs slave naming).
- Verify plugin load at mysqld startup logs before relying on semi-sync status checks.
When it happens
Trigger: Calling Mysqld.SemiSyncReplicationStatus when the query for rpl_semi_sync_replica_status returns len(qr.Rows) != 1 — the semi-sync plugin isn't installed, so MySQL has no such status variable.
Common situations: Checking semi-sync status on a replica where semisync_slave.so was never installed; MySQL version mismatch where the replica uses newer source/replica naming (rpl_semi_sync_replica_status missing on older servers expecting rpl_semi_sync_slave_status); plugin load failures at mysqld startup.
Related errors
- ErrNoSemiSync
- Last_SQL_Error: ${LastSQL_Error}, Last_IO_Error: ${LastIO_Er
- GetPreviousGTIDs: previous GTIDs not found
- startPos.GTIDSet is wrong type - expected filePosGTID, got:
- failed to set @source_binlog_checksum=@@global.binlog_checks
AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01).
Data as JSON: /api/errors/047bacc522d7bc51.
Report an issue: GitHub.