Database engineer validating MySQL binary logs and transaction boundaries during point-in-time recovery

Restore MySQL to the Right Transaction, Not Just the Right Time

Sat, Sep 19, 2026

A restored MySQL instance can start normally and return plausible rows while its final included commit remains unproved. In this explicitly synthetic incident, the original server stays untouched while a disposable candidate is rebuilt from a known backup and binary logs. The requested historical state is the commit after Txn2 and immediately before the harmful multi-statement Txn3. That decision also excludes the otherwise valid Txn4 and Txn5 because they occurred after the approved boundary. Oracle's MySQL 8.4 point-in-time recovery guidance describes the full-backup plus binary-log model, but a running server alone does not identify the selected business state. The recovery owner assembles the evidence, the application reviewer checks business invariants, and the incident authority authorizes any exposure to application traffic. The outcome for this one candidate is Accept, Hold, or Restart from the verified base.

Define the recovery point and who can approve it

  • Backup source: A full backup (for example, a MySQL dump or physical snapshot) taken at a known timestamp.

  • Requested cutoff: Include every committed transaction through Txn2 at 2026-09-15 13:45:01 UTC. Stop before the first event of the unwanted Txn3 at approximately 13:50 UTC. Every later commit, whether useful or harmful, remains outside this historical prefix.

  • Affected data: For example, orders and inventory tables modified since that cutoff. Identify which records or business invariants (totals, account balances) depend on the cutoff.

  • Recovery owner: The database-reliability engineer or DBA team lead responsible for the recovery process.

  • Application reviewer: The application or product manager who will verify the restored data against business expectations.

  • Incident authority: The designated incident decision-maker who signs the final Accept, Hold, or Restart-from-base record.

This is not simply turning a database back on or pointing an application at a server that accepts connections. It is a point-in-time restore whose approved endpoint is a complete transaction boundary. It is separate from replica promotion, current-state repair, or selective salvage of later writes. Before work begins, approve the scope card and phrase the target as an authoritative commit, not “sometime this afternoon” or “before the bad query.” Accept means all evidence agrees; Hold means the candidate remains isolated while uncertainty is investigated; Restart means discard the candidate and rebuild from the verified base. For broader context, see backup and recovery within the wider DBA role.

Inventory the backup, tools and source configuration

Before touching any data, assemble a manifest of the source environment and the backup. This includes:

  • Backup method and provenance: Record exactly how the backup was created. In this lab, the example is a logical dump of the InnoDB-only fixture using mysqldump --single-transaction --source-data=2 --flush-logs. Record the source host identity, start and completion times, file name, SHA256 checksum, job output, and the commented CHANGE REPLICATION SOURCE TO coordinates. Oracle's mysqldump documentation explains the consistency and coordinate conditions for these options.

  • Server and client versions: Pin the MySQL Server, mysql client, mysqldump, and mysqlbinlog to matching 8.4 patch releases. Record the operating system, architecture, SQL modes, character sets, and any configuration that could change replay behavior.

  • Logging mode: Confirm log_bin=ON and binlog_format=ROW on the source. The disposable fixture was provisioned with gtid_mode=OFF from the beginning. Do not disable GTID or binary logging on a production server to imitate this lab; a GTID-enabled estate needs its own qualified backup and replay procedure.

  • Storage engines and change conditions: Confirm that the selected fixture tables are InnoDB. A --single-transaction dump does not make nontransactional tables consistent, and concurrent table-changing DDL can invalidate the data or recorded coordinates. Capture the maintenance and change window evidence rather than assuming every successful dump is consistent.

  • Credentials and access: Record the source and candidate accounts, the minimum privileges required by the chosen backup and restore procedure, and the filesystem permissions needed to read evidence. Keep passwords and tokens in an approved credential store or client login path, never in commands, transcripts, or the acceptance record.

All these details go into a formal backup manifest (for example, a table or structured note). For instance:

Item

Detail

Backup method

mysqldump --single-transaction --source-data=2 --flush-logs for the InnoDB-only fixture

Backup file

backup-20260915-133500.sql; SHA256 recorded in the evidence manifest

Backup timestamp

2026-09-15 13:35:00 UTC

Server and clients

Matching pinned MySQL 8.4.x patch release

Binary logging

log_bin=ON; binlog_format=ROW

GTID mode

OFF from initial disposable-lab provisioning

Engines

InnoDB only; no nontransactional tables

Credential handling

Approved login path or secret store; no passwords in commands or reports

For a logical dump created with --source-data=2, use the commented CHANGE REPLICATION SOURCE TO statement as the backup-to-log coordinate record. For a physical backup, use the coordinates emitted by that backup tool. A file timestamp, filename, or InnoDB startup message is not authoritative. The manifest must name the exact binary-log file and position from which replay starts, and that coordinate must reconcile with the retained evidence.

This fixture is intentionally narrow: one disposable MySQL server, InnoDB-only tables, row-based logging, GTID disabled at initial provisioning, no concurrent DDL, and no external writers. The MySQL database backup methods documentation distinguishes logical and physical approaches; mixed engines, encrypted logs, managed-service restore APIs, replication promotion, distributed transactions, and production GTID procedures require different controls. Store the manifest and reviewed commands with version-controlled database recovery automation rather than relying on an operator’s memory.

Preserve the full binary-log chain before investigating

Before investigation, copy every required binary-log file to read-only evidence storage and leave the original instance untouched. Record source identity, ordered filename, size, SHA256 checksum, encryption state if relevant, and whether mysqlbinlog can parse the file with checksum verification. Do not purge, rotate, rename, or overwrite source logs during the exercise. Continuity must extend from the backup coordinate through the selected endpoint, with enough surrounding history to identify the complete transaction. A missing, unreadable, or ambiguous file is a hard Hold. This distinction also matters when comparing managed and self-managed recovery boundaries.

Binlog file

Size

SHA256

Source / parse evidence

Decision

binlog.000010

1,048,576 bytes

d4e5…3f2a

Expected source; checksum verification passes

Retain

binlog.000011

524,288 bytes

a1b2…c9d0

Expected successor; checksum verification passes

Retain

binlog.000012

786,432 bytes

e7f8…1a2b

Current file; preserve but do not assume complete

Review

If binlog.000011 is expected between binlog.000010 and binlog.000012 but is absent, the chain is broken. A later file cannot reconstruct the missing predecessor, and a plausible filename cannot prove common origin. Preserve the inventory, stop replay planning, and either recover the missing evidence or select an earlier base followed by a complete chain.

Tie the backup to an authoritative replay start

Extract the binary-log filename and position recorded by the backup procedure. With --source-data=2, the dump contains an informational, commented statement similar to this:

-- CHANGE REPLICATION SOURCE TO SOURCE_LOG_FILE='binlog.000010', SOURCE_LOG_POS=150;

The coordinate means replay begins with the first eligible event at or after position 150 in binlog.000010. Confirm that the named file is the retained file from the same source and that mysqlbinlog can read from that event boundary. Do not guess a start from wall-clock time, a backup filename, or a same-named log copied from another server. The numbers in this article are synthetic; an actual run must use the values produced by its own backup and logs.

Reject any file whose source identity, checksum, expected order, or format does not agree with the manifest. If the coordinate points outside the retained file, falls in the middle of an event, or names an unavailable file, the candidate stays on Hold.

Distinguish an intact chain from a list of available files

An intact chain is more than a directory listing. Binary-log byte positions restart within each file, so the final position of one file does not need to equal the first position of the next. Instead, reconcile the ordered filenames with the captured index or backup evidence, verify checksums, parse each file, inspect file headers and rotation context, and confirm that every expected predecessor is present. A practical inspection pattern is:

mysqlbinlog --verify-binlog-checksum /evidence/binlog.000010 > /dev/null
mysqlbinlog --verify-binlog-checksum /evidence/binlog.000011 > /dev/null
sha256sum /evidence/binlog.000010 /evidence/binlog.000011

Run inspection only against read-only copies. Record each command, tool version, exit status, and checksum in the continuity ledger. A zero exit status confirms that a file was readable under that tool and configuration; it does not by itself prove that no predecessor is missing or that the file belongs to the selected source.

Illustrative inventory when something is missing:

Expected order

File present?

Source identity

Parse result

Gate

1

binlog.000010: Yes

Matches manifest

Readable

Pass

2

binlog.000011: No

Unknown

Not available

Hold

3

binlog.000012: Yes

Matches manifest

Readable

Does not repair gap

Unrelated copy

binlog.000011: Yes

Different source

Readable

Reject

In the missing-file example, the evidence jumps from binlog.000010 to binlog.000012. The contents of binlog.000011 are unknown, so the team cannot prove whether it contained approved work, the unwanted transaction, or another dependency. The decision is Hold until the file is recovered, or Restart from a different verified base with a complete successor chain.

Treat a same-named file from another server, a file with a different source identity, or an unexpected out-of-sequence file as unrelated evidence. Availability is not continuity. Only a gapless, attributable chain can pass this gate.

Build a small ledger with a known commit history

The executable fixture uses a small synthetic inventory ledger on a throwaway server. The base backup is taken at 13:35 UTC after the schema exists but before the five transactions below. Txn1 and Txn2 are approved; Txn3 is the harmful multi-statement commit; Txn4 and Txn5 are otherwise valid but occur after the selected historical boundary.

Txn

Synthetic time (UTC)

SQL statements

Committed effect

1

2026-09-15 13:40:00

INSERT INTO inventory VALUES (1,'apple',50);

Apple qty=50

2

2026-09-15 13:45:00

BEGIN; INSERT INTO inventory VALUES (2,'banana',20); UPDATE inventory SET qty=55 WHERE id=1; COMMIT;

Approved target: apple=55; banana=20

3 harmful

2026-09-15 13:50:00

BEGIN; DELETE FROM inventory WHERE id=2; UPDATE inventory SET qty=30 WHERE id=1; COMMIT;

Unwanted: apple=30; banana absent

4

2026-09-15 13:55:00

INSERT INTO inventory VALUES (3,'orange',15);

Later valid write; excluded

5

2026-09-15 14:00:00

UPDATE inventory SET qty=60 WHERE id=1;

Later valid write; excluded

Txn3, marked as harmful, must be excluded as a whole. The independent expected-state oracle records the state after every committed transaction:

  • After Txn1: id=1 apple has qty=50; ids 2 and 3 are absent.

  • After Txn2, the approved target: id=1 apple has qty=55 and id=2 banana has qty=20.

  • After Txn3: id=1 apple has qty=30 and id=2 banana is absent.

  • After Txn4: id=1 apple has qty=30, id=2 remains absent, and id=3 orange has qty=15.

  • After Txn5: id=1 apple has qty=60, id=2 remains absent, and id=3 orange has qty=15.

Keep this oracle outside the database being recovered, for example in a reviewed incident worksheet. It must be generated from the approved synthetic script rather than inferred from the restored candidate. Adjacent transactions make a coarse time window ambiguous, while primary keys and values expose a stop that is too early, inside the wrong transaction, or beyond the target. Capture actual positions from the generated binary log; never reuse the illustrative offsets below in another environment.

# Synthetic illustration only; capture actual event boundaries in the lab
# Backup coordinate: 150
# Txn1 events begin at 160; Txn2 begins at 251
# Txn2 is complete before Txn3 begins at 381
# Txn3 begins at 381; Txn4 begins at 551
# Txn5 begins at 621

The approved replay prefix therefore starts at the backup coordinate and stops before the first event of Txn3. The expected candidate contains the complete effects of Txn1 and Txn2 only.

Use time to locate events and positions to select replay

Use time only to narrow the inspection window. mysqlbinlog interprets datetime options in the local time zone of the machine running the utility, so the lab pins that context to UTC. The MySQL event-position recovery guidance recommends locating the relevant event with datetime bounds and selecting replay with positions. The following command is diagnostic only:

TZ=UTC mysqlbinlog \
 --start-datetime="2026-09-15 13:40:00" \
 --stop-datetime="2026-09-15 14:10:00" \
 --base64-output=DECODE-ROWS --verbose \
 /evidence/binlog.000010 | less

The discovery transcript should show transaction framing, row images, event start positions, and commit markers. The expected synthetic sequence is:

  • A BEGIN at 13:40:00 (Txn1 start) and COMMIT at 13:40:01 (Txn1 end).

  • A BEGIN at 13:45:00 and COMMIT at 13:45:01.

  • A multi-statement Txn3 begins at 13:50:00, deletes id=2, updates id=1 to qty=30, and commits at 13:50:05.

  • Txn4 inserts id=3 orange at 13:55:00 and commits.

  • Txn5 updates id=1 to qty=60 at 14:00:00 and commits.

Map the unwanted business change to its containing transaction, then verify that Txn2 has committed before Txn3 begins. The selected endpoint is not “13:50.” It is the event boundary immediately before the first event of Txn3.

We document each candidate boundary in a table. For instance:

Binlog file

Synthetic event position

Boundary evidence

Replay decision

binlog.000010

160

Txn1 begins; commit observed before Txn2

Include

binlog.000010

251

Txn2 begins; commit observed before position 381

Include complete Txn2

binlog.000010

381

First event of harmful Txn3

Stop before this event

In this synthetic illustration, Txn3 begins at position 381. A replay with --stop-position=381 includes eligible events before 381 and excludes the event that begins at 381. The actual stop position must come from the inspected log, not from this article.

Separate the discovery transcript from executable input

The DECODE-ROWS and verbose output is a human diagnostic artifact. It suppresses the executable BINLOG statements required to reapply row events, so it is not the replay stream. The mysqlbinlog utility documentation distinguishes diagnostic row decoding from executable output. Generate replay input independently with the default executable event representation:

mysqlbinlog --verify-binlog-checksum \
 --start-position=150 --stop-position=381 \
 /evidence/binlog.000010 \
 > /evidence/replay-approved.sql

Label the artifacts clearly, for example discovery-binlog-000010.txt and replay-approved.sql, and record a SHA256 checksum for each. The replay file must be regenerated from the approved manifest values rather than hand-edited.

Exclude the whole unwanted transaction

Do not approve a boundary merely because it appears near the first harmful row event. Review the BEGIN or transaction context, every row event in the transaction, and the COMMIT or Xid marker. For an InnoDB-only fixture, stopping inside a transaction may leave that transaction uncommitted and rolled back when the client connection closes, but relying on that side effect is not an approved recovery boundary. The evidence must show a deliberate stop before Txn3 begins.

# at 381 # first event of unwanted Txn3; use stop-position=381

The transaction inclusion table must identify the last approved commit as present and the first event of the unwanted transaction as excluded. If the framing is ambiguous, Hold rather than guessing.

Restore the base into an isolated candidate

Provision a separate candidate with restricted networking, a unique service identity, distinct credentials, no application writers, no outbound integrations, and no registration under the production endpoint. Restore only into this isolated target. For a logical dump, a proposed command using a preconfigured login path is:

mysql --login-path=pitr-candidate inventory < /evidence/backup-20260915-133500.sql

Check the client exit status and server error log. Do not replay binary logs until the base restore has completed and its baseline has been recorded. A failed or interrupted import is diagnostic evidence, not a clean base.

Qualify backup consistency rather than assuming it

Check that the backup is consistent with its manifest. For example, verify that all tables are InnoDB:

mysql> SELECT ENGINE, COUNT(*) FROM information_schema.TABLES
 WHERE TABLE_SCHEMA='inventory' GROUP BY ENGINE;

The engine query must show only InnoDB for the selected schema. Separately review the backup job and change records for concurrent ALTER TABLE, CREATE TABLE, DROP TABLE, RENAME TABLE, or TRUNCATE TABLE activity. A successful mysqldump process does not qualify the backup if the conditions for --single-transaction consistency were violated.

If engine scope, DDL history, coordinates, privileges, or the dump checksum cannot be reconciled, place the candidate on Hold. Preserve the failed base for diagnosis, then create a new candidate from a qualified backup rather than layering recovery on an uncertain restore.

Record the baseline before applying another event

Once the restore has finished, capture key baseline metrics in the candidate. For example:

mysql> SELECT COUNT(*) FROM inventory;
mysql> SELECT SUM(qty) FROM inventory;
mysql> SHOW TABLE STATUS LIKE 'inventory';
mysql> SELECT @@VERSION, @@GLOBAL.gtid_mode, @@GLOBAL.binlog_format;

Because the synthetic base was taken before Txn1, the expected baseline contains the schema and zero fixture rows. Record COUNT(*), SUM(qty), schema definitions, table engines, server and client versions, GTID mode, binlog format, and candidate identity. These observations prove what existed before replay; they prevent a contaminated base from being mistaken for replay output.

Keep the candidate idle and isolated after baseline capture. Disable scheduled jobs, event-driven integrations, and any service discovery that could make it appear to be production. If the import failed, retain logs and the failed candidate for diagnosis, then rebuild a fresh candidate before the accepted replay attempt.

Replay the approved range without skipping errors

Generate the replay command from the reviewed manifest. The values below are synthetic and must be replaced by the candidate’s approved backup coordinate, ordered log list, and first event position of the unwanted transaction:

BACKUP_POS=150
BAD_TXN_START_POS=381
LOG_DIR=/evidence
REPLAY_SQL=/evidence/replay-approved.sql

mysqlbinlog --verify-binlog-checksum \
 --start-position="$BACKUP_POS" \
 --stop-position="$BAD_TXN_START_POS" \
 "$LOG_DIR/binlog.000010" > "$REPLAY_SQL"

sha256sum "$REPLAY_SQL" > "$REPLAY_SQL.sha256"
mysql --login-path=pitr-candidate inventory < "$REPLAY_SQL"

When the approved range spans multiple binary-log files, pass the ordered files to one mysqlbinlog invocation and apply the output through one mysql client connection. Do not run a separate mysql client per file. If the team chooses a direct pipeline, capture both producer and consumer exit status immediately:

set -o pipefail
mysqlbinlog --verify-binlog-checksum \
 --start-position="$BACKUP_POS" \
 --stop-position="$BAD_TXN_START_POS" \
 "$LOG_1" "$LOG_2" \
| mysql --login-path=pitr-candidate inventory
status=("${PIPESTATUS[@]}")
if (( status[0] != 0 || status[1] != 0 )); then
 printf 'Replay failed: mysqlbinlog=%s mysql=%s\n' "${status[0]}" "${status[1]}" >&2
 exit 1
fi

Do not use force, force-read, force-if-open, idempotent, or ignore-error behavior to manufacture a green run. Preserve the exact ordered files, start and stop positions, tool versions, output checksum, client status, and server log excerpt. Avoid ad hoc --database filtering, grep, or text deletion because those operations can remove required transaction context.

If generation or application fails, keep the candidate isolated and preserve the transcript. Unless a separately designed and tested resume procedure proves the last durable transaction and safe next event, Restart from the verified base. Blindly applying the same range twice can duplicate already committed work.

Exercise incomplete logs and interrupted replay

We intentionally test failure modes on throwaway copies to understand what breaks. Examples include:

  • Missing log file: Remove an expected predecessor from a disposable copy. Expected outcome: continuity evidence fails before replay. A file-not-found error is possible, but a later file that parses successfully does not repair the gap. Decision: Hold and recover the file, or select a different base with a complete chain.

  • Boundary inside a transaction: Choose a stop position after Txn3 begins but before it commits. Expected outcome: the selected boundary is structurally invalid. The InnoDB transaction may roll back when the client closes, leaving a candidate that looks healthy but ends earlier than intended. Decision: Restart from base with an approved between-transaction boundary.

  • Inspection-only file used as input: Apply output generated with --base64-output=DECODE-ROWS --verbose. Expected outcome: row events are not represented as the executable BINLOG statements required for replay; the client may fail or may apply an incomplete stream. Decision: invalidate the candidate and Restart from base.

  • Interrupted replay: Terminate the client after some approved transactions have committed. Expected outcome: prior commits remain while the active transaction rolls back, producing a partial prefix. Unless a qualified resume design exists, preserve the failed candidate for evidence and Restart from the verified base.

These are proposed negative tests for disposable candidates, not claims that this article’s commands were executed. A semantically wrong candidate can start normally and every process can return zero. The final state must still be reconciled against the independent oracle.

Reconcile the restored state against the independent ledger

With replay done, we now compare the candidate’s data to our expected oracle. Run queries on the restored candidate and check them against the ledger:

  • Primary-key set: SELECT id FROM inventory ORDER BY id must return exactly {1,2}. Id 1 proves Txn1 is present, id 2 proves Txn2 is present, and the absence of id 3 helps prove replay did not extend into Txn4.

  • Values: id=1 must be ('apple',55) and id=2 must be ('banana',20). Apple at 50 exposes a too-early stop; apple at 30 or a missing banana exposes Txn3; apple at 60 exposes replay beyond the target.

  • Business totals: COUNT(*) must be 2 and SUM(qty) must be 75. Totals support the decision, but they cannot replace row-level checks because different wrong states can share the same total.

  • Structural checks: Verify relevant foreign keys, uniqueness, order-to-inventory relationships, and application-level invariants. Table checksums can support comparison, but a checksum alone does not explain which transaction was included.

The reconciliation must contain one check for the last approved commit, one for every effect of the unwanted transaction, one for a too-early stop, and one for replay beyond the target. A candidate with apple=50 stopped before Txn2; apple=30 or a missing banana includes Txn3; id=3 or apple=60 proves later commits crossed the boundary.

A reconciliation checklist might look like:

mysql> SELECT id, product, qty FROM inventory ORDER BY id;
+----+---------+-----+
| id | product | qty |
+----+---------+-----+
| 1 | apple | 55 |
| 2 | banana | 20 |
+----+---------+-----+

mysql> SELECT COUNT(*) AS rows_present, SUM(qty) AS total_qty FROM inventory;
+--------------+-----------+
| rows_present | total_qty |
+--------------+-----------+
| 2 | 75 |
+--------------+-----------+

mysql> SELECT COUNT(*) AS later_rows FROM inventory WHERE id=3;
+------------+
| later_rows |
+------------+
| 0 |
+------------+

Reconciliation check

Expected historical state

Candidate evidence to record

Gate

Primary-key set

{1,2}

Export SELECT id ORDER BY id

Pass only on exact match

Apple quantity

id=1, qty=55

Export row value

Catches early, bad, or late replay

Banana quantity

id=2, qty=20

Export row value

Proves Txn2; rejects Txn3

Later row

id=3 absent

COUNT(*) WHERE id=3 equals 0

Rejects replay into Txn4

Business total

2 rows; total qty=75

COUNT(*) and SUM(qty)

Supporting evidence

These are synthetic expected observations, not an execution transcript. The reviewer records the candidate’s actual results beside the oracle and signs each gate only when they agree.

The approved state contains Txn1 and Txn2 only. Every effect of Txn3 is absent, and the otherwise valid Txn4 and Txn5 are also absent because they occurred after the cutoff. Reapplying those later commits would create a different history and requires a separate dependency-aware repair plan.

Store the reconciliation queries, result exports, oracle version or checksum, reviewer identity, and decision in the evidence bundle. A mismatch means Hold while the boundary, base, logs, and replay transcript are re-examined; a contaminated or partially replayed candidate normally requires Restart from base.

Use application and database integration checks to extend the ledger from table rows to the invariants the application actually depends on.

Explain what the historical restore does not recover

It is critical to document what remains broken by this operation. Rolling back MySQL to an earlier transaction boundary does not magically rewind the outside world. For example:

  • Writes after cutoff: Any data written to other systems (logs, files, caches, or even other DBs) after 13:45:01 is now orphaned. If the application sent emails or updated a cache, those actions will not have been undone.

  • External messages: Outbound notifications (emails, messages in queues) triggered by the bad transaction or subsequent ones will still have been sent. Those recipients will need manual reconciliation.

  • Downstream databases: If this database was a source for others (via replication or ETL), those downstream snapshots are inconsistent with our restored state. They must be locked or re-synced independently.

  • System state: If any software licenses were activated, files written, or external systems called in response to now-omitted transactions, those will remain changed.

Do not graft later “good” writes onto the historical candidate without dependency analysis. Txn4 or Txn5 may depend on data, sequence values, messages, or external effects created by Txn3. Create an exclusions register covering post-cutoff database writes, outbound messages, files, caches, search indexes, downstream databases, and third-party calls. Assign each reconciliation or compensating action to an owner. This point-in-time restore qualifies only the selected MySQL state; it does not claim a universal rollback of external systems.

Approve access only after the evidence agrees

Now that all pieces are in place, we use a decision matrix to determine Accept/Hold/Restart. The restore candidate can be accepted if and only if all the following conditions are unequivocally satisfied:

  • Backup identity matches manifest: The backup used is exactly the one documented, with matching checksum and timestamp.

  • Continuous binlog chain: All required binlog files were present and intact; no gaps were found.

  • Transaction boundary approved: The chosen stop position lies between full transactions (as documented), and specifically immediately after the last good commit before the bad transaction.

  • Clean replay: The mysqlbinlog + mysql pipeline exited with code 0, and logs show no truncated or skipped events.

  • State reconciled: All target table rows, values, and business invariants match the independent ledger (as above).

If any gate fails, the candidate remains on Hold. Preserve manifests, hashes, log inventory, discovery transcript, replay artifact, command statuses, server logs, and reconciliation results for independent review. Use Restart from base when the base is contaminated, replay was interrupted or duplicated, or the approved range cannot be proved. No smoke connection or timing target overrides conflicting evidence.

Below is a simplified decision table example:

Evidence gate

Pass requirement

Failure decision

Backup identity

Method, source, checksum, versions, and coordinates agree

Hold or Restart from a qualified base

Log continuity

Every required file is attributable, ordered, readable, and intact

Hold; do not bridge a gap

Transaction boundary

Last approved commit is complete; unwanted transaction has not begun

Hold and reselect the boundary

Replay execution

Approved range applied once with clean producer, client, and server evidence

Restart from base

Business reconciliation

Primary keys, values, relationships, and totals match the oracle

Hold; Restart if the candidate is contaminated

Overall decision

All gates pass and independent reviewer signs

No application access

Accept releases this candidate only after every required gate passes. Hold keeps it isolated while evidence is disputed or incomplete. Restart discards the candidate and rebuilds from the verified base. A successful login, process start, or simple SELECT cannot substitute for the full evidence chain.

Before handover, complete a decision record that binds the accepted state to the candidate identity, base backup checksum, ordered log set, replay start and stop positions, oracle version, reconciliation result, independent reviewer, and access authorization.

Decision-record field

Required evidence

Candidate identity

Unique host or instance ID, port, network zone, and creation time

Base backup

Filename, source identity, method, creation record, and SHA256

Replay range

Ordered log list, start position, stop position, and replay artifact SHA256

Expected-state oracle

Version or checksum plus independent owner

Review result

Reconciliation sheet, unresolved exclusions, and decision: Accept, Hold, or Restart

Authorization

Recovery owner, application reviewer, incident authority, and access time

Plan the handover and the route back

Assuming the candidate is accepted, we now plan how to actually switch the application to it, and ensure there is a rollback path if anything goes wrong. This phase is as much operational coordination as it is technical. Steps might include:

  • Freeze writes: Place the original application path under a controlled write freeze before endpoint changes. Record the freeze time and owner; do not rely on an informal request.

  • Protect original evidence: Retain the untouched source, qualified backup, binary logs, manifests, and failed candidates under access control until incident closure and retention requirements are met.

  • Control the endpoint: Route only the approved application tier to the accepted candidate. Verify DNS, service discovery, secrets, connection pools, jobs, and integrations so the candidate cannot coexist as an accidental second writer.

  • Verify first operations: The application owner checks the historical invariants before writes resume, then records the first authorized read and write operations. In the synthetic example, apple remains 55 and banana remains 20 before any new write.

  • Resume progressively: Enable write traffic in controlled stages, monitor database and application errors, and record the new post-handover transaction boundary. New writes belong to a new history and change the recovery options.

After new writes begin, returning to the former source is not a simple connection-string rollback. It requires its own reconciliation or migration plan because the two histories have diverged. Keep a final stop point before writes resume, assign owners for external compensation, and use clear communication during database incidents so each approval and dependency is understood.

Record the handover in a step-by-step form. For example:

  1. 00:00: Disable application writes to the original database and record the freeze.

  2. 00:05: Route read-only validation traffic to the accepted candidate and run the approved checks.

  3. 00:10: Authorize one controlled write, verify its database and application effects, and record its transaction identifier.

  4. 00:15: Review database, application, queue, and integration telemetry for unexpected behavior.

  5. 00:30: If the owner-approved gates remain satisfied, restore normal traffic and close the controlled handover window.

These times are a proposed drill sequence, not measured recovery performance. Report actual durations only after a controlled exercise. Keep the original source protected and non-writable until the post-handover reconciliation plan is complete.

Build database foundations for recovery decisions

Recovery decisions depend on database fundamentals, SQL fluency, backup qualification, performance monitoring, and clear operational ownership. Readers building those foundations can review the Refonte Learning Database Administrator Program. Its page lists a three-month format, 12–14 hours per week, and topics including database backup and recovery, SQL optimization, performance monitoring, and disaster-recovery strategies. It also names database fundamentals, advanced SQL, and MySQL Workbench. The page does not establish that this specific MySQL 8.4 transaction-boundary lab or its failure injections are included.

  • Explain the difference between logical, physical, full, and incremental backup evidence, and state the consistency conditions for the selected method.

  • Use mysqlbinlog datetime options to locate events and position options to define an approved replay range.

  • Qualify an InnoDB --single-transaction dump by checking engine scope, coordinate capture, privileges, and concurrent DDL conditions.

  • Communicate the cutoff, exclusions, evidence gaps, decision authority, and route back to technical and business reviewers.

Use this learning evidence checklist to assess whether the team can review the runbook rather than merely copy its commands:

☐ Explain the selected backup method and its consistency limits.

☐ Locate binary-log events and distinguish discovery output from executable replay input.

☐ Identify complete InnoDB transaction boundaries and reject an ambiguous cutoff.

☐ Build a controlled replay artifact and verify producer, client, and server results.

☐ Reconcile restored rows and application invariants against an independent oracle.

A checked box should correspond to demonstrated evidence in a disposable lab or reviewed exercise, not simple familiarity with the terminology.

Accept the state you proved, not the server that started

The final handover checklist is compact because the supporting evidence has already been built:

  • Backup manifest: who, what, when, and the starting binlog coordinates.

  • Log inventory: a table of binlog files, their order and integrity.

  • Transaction boundary approval: a record (table) showing the selected last-included transaction and stop position.

  • Replay transcript: the full mysqlbinlog SQL output file, with checksums, that was applied.

  • State reconciliation: query results or checksums comparing the restored data to the expected ledger.

  • Access decision: signed off by the recovery owner, app reviewer, and incident authority (Accept/Hold).

Accept the state only when the backup manifest, log chain, transaction boundary, replay record, and business reconciliation all describe the same candidate. Hold is a legitimate outcome when evidence is incomplete. Restart from base is the safer outcome when a failed or interrupted attempt cannot be resumed from a proven event boundary.

A point-in-time recovery can establish a specific historical MySQL prefix; it cannot guarantee zero data loss, rewind external systems, or prove universal production readiness. The server that started is not the asset being approved. The approved asset is the database state the evidence actually supports.