{"record":{"id":"116c1cdb80eac723","repo":"vitessio/vitess","slug":"errnosemisync","errorCode":"ErrNoSemiSync","errorMessage":"semi-sync plugin not loaded","messagePattern":"semi-sync plugin not loaded","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"go/vt/mysqlctl/replication.go","lineNumber":1222,"sourceCode":"\tquery := fmt.Sprintf(\"SHOW BINLOG EVENTS IN '%s' LIMIT 2\", binlog)\n\tqr, err := mysqld.FetchSuperQuery(ctx, query)\n\tif err != nil {\n\t\treturn previousGtids, err\n\t}\n\tpreviousGtidsFound := false\n\tfor _, row := range qr.Named().Rows {\n\t\tif row.AsString(\"Event_type\", \"\") == \"Previous_gtids\" {\n\t\t\tpreviousGtids = row.AsString(\"Info\", \"\")\n\t\t\tpreviousGtidsFound = true\n\t\t}\n\t}\n\tif !previousGtidsFound {\n\t\treturn previousGtids, errors.New(\"GetPreviousGTIDs: previous GTIDs not found\")\n\t}\n\treturn previousGtids, nil\n}\n\nvar ErrNoSemiSync = errors.New(\"semi-sync plugin not loaded\")\n\nfunc (mysqld *Mysqld) SemiSyncType(ctx context.Context) mysql.SemiSyncType {\n\tif mysqld.semiSyncType == mysql.SemiSyncTypeUnknown {\n\t\tmysqld.semiSyncType, _ = mysqld.SemiSyncExtensionLoaded(ctx)\n\t}\n\treturn mysqld.semiSyncType\n}\n\nfunc (mysqld *Mysqld) enableSemiSyncQuery(ctx context.Context) (string, error) {\n\tswitch mysqld.SemiSyncType(ctx) {\n\tcase mysql.SemiSyncTypeSource:\n\t\treturn \"SET GLOBAL rpl_semi_sync_source_enabled = %v, GLOBAL rpl_semi_sync_replica_enabled = %v\", nil\n\tcase mysql.SemiSyncTypeMaster:\n\t\treturn \"SET GLOBAL rpl_semi_sync_master_enabled = %v, GLOBAL rpl_semi_sync_slave_enabled = %v\", nil\n\t}\n\treturn \"\", ErrNoSemiSync\n}\n","sourceCodeStart":1204,"sourceCodeEnd":1240,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/mysqlctl/replication.go#L1204-L1240","documentation":"ErrNoSemiSync is a sentinel error (errors.Is-comparable) indicating the semi-sync replication plugin (rpl_semi_sync_master/replica) is not loaded in mysqld. enableSemiSyncQuery and semiSyncReplicationStatusQuery return it when the semi-sync status variable doesn't exist because the plugin was never installed. Callers can use errors.Is to branch on it gracefully rather than treating it as a hard failure.","triggerScenarios":"Calling SemiSyncReplicationStatus (or code paths via enableSemiSyncQuery / semiSyncReplicationStatusQuery) on a mysqld without the semi-sync plugin loaded: the SHOW query for the semi-sync status variable returns no rows / unknown variable, and the function returns ErrNoSemiSync.","commonSituations":"MySQL 8.0.26+ renamed plugin variables (rpl_semi_sync_master_* -> rpl_semi_sync_source_*), leaving the plugin effectively unloaded under the old names; semi-sync plugin never installed via INSTALL PLUGIN; vanilla MySQL community builds without semi-sync compiled in.","solutions":["Load the plugin: INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so' (and the master/source equivalent) on the mysqld instance.","Check SemiSyncExtensionLoaded / SemiSyncType first and skip semi-sync setup when the plugin is absent.","On MySQL 8.0.26+, account for the source/replica variable renaming — use the correct variable names for the server version.","Compare with errors.Is(err, mysqlctl.ErrNoSemiSync) to treat absence as an expected, non-fatal condition."],"exampleFix":"// before\n_, err := mysqld.SemiSyncReplicationStatus(ctx)\nif err != nil {\n    return err\n}\n\n// after\n_, err := mysqld.SemiSyncReplicationStatus(ctx)\nif errors.Is(err, mysqlctl.ErrNoSemiSync) {\n    log.Info(\"semi-sync plugin not loaded; continuing without semi-sync\")\n    return nil\n} else if err != nil {\n    return vterrors.Wrapf(err, \"checking semi-sync status\")\n}","handlingStrategy":"type-guard","validationCode":"loaded, semiSyncType := mysqld.SemiSyncExtensionLoaded(ctx)\nif !loaded {\n    log.Info(\"semi-sync extension not loaded; skipping semi-sync setup\")\n}","typeGuard":"func isSemiSyncMissing(err error) bool {\n    return errors.Is(err, mysqlctl.ErrNoSemiSync)\n}","tryCatchPattern":"status, err := mysqld.SemiSyncReplicationStatus(ctx)\nswitch {\ncase errors.Is(err, mysqlctl.ErrNoSemiSync):\n    // expected: plugin absent, degrade gracefully\ncase err != nil:\n    return vterrors.Wrapf(err, \"semi-sync status\")\ndefault:\n    _ = status\n}","preventionTips":["INSTALL PLUGIN semisync (master/replica or source/replica variants) on all mysqlds that need semi-sync.","On MySQL 8.0.26+ use the renamed rpl_semi_sync_source/replica variables and plugin names.","Check SemiSyncExtensionLoaded before any semi-sync enable/status call.","Always branch with errors.Is(err, mysqlctl.ErrNoSemiSync) instead of string matching."],"tags":["mysql","semi-sync","replication","plugin","sentinel-error"],"backgroundTag":"semi-sync-plugin-not-loaded","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}