mysql数据库迁移中的主从复制配置与优化

12次阅读

主从复制前须确认4个状态:主库SHOW MASTER STATUS确保File/position非空且GTID有值;从库SHOW SLAVE STATUS检查IO和sql线程为Yes、延迟不增;server_id主从不同;log_bin开启且binlog_format统一为ROW。

mysql数据库迁移中的主从复制配置与优化

主从复制前必须确认的 4 个状态

主从同步失败,80% 源于基础状态没对齐。别急着改 my.cnf,先在主库和从库分别执行:

  • SHOW MASTER STATUS;(主库)——确认 FilePosition 非空,且 Executed_Gtid_Set 有值(若启用了 GTID)
  • SHOW SLAVE STATUSG(从库)——重点看 Slave_IO_RunningSlave_SQL_Running 是否都为 YesSeconds_Behind_Master 是否持续增长
  • select @@server_id; —— 主从必须不同,否则复制线程直接拒绝启动
  • SELECT @@log_bin, @@binlog_format; —— 主库 log_bin 必须为 ONbinlog_format 建议统一用 ROW(避免语句级复制在从库因函数/临时表等导致不一致)

配置文件里最容易写错的 3 个参数

my.cnf 中几个关键项看似简单,但拼写、作用域或默认值陷阱极多:

  • server-id:必须是整数(如 12),不能是 1.0字符串 "1";且仅在 [mysqld] 段生效,[client] 段无效
  • log-bin:值不是布尔,而是日志文件前缀(如 log-bin = /var/lib/mysql/mysql-bin),路径需 MySQL 进程有写权限;若只写 log-bin 不带值,MySQL 会用主机名自动命名,但迁移时易引发路径不一致问题
  • binlog-do-dbreplicate-do-db:慎用!它们不支持通配符,且对跨库语句(如 INSERT INTO db2.t SELECT * FROM db1.t)行为不可靠;更安全的做法是用 replicate-wild-do-table = db1.%

GTID 模式下 CHANGE MASTER TO 的写法差异

启用 GTID(gtid_mode=ON + enforce_gtid_consistency=ON)后,不能再用传统 MASTER_LOG_FILE/MASTER_LOG_POS,必须用 MASTER_AUTO_POSITION=1

CHANGE MASTER TO   MASTER_HOST='192.168.1.10',   MASTER_USER='repl',   MASTER_PASSword='xxx',   MASTER_PORT=3306,   MASTER_AUTO_POSITION=1;

如果从库已有旧复制关系,执行前必须先 STOP SLAVE;RESET SLAVE ALL;(注意是 ALL,否则 gtid_purged 可能残留冲突值);主库导出时也要用 mysqldump --set-gtid-purged=ON,否则从库恢复后无法自动定位同步起点。

从库延迟高时优先检查的 3 类瓶颈

Seconds_Behind_Master 持续 > 60 秒,不要立刻调大 slave_parallel_workers

  • 单线程 SQL 回放卡住:查 SHOW PROCEsslISTState 是否长期停留在 UpdatingCreating sort index,说明某条大事务(如 ALTER TABLE 或未加索引的 delete)正在阻塞整个 SQL 线程
  • 磁盘 I/O 跟不上:用 iostat -x 1 观察 %util 是否持续 > 90%,尤其是从库的 mysql-bin 所在磁盘;sync_binlog=1innodb_flush_log_at_trx_commit=1 在从库可酌情改为 02(牺牲少量安全性换吞吐)
  • 网络抖动导致 IO 线程反复重连:检查 Seconds_Behind_Master 是否周期性归零又跳升,配合 tcpdump 抓包看是否有频繁 RST;可在主库设置 slave_net_timeout=60,从库设 master_connect_retry=30 避免重试风暴

真正难处理的是混合了大事务和高并发写入的场景——这时候单靠配置调优收效甚微,得拆分业务逻辑或引入中间件做读写分流。

text=ZqhQzanResources