迁移期间应交叉验证Seconds_Behind_Master、SQL_Delay、Slave_SQL_Running_State及pt-heartbeat结果,并配置log_error_verbosity=3、ROW格式binlog、TABLE型复制元数据以保障监控与排障有效性。

迁移期间如何实时监控 MySQL 主从同步延迟
迁移常依赖主从复制,Seconds_Behind_Master 是最直接的延迟指标,但它在某些场景下会显示 NULL 或 0 却实际不同步——比如从库 SQL 线程已停止、或启用多线程复制(slave_parallel_type = LOGICAL_CLOCK)时该值不可靠。
更稳妥的方式是结合以下三项交叉验证:
- 查
SHOW SLAVE STATUS\G中的SQL_Delay(是否人为设了延迟)、Slave_SQL_Running_State(如卡在 “Reading event from the relay log” 可能是大事务回放慢) - 用
pt-heartbeat工具:在主库定时写入时间戳,从库读取并计算差值,结果不受复制线程状态影响,适合跨版本/云环境 - 监控
relay_log_space_limit是否被突破:空间不足会导致 I/O 线程暂停,表现为Slave_IO_Running: Yes但无新中继日志写入
迁移中必须开启的关键日志与参数设置
默认配置下,MySQL 日志对排障支撑很弱。迁移过程一旦出错(如字符集不一致导致同步中断、DDL 失败),没有足够日志几乎无法定位。
需在从库(及必要时主库)补充配置:
-
log_error_verbosity = 3:让错误日志包含连接上下文、SQL 原始语句和堆栈(MySQL 8.0+),避免只看到 “Error 1032” 却不知哪条语句触发 -
binlog_format = ROW+binlog_row_image = FULL:确保从库重放时有完整行镜像,防止因部分列更新导致数据不一致;注意该组合会增大 binlog 体积,迁移前需确认磁盘余量 -
relay_log_info_repository = TABLE和master_info_repository = TABLE:把复制元数据存到mysql.slave_relay_log_info表中,比文件方式更可靠,崩溃后不易丢失位置点
如何快速识别迁移中的复制中断原因
执行 SHOW SLAVE STATUS\G 后,重点不是只看 Seconds_Behind_Master,而是盯住三个字段:
-
Last_IO_Errno/Last_SQL_Errno:数值非 0 就代表出错,常见如2003(连接主库失败)、1032(行不存在)、1062(唯一键冲突) -
Last_IO_Error/Last_SQL_Error:直接给出错误原文,例如 “Could not execute Delete_rows event on table db.t; Can’t find record in ‘t’” 就说明从库缺数据 -
Retrieved_Gtid_SetvsExecuted_Gtid_Set:若前者远大于后者,说明中继日志堆积但没执行,大概率是 SQL 线程卡住;两者相等但Seconds_Behind_Master非零,可能是 GTID 模式下存在空事务或 auto-position 同步异常
监控工具链里最容易被忽略的细节
用 Prometheus + mysqld_exporter 监控时,很多人只加 collect.slave_status,却漏掉 collect.global_status 和 collect.info_schema.processlist。
实际迁移中,这几个指标往往比延迟值更有预警价值:
-
mysql_global_status_slave_open_temp_tables持续上升:说明从库频繁创建临时表,可能因排序或 GROUP BY 操作内存不足,触发磁盘临时表,严重拖慢回放 -
mysql_info_schema_processlist_time中出现大量State: Waiting for table metadata lock:通常是主库有长事务未提交,阻塞了从库 DDL,此时SHOW PROCESSLIST在从库看不到主库锁源,必须去主库查information_schema.INNODB_TRX -
mysql_slave_status_seconds_behind_master的采集间隔不能大于 5 秒:延迟突增可能仅持续几秒,间隔过长会漏掉关键毛刺
真正难的不是加监控,而是理解每个数字背后对应的 MySQL 内部状态流转。比如 Seconds_Behind_Master 归零时,SQL 线程仍可能卡在 apply event 的某个 mutex 上——这时候得看 performance_schema.events_waits_summary_by_thread_by_event_name 才能确认。










