When a MySQL replica falls behind, determine whether the delay is in receiving transactions or applying them. Inspect channel state, positions, errors and worker progress together. Seconds_Behind_Source = 0 alone does not prove the replica is current with the source.1
This guide uses MySQL 8.4 asynchronous replication. It does not cover promotion or Group Replication membership decisions. The examples are read-only and untested; no replication thread was stopped, restarted or reconfigured.
Follow the pipeline
The receiver obtains the source's binary-log events and makes them available through the replica's relay-log path. The applier executes the received work. With parallel application, a coordinator and multiple workers contribute distinct status information.1, 2, 3
A healthy connection at the first stage does not establish completion at the second. Likewise, an applier waiting for more relay-log work may simply have caught up with a receiver that is itself delayed. Diagnose both stages before changing worker counts or blaming the network.
Identify the exact source, replica and channel. Multi-source deployments can have several channels with different failure states. A metric for the default channel does not describe every stream feeding the server.
Record topology and any intentional delay. A deliberately delayed replica serves a different purpose from a read replica expected to be current. Its configured delay must be considered before calling the observed age a performance fault.
Read status with its timing limits
MySQL documents this read-only statement, requiring REPLICATION CLIENT or the older broader privilege described in the reference:1
SHOW REPLICA STATUS;
Use an existing authorised monitoring account, not a new unrestricted application privilege. Capture the channel and timestamp with the result, and restrict raw output because it includes connection and infrastructure details.
The statement is nonblocking. MySQL explains that it can return while a concurrent stop operation is still completing, so it is an immediate observation rather than a synchronised proof of a final transition.1
Read at least receiver state, applier state, the relevant source/relay positions, last I/O and SQL errors with their timestamps, GTID sets where used and configured delay. Preserve the original error before any reset or restart changes the evidence.
For a specific named channel, have the DBA select the documented channel-specific form for that environment. Do not silently collapse multiple rows into one overall “replication healthy” result.
Compare received work with the actual source
On the source identified by this channel, use an existing account with REPLICATION CLIENT and capture the following read-only output. Record source identity and UTC capture time alongside it; this is a separate connection from the replica sample.5
-- Run on the verified SOURCE, not on the replica.
SHOW BINARY LOG STATUS;
With file/position replication, compare the source's File and Position with this channel's Source_Log_File and Read_Source_Log_Pos from SHOW REPLICA STATUS. Compare the channel's applied pair, Relay_Source_Log_File and Exec_Source_Log_Pos, separately. Positions are byte offsets within their named log, not globally comparable numbers: do not subtract offsets from different files or different source histories.1, 5
With GTIDs, retain the source's Executed_Gtid_Set, the channel's Retrieved_Gtid_Set, and the replica's Executed_Gtid_Set. For transactions in the intended source lineage/channel, distinguish received-but-not-executed work from source transactions absent from both retrieved and executed sets. Do not require raw equality: the replica's executed set is server-wide and can contain other channels or local work, and a retrieved set is not a permanent history of everything once received. Record filters and expected channel scope before interpreting missing transactions or application rows.1
The samples are not simultaneous. Compare against a retained source point and observe whether the replica reaches that point in an agreed bounded window while accounting for new source activity and intentional delay. A one-time difference is not proof of loss, and a single match is not proof of sustained freshness. If source access or history is unavailable, record receiver freshness as unverified rather than accepting a zero lag value.
For a GTID_ONLY channel after restart, Source_Log_File and Relay_Source_Log_File can show INVALID, with read and executed positions zero. The received pair becomes valid when the receiver obtains source position information; the applied pair becomes valid when the applier applies or skips an already executed transaction. Do not diagnose these initial values as lost position. Use the GTID and channel-state evidence until the relevant position is valid.1
Interpret the lag value carefully
In MySQL 8.4, Seconds_Behind_Source relates the event being processed to its timestamp. The manual explains that it primarily measures the applier's delay relative to the receiver. If the receiver is delayed by a slow source connection, the applier can catch up with it and show zero while the replica is still behind the actual source.1
The value can also be null when the applier is not running, or when it has exhausted relay work and the receiver is not running. Null is an undefined/unknown state in the documented cases, not a numeric zero.1
Clock-offset changes, chained replication and parallel application introduce further interpretation limits. MySQL notes that a multithreaded replica's value may not represent the most recently committed transaction's position.1 Do not convert the field directly into a guaranteed recovery-point or business-freshness statement.
Use the lag value as one symptom alongside actual movement. Record whether new transactions are being received, whether workers are completing them and whether the application's known reference data is visible.
Separate receiver problems from applier problems
The receiver's Replica_IO_Running can be Yes, No or Connecting, with different meanings. Connecting is not a completed source connection. Replica_SQL_Running reports whether the applier thread is started; it does not demonstrate that every transaction is making useful progress.1
Use these distinctions:
| Observed pattern | Primary investigation |
|---|---|
| Receiver not connected, new source work not arriving | Connection, authentication, source availability or required-log errors. |
| Receiver advances, applied position does not | Applier errors, waits, transaction work or worker/coordinator state. |
| Both advance but backlog grows | Incoming work exceeds effective receive/apply capacity. |
| Threads run and lag reads zero, but reference data is absent | Compare the retained source point with received/applied progress; check channel identity and filters before claiming freshness. |
| Errors clear after restart but data still differs | Preserve the historical failure and investigate continuity, not just current flags. |
Do not turn the first branch into generic network reconfiguration. A source authentication error and a missing binary-log interval require different owners and remedies. Keep the exact database error with any network evidence.
Inspect parallel workers
The Performance Schema replication tables expose receiver, coordinator and worker information. MySQL 8.4 includes per-worker transaction identifiers and timing fields; local timing information is not collected when Performance Schema is disabled.2, 3
This untested SELECT provides a bounded starting set of worker fields. It does not start or alter replication:
The fully qualified table name keeps the inspection in the performance_schema database regardless of the connection's current database.4
SELECT CHANNEL_NAME,
WORKER_ID,
SERVICE_STATE,
LAST_ERROR_NUMBER,
LAST_ERROR_MESSAGE,
LAST_ERROR_TIMESTAMP,
LAST_APPLIED_TRANSACTION,
APPLYING_TRANSACTION
FROM performance_schema.replication_applier_status_by_worker;
The worker table defines SERVICE_STATE = ON as a thread that exists and is active or idle. It is not a throughput metric. Error fields identify the most recent error that stopped a worker, and some fields reset on replication transitions.3 Keep lifecycle events with the samples.
Compare worker and coordinator evidence instead of assuming that more workers automatically divide every transaction evenly. A single large transaction or dependency pattern can limit useful parallelism. Confirm the actual transaction and wait evidence before changing concurrency.
Use the worker's associated thread information and approved performance diagnostics to investigate its wait. This article does not enable broad instrumentation or retrieve every SQL statement. Captures should be scoped because replication events can expose customer data.
Assess capacity and correctness together
If work arrives faster than it is applied, measure the backlog trend and source workload over a representative interval. An estimated catch-up time needs stable assumptions about arrival and processing rates; do not invent a completion time from one sample.
Inspect whether another workload on the replica competes for storage, CPU or locks, using measured evidence. A reporting query may be relevant, but its existence alone is not proof. Preserve before/after workload and worker observations for any proposed correction.
Do not skip a failed transaction, reset replication history or change GTID state merely to make the thread run. Such actions can create data divergence while improving the status display. Missing required logs or inconsistent data may require a supported reinitialisation workflow and explicit reconciliation.
A read replica's ability to answer queries is separate from freshness and promotion suitability. This article does not authorise failover based on these diagnostics. Promotion needs the wider topology, durability and write-authority decision.
Verify the corrected stage
Define acceptance as sustained receive/apply progress, understood error state, backlog within the service's agreed limit and application data matching an independently known reference. A running receiver alone is insufficient; a completed worker alone may not establish every channel's state.
Use an authorised isolated test for proposed tuning or consumer changes, with synthetic transactions that expose ordering and freshness. No such validation was performed here. If testing intentionally delayed replication, preserve the intended delay rather than treating its removal as an improvement.
Record previous settings and a return condition before changing parallelism or workload scheduling. Returning a parameter does not repair transactions already skipped or data already diverged. A supported rebuild/reseed may be necessary when continuity is lost.
Keep the final incident statement specific: which stage failed, what evidence identified it, what changed and which application checks passed. If source-reference data or channel history is unavailable, report freshness as unverified rather than using a zero lag number as proof.
Learning notes
- Receiver and applier progress are separate facts.
- Zero or null lag values have documented limitations.
- Clearing an error is not equivalent to proving data continuity and freshness.
Acceptance checklist
- [ ] Source, replica, channel, filters and intentional delay are identified.
- [ ] A retained source point is compared with received and applied progress, including GTID_ONLY caveats.
- [ ] Errors and worker evidence identify the delayed stage without treating zero/null lag as proof.
- [ ] Sustained progress and independently known application data meet the freshness requirement.
References
- MySQL :: MySQL 8.4 Reference Manual :: 15.7.7.35 SHOW REPLICA STATUS Statement. Accessed 2026-11-01.
- MySQL :: MySQL 8.4 Reference Manual :: 29.12.11 Performance Schema Replication Tables. Accessed 2026-11-01.
- MySQL :: MySQL 8.4 Reference Manual :: 29.12.11.7 The replication_applier_status_by_worker Table. Accessed 2026-11-01.
-
MySQL :: MySQL 8.4 Reference Manual :: 29.1 Performance Schema Quick Start. Accessed 2026-11-01.
-
MySQL :: MySQL 8.4 Reference Manual :: 15.7.7.1 SHOW BINARY LOG STATUS Statement. Accessed 2026-11-02.