Chapter 13 · Backup, Restore, Binary Logs, and Point-in-Time Recovery

Binary Log Formats, GTIDs, Retention, and Recovery Prerequisites

Treat the MySQL binary log as an ordered recovery stream: inspect format, GTID state, retention, checksums, and decode safe events so PITR prerequisites remain observable before disaster.

Intermediate130–180 minbinlog + GTID evidence labMySQL Community Server 8.4.10 LTS · binary logging required for PITR labrecovery / binary logLast reviewed: August 2026

Learning outcomes

A full backup gives ServiceHub a historical starting point. The binary log supplies the ordered changes after that point. If the log is disabled, incomplete, purged too early, or misunderstood, point-in-time recovery becomes impossible no matter how good the full backup is. This lesson makes the recovery stream observable before it is needed.

01

Distinguish the MySQL binary log from InnoDB redo logging and explain their different recovery purposes.

02

Inspect binary logging, format, GTID mode, retention, files, and current source position on MySQL 8.4.

03

Compare statement-, row-, and mixed-format semantics without assuming the same default across every release family or topology.

04

Decode a safe test transaction with mysqlbinlog and relate positions/GTIDs to the business change.

05

Demonstrate why purging a required binary-log interval creates an unrecoverable gap in a PITR chain.

Redo is crash recovery; the binary log is a server change stream

InnoDB redo exists so the storage engine can recover durable page changes after a crash. The MySQL binary log records server data-changing events for replication and incremental/point-in-time recovery. Their retention, file formats, and consumers differ. A database can recover from a crash with redo yet still lack enough historical binary logs to rewind to yesterday at 14:31.

MechanismPrimary purposeTypical retention scope
InnoDB redoCrash recovery / durability of InnoDB changesEngine-managed active recovery horizon
Binary logReplication + incremental/PITR change historyOperator-configured time window / files
Full backupHistorical restore baseBackup retention policy
GTID metadataTransaction identity across topology/recovery workflowsExecuted/purged transaction history metadata

Inventory the recovery stream

sql · create the disposable ServiceHub recovery lab
-- Run on a disposable local MySQL 8.4 LTS instance.CREATE DATABASE IF NOT EXISTS servicehub_recovery_lab  CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;CREATE TABLE IF NOT EXISTS servicehub_recovery_lab.sites (  site_id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,  site_code VARCHAR(20) NOT NULL UNIQUE,  site_name VARCHAR(120) NOT NULL) ENGINE=InnoDB;CREATE TABLE IF NOT EXISTS servicehub_recovery_lab.work_orders (  work_order_id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,  site_id BIGINT UNSIGNED NOT NULL,  status ENUM('OPEN','IN_PROGRESS','DONE','CANCELLED') NOT NULL DEFAULT 'OPEN',  summary VARCHAR(180) NOT NULL,  opened_at TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),  closed_at TIMESTAMP(6) NULL,  CONSTRAINT fk_recovery_work_order_site    FOREIGN KEY (site_id) REFERENCES servicehub_recovery_lab.sites(site_id)) ENGINE=InnoDB;CREATE TABLE IF NOT EXISTS servicehub_recovery_lab.recovery_markers (  marker_id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,  marker_name VARCHAR(80) NOT NULL UNIQUE,  marker_time TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),  note VARCHAR(255) NOT NULL) ENGINE=InnoDB;INSERT IGNORE INTO servicehub_recovery_lab.sites(site_code,site_name)VALUES ('BAKU-01','Baku Central Service Site'),       ('BAKU-02','Baku East Service Site');INSERT IGNORE INTO servicehub_recovery_lab.recovery_markers(marker_name,note)VALUES ('CH13_BASELINE','Known recovery invariant before Chapter 13 drills');SELECT COUNT(*) AS sites FROM servicehub_recovery_lab.sites;SELECT COUNT(*) AS markers FROM servicehub_recovery_lab.recovery_markers;
sql · inspect binary-log and GTID posture
SELECT VERSION() AS server_version;SHOW GLOBAL VARIABLES WHERE Variable_name IN (  'log_bin','binlog_format','binlog_row_image',  'binlog_expire_logs_seconds','binlog_expire_logs_auto_purge',  'gtid_mode','enforce_gtid_consistency');SHOW BINARY LOGS;SHOW BINARY LOG STATUS;SELECT @@GLOBAL.gtid_executed AS gtid_executed,       @@GLOBAL.gtid_purged AS gtid_purged;

MySQL 8.4 enables binary logging by default for ordinary initialized installations, but there are documented initialization/startup cases where it can be disabled. Therefore the lab checks log_bin rather than assuming it. The default automatic expiration period is 2,592,000 seconds (30 days), but recovery requirements—not defaults—should determine the production window.

Statement, row, and mixed formats describe how changes are represented

STATEMENT records SQL statements; this can be compact but requires deterministic behavior and has classes of unsafe statements. ROW records row-change events and avoids many statement nondeterminism concerns at the cost of potentially larger logs. MIXED lets the server choose statement or row representation depending on safety. This chapter does not ask learners to switch a production source merely to observe the difference.

Inspect the actual format

Use @@GLOBAL.binlog_format and decode real events. Do not copy a blog's assumption about the default from another MySQL generation.

Create an identifiable transaction and rotate the log

sql · write a safe marker transaction
INSERT INTO servicehub_recovery_lab.recovery_markers(marker_name,note)VALUES (CONCAT('BINLOG_MARKER_',DATE_FORMAT(NOW(6),'%Y%m%d%H%i%s%f')),        'Safe transaction for mysqlbinlog inspection');SELECT LAST_INSERT_ID() AS marker_id;SHOW BINARY LOG STATUS;

Record the file/position before and after the transaction in your lab notebook. If your disposable account can do so, FLUSH BINARY LOGS can rotate to a new log file, making boundaries easier to inspect; it requires administrative privileges and should not be used as a casual production troubleshooting command.

sql · optional controlled rotation on the disposable instance
FLUSH BINARY LOGS;SHOW BINARY LOGS;SHOW BINARY LOG STATUS;

Decode events with mysqlbinlog

mysqlbinlog can read local binary-log files when you have filesystem access or read them from a running server with the appropriate remote-read options and privileges. For row-based events, --base64-output=DECODE-ROWS -vv provides human-oriented row annotations. Treat the output as sensitive because it can contain application values.

text · inspect a copied/disposable binary log file
# Replace the filename with the actual log from SHOW BINARY LOGS.mysqlbinlog --verify-binlog-checksum \  --base64-output=DECODE-ROWS -vv \  binlog.000123 > decoded_binlog.txt# Search the decoded output for the lab schema/table and surrounding positions.

The important evidence is the event position, timestamp, transaction boundary, and, when GTIDs are enabled, the GTID. A position is a byte location in a binary-log file—not “transaction number 27.”

GTIDs: transaction identity and the meaning of purged history

A Global Transaction Identifier (GTID) uniquely identifies a committed transaction in a replication topology when GTID mode is enabled. gtid_executed represents executed GTIDs. gtid_purged represents executed transactions that no longer exist in any current binary-log file on the server. Therefore a transaction can remain known to GTID metadata after the binary log bytes required for a detailed PITR replay have been purged.

sql · compare executed and purged sets
SELECT @@GLOBAL.gtid_mode AS gtid_mode,       @@GLOBAL.gtid_executed AS gtid_executed,       @@GLOBAL.gtid_purged AS gtid_purged;

Do not “fix” GTID mismatches by resetting GTID history casually. Commands that reset binary logs/GTIDs are topology-changing operations and are intentionally deferred to controlled recovery/provisioning contexts.

Retention failure: the missing interval cannot be reconstructed from wishful thinking

Suppose the last tested full backup is Sunday 02:00 and the accidental DELETE is Thursday 14:00. To achieve near-zero RPO, every required binary-log event after the backup boundary through 13:59:59 must still be available. If Wednesday's log was purged, the chain has a hole. A later log cannot recreate transactions that were only present in the missing file.

Do not purge by disk pressure alone

Binary-log retention must cover the oldest full-backup boundary you still expect to use for PITR, plus operational margin and any replication consumer requirements. Purging a needed interval converts a nominal backup policy into a larger real RPO.

sql · observe retention rather than changing it in the lab
SHOW GLOBAL VARIABLES LIKE 'binlog_expire_logs_seconds';SHOW GLOBAL VARIABLES LIKE 'binlog_expire_logs_auto_purge';SHOW BINARY LOGS;

MySQL automatically purges expired binary logs when automatic purge is enabled; manual PURGE BINARY LOGS also exists. This lesson intentionally does not purge the learner's active recovery chain. A safe failure drill can instead copy a set of log files into a disposable directory, remove one copied file, and prove the sequence is incomplete before any restore begins.

Recovery prerequisites checklist

QuestionEvidence
Is binary logging enabled?@@GLOBAL.log_bin
What representation is used?@@GLOBAL.binlog_format
What is the active recovery coordinate?SHOW BINARY LOG STATUS
What files are retained?SHOW BINARY LOGS + backup copies
Are GTIDs in use?@@GLOBAL.gtid_mode and executed/purged sets
Can log bytes be decoded?mysqlbinlog --verify-binlog-checksum on a copy
Does the full backup record its ending coordinate?dump metadata / source-data comment / backup manifest

Knowledge check

  1. How does the binary log differ from InnoDB redo?
  2. What does gtid_purged tell you?
  3. Why is a 30-day default expiration not automatically a correct retention policy?
  4. What does --start-position refer to in mysqlbinlog?
  5. Why should decoded binary logs be treated as sensitive data?
Reveal answers
  1. Redo is an InnoDB crash-recovery mechanism; the binary log is a server-level ordered change stream used for replication and PITR.
  2. It identifies executed GTIDs whose transactions are no longer present in any current binary-log file on that server.
  3. Retention must satisfy the chosen backup/PITR window and replication consumers; defaults do not know the business RPO.
  4. A byte position corresponding to an event boundary in a particular binary-log file.
  5. Row and statement events can expose application values, object names, and operational activity.

Summary and bridge to Lesson 4

You now know whether a usable post-backup change stream exists and how to identify events within it. Lesson 4 combines the two halves: restore the full backup, locate an accidental change, then replay the binary log only through the last valid position before that change.

Authoritative references

Keep knowledge open

Help the academy stay free and grow.

If these tutorials save you time, a small donation supports new lessons, technical review, diagrams, examples, and long-term maintenance.

ETHEthereum / ERC-20 only
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0

Send only assets compatible with the Ethereum/ERC-20 network. Do not send TRC-20/TRON assets.