MySQL大库迁移缩至秒级停写窗口的核心是:用--single-transaction+--master-data=2组合,通过事务快照保证一致性,并在dump文件中精准记录binlog位点;dump完成后立即执行FLUSH TABLES WITH READ LOCK(几秒内完成),而非全程锁表。

不能直接“无缝”改造,必须停写或锁表做一次初始同步;所谓“安全”核心是控制主库写入中断时间、避免从库误写、确保 binlog 位置精准对齐。
主库停写窗口怎么缩到最短
关键不是“不停写”,而是把写入中断压缩到秒级。mysqldump 加 --single-transaction 和 --master-data=2 是最常用组合:前者用事务快照保证一致性,后者在 dump 文件开头自动插入 CHANGE MASTER TO 所需的 MASTER_LOG_FILE 和 MASTER_LOG_POS。
- 执行前先在主库运行
SHOW MASTER STATUS记下当前File和Position,和 dump 文件里生成的值比对,确认没漂移 - dump 过程中主库仍可写,但 dump 完成后要立刻执行
FLUSH TABLES WITH READ LOCK—— 这一步才真正停写,几秒内做完解锁即可 - 如果业务完全不能接受任何锁,就得用物理备份(如 Percona XtraBackup),它支持热备份 +
--slave-info,但要求主库已启用log-bin且未跳过binlog
从库启动时为什么总报 Slave_IO_Running: No
90% 是连接或权限问题,不是数据问题。先检查 SHOW SLAVE STATUS\G 中的 Seconds_Behind_Master、IO_Running、SQL_Running 三个字段,再看 Last_IO_Error 具体内容。
-
Access denied for user 'repl'@'xxx':复制用户没在主库创建,或密码错误,或主机名/IP 不匹配('repl'@'192.168.1.%'比'repl'@'%'更安全也更可控) -
Can't connect to MySQL server:从库连不上主库 3306 端口,检查bind-address是否为0.0.0.0、防火墙是否放行、SELinux 是否拦截(setenforce 0临时验证) -
Could not find first log file name in binary log index file:主库log-bin路径配置错,或从库CHANGE MASTER TO里填的MASTER_LOG_FILE文件名不存在(注意大小写和扩展名,如mysql-bin.000001不是binlog.000001)
read_only=1 在从库上到底要不要开
要开,而且必须在 START SLAVE 之前就生效。否则应用误连从库执行 INSERT 或 DROP,会导致主从数据不一致,且后续无法自动修复。
- 仅靠权限控制不够:DBA 或运维仍可能用 root 登录从库执行写操作
- 配置项必须写进
/etc/my.cnf的[mysqld]段,并重启 MySQL 或执行SET PERSIST read_only = ON(MySQL 8.0+)才能持久化 - 例外情况:当从库需临时升级为主库(failover),先
SET GLOBAL read_only = OFF,再STOP SLAVE,否则STOP SLAVE会失败
验证同步是否真可靠,不能只看 Seconds_Behind_Master = 0
Seconds_Behind_Master = 0 只代表 SQL 线程追上了中继日志末尾,不代表数据逻辑一致。生产环境必须做三件事:
- 在主库建测试表
CREATE TABLE test_replica (id INT PRIMARY KEY, ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP),插一行INSERT INTO test_replica VALUES (1, NOW()) - 立刻在从库查:
SELECT * FROM test_replica,确认有且仅有一行,且ts值与主库误差 - 跑
pt-table-checksum(Percona Toolkit)全量校验表数据一致性,尤其注意大表和含TIMESTAMP字段的表——它们容易因时区或默认值行为差异导致隐式不一致
真正麻烦的是那些没显式报错、但字段值悄悄变掉的情况,比如主库 sql_mode 包含 STRICT_TRANS_TABLES 而从库没配,一条带警告的 INSERT 在主库被拒绝,在从库却成功写入空值。


















