Monitor replica lag and applier worker errors (performance_schema)
MySQLReplicationCommand
-- Receiver (I/O) thread: connection state and last error
SELECT CHANNEL_NAME, SERVICE_STATE, LAST_ERROR_NUMBER,
LEFT(LAST_ERROR_MESSAGE, 100) AS last_error,
LAST_QUEUED_TRANSACTION, LAST_HEARTBEAT_TIMESTAMP
FROM performance_schema.replication_connection_status;
-- Applier workers: error, applied GTID and real lag
SELECT CHANNEL_NAME, WORKER_ID, SERVICE_STATE, LAST_ERROR_NUMBER,
LEFT(LAST_ERROR_MESSAGE, 120) AS last_error,
LAST_APPLIED_TRANSACTION,
APPLYING_TRANSACTION,
IF(APPLYING_TRANSACTION = '', 0,
TIMESTAMPDIFF(SECOND, APPLYING_TRANSACTION_ORIGINAL_COMMIT_TIMESTAMP, NOW(6))) AS current_lag_sec,
TIMESTAMPDIFF(MICROSECOND, LAST_APPLIED_TRANSACTION_ORIGINAL_COMMIT_TIMESTAMP,
LAST_APPLIED_TRANSACTION_END_APPLY_TIMESTAMP) / 1000000 AS last_trx_lag_sec
FROM performance_schema.replication_applier_status_by_worker
ORDER BY CHANNEL_NAME, WORKER_ID;What it does
Breaks down what SHOW REPLICA STATUS summarizes in a single row, per channel and per worker: receiver thread state, each worker's last error, the applied / currently applying GTID and the real lag computed from the original commit timestamp.
When to use it
When Seconds_Behind_Source looks unreliable (jumping between 0 and large values, NULL), to find which worker is stuck on a multi-threaded replica, and to feed an accurate lag metric into monitoring.
Caution
current_lag_sec is meaningful only while a transaction is being applied; an idle replica returns 0. To see whether the receiver is also behind, compare LAST_QUEUED_TRANSACTION with the source's gtid_executed. The original commit timestamp comes from the source clock; clock skew between servers (NTP) distorts the result. Seconds_Behind_Source stays near zero at the start of a large transaction and jumps at the end; long transactions make that metric misleading.