vitessio/vitess · error
GetPreviousGTIDs: previous GTIDs not found
Error message
GetPreviousGTIDs: previous GTIDs not found
What it means
GetPreviousGTIDs scans binlog events (SHOW BINLOG EVENTS) looking for the Previous_gtids event that records the set of GTIDs executed before the current binlog file. If no such event exists in the scanned binlog, this error is returned. This usually means the binlog file is empty, freshly rotated, or the server has GTIDs disabled.
Source
Thrown at go/vt/mysqlctl/replication.go:1217
return binaryLogs, err
}
// GetPreviousGTIDs is part of the MysqlDaemon interface.
func (mysqld *Mysqld) GetPreviousGTIDs(ctx context.Context, binlog string) (previousGtids string, err error) {
query := fmt.Sprintf("SHOW BINLOG EVENTS IN '%s' LIMIT 2", binlog)
qr, err := mysqld.FetchSuperQuery(ctx, query)
if err != nil {
return previousGtids, err
}
previousGtidsFound := false
for _, row := range qr.Named().Rows {
if row.AsString("Event_type", "") == "Previous_gtids" {
previousGtids = row.AsString("Info", "")
previousGtidsFound = true
}
}
if !previousGtidsFound {
return previousGtids, errors.New("GetPreviousGTIDs: previous GTIDs not found")
}
return previousGtids, nil
}
var ErrNoSemiSync = errors.New("semi-sync plugin not loaded")
func (mysqld *Mysqld) SemiSyncType(ctx context.Context) mysql.SemiSyncType {
if mysqld.semiSyncType == mysql.SemiSyncTypeUnknown {
mysqld.semiSyncType, _ = mysqld.SemiSyncExtensionLoaded(ctx)
}
return mysqld.semiSyncType
}
func (mysqld *Mysqld) enableSemiSyncQuery(ctx context.Context) (string, error) {
switch mysqld.SemiSyncType(ctx) {
case mysql.SemiSyncTypeSource:
return "SET GLOBAL rpl_semi_sync_source_enabled = %v, GLOBAL rpl_semi_sync_replica_enabled = %v", nil
case mysql.SemiSyncTypeMaster:View on GitHub (pinned to 01a25a7d17)
Solutions
- Verify gtid_mode=ON on the server; Previous_gtids events only exist when GTIDs are enabled.
- Query the first binlog file in the series (SHOW BINARY LOGS) rather than a file that may be empty/rotated.
- Fall back to reading executed GTIDs from @@GLOBAL.gtid_executed if the binlog event is unavailable.
- If the binlog was purged, restore from a backup that still has the needed binlogs.
Defensive patterns
Strategy: fallback
Validate before calling
gtidMode, err := mysqld.FetchSuperQuery(ctx, "SELECT @@GLOBAL.gtid_mode") // proceed only if gtidMode == "ON" and the target binlog file has events
Try / catch
gtids, err := mysqld.GetPreviousGTIDs(ctx, binlogFile)
if err != nil {
if strings.Contains(err.Error(), "previous GTIDs not found") {
gtids, err = readFromGtidExecuted(ctx, mysqld) // fallback to @@GLOBAL.gtid_executed
}
if err != nil {
return vterrors.Wrapf(err, "resolving previous GTIDs")
}
} Prevention
- Require gtid_mode=ON for workloads that depend on Previous_gtids events.
- Target the correct (non-empty, unrotated) binlog file when scanning events.
- Prevent binlog purging of files still needed for GTID position computation.
When it happens
Trigger: Calling Mysqld.GetPreviousGTIDs when SHOW BINLOG EVENTS on the target binlog file contains no row with Event_type == 'Previous_gtids' (previousGtidsFound stays false), producing "GetPreviousGTIDs: previous GTIDs not found".
Common situations: Point-in-time recovery / GTID position calculation against a brand-new binlog file with no prior events; GTID mode disabled (gtid_mode=OFF) so Previous_gtids events never exist; purged or truncated binlogs on the server.
Related errors
- startPos.GTIDSet is wrong type - expected filePosGTID, got:
- failed to get primary position: %v
- stream error @ (including the GTID we failed to process) %v:
- failed to set @source_binlog_checksum=@@global.binlog_checks
- failed to send the ComBinlogDump command: %v
AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01).
Data as JSON: /api/errors/ea1e77eda304a933.
Report an issue: GitHub.