mysql基于 Binlog 的主从复制平滑迁移
2026-02-24 / SQL / 9 次围观 / 0 次吐槽 /第一步:配置旧库(主库)
旧库必须开启了 binlog(二进制日志),这是同步数据的基石。
1.检查旧库配置 (/etc/mysql/my.cnf 或 /etc/mysql/mysql.conf.d/mysqld.cnf),确保有以下参数:
[mysqld]server-id = 1 log_bin = /var/log/mysql/mysql-bin.log
(如果修改了配置,需要重启旧库。如果已经开启了,则跳过重启)
2.在旧库上创建一个专门用于同步的账号:
CREATE USER 'repl_user'@'%' IDENTIFIED BY '你的同步密码';GRANT REPLICATION SLAVE ON *.* TO 'repl_user'@'%'; FLUSH PRIVILEGES;
第二步:获取旧库的“快照”和“位点”(关键)
我们需要导出一份旧库的当前数据,并且记住导出这一瞬间,日志走到了哪个位置。
1.在旧库服务器上执行(替换密码和库名):
# --single-transaction 保证导出时不锁表(不影响业务写入) # --master-data=2 会在导出的 SQL 文件里自动记录当时的 Binlog 文件名和位置 mysqldump -u root -p \ --single-transaction \ --master-data=2 \ --routines --events --triggers \ --databases sql1 sql2 > /tmp/snapshot.sql
导出完成后,打开 head -n 30 /tmp/snapshot.sql | grep "CHANGE MASTER TO",记下这两个值:
-- CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000022', MASTER_LOG_POS=175710;
2.导出指定用户的权限文件
# 请将 IN (...) 括号里的用户名替换为你真正需要迁移的两个用户名
mysql -u root -p -B -N -e \
"SELECT CONCAT('SHOW CREATE USER \'', user, '\'@\'', host, '\'; SHOW GRANTS FOR \'', user, '\'@\'', host, '\';') FROM mysql.user WHERE user IN ('user1', 'user2');" \
| mysql -u root -p -B -N \
| sed 's/$/;/g' > /tmp/users.sql第三步:配置新库并导入数据
1.配置新库,确保新库的 server-id 和旧库不一样(比如设为 2) (/etc/mysql/my.cnf 或 /etc/mysql/mysql.conf.d/mysqld.cnf):
[mysqld] server-id = 2 log_bin = /var/log/mysql/mysql-bin.log #持久化 replicate-do-db = sql1 replicate-do-db = sql2
2.重启新库生效。
3.把刚才旧库导出的用户权限文件和数据导入到新库:
mysql -u root -p < /tmp/users.sql # 强制刷新权限,让账号立刻生效 # mysql -u root -p -e "FLUSH PRIVILEGES;" mysql -u root -p < /tmp/snapshot.sql
第四步:开启同步,让新库同步旧库数据
1.设置只同步指定的数据库
-- 设置同步白名单(只同步这两个库,如果有其他库请继续用逗号隔开) CHANGE REPLICATION FILTER REPLICATE_DO_DB = (sql1, sql2);
2.登录到新库的 MySQL 命令行,告诉它旧库在哪里,以及从哪个位置开始同步:
CHANGE MASTER TO MASTER_HOST='旧库的IP地址', MASTER_USER='repl_user', MASTER_PASSWORD='你的同步密码', MASTER_LOG_FILE='刚才记下的文件名', -- 例如 'mysql-bin.000022' MASTER_LOG_POS=刚才记下的数字; -- 例如 175710;
3.开始同步
START SLAVE;
4.检查同步状态:
SHOW SLAVE STATUS \G
如果 Slave_IO_Running 和 Slave_SQL_Running 都是 Yes,说明同步成功了!
看 Seconds_Behind_Master 这个值,等它变成 0,就说明新库已经和旧库完全实时同步了。
第五步:业务切换(割接)
停旧库写入:把旧库设为只读
SET GLOBAL read_only = 1;,或者直接把应用服务停掉。确认完全同步:在新库上最后看一眼
SHOW SLAVE STATUS \G;,确保Seconds_Behind_Master为 0。新库解除主从关系:在新库执行
STOP SLAVE; RESET SLAVE ALL;,让新库变成独立的主库。修改代码配置:把你的业务代码里的数据库 IP 改为新库 IP。
启动业务:大功告成,迁移过程对用户基本无感(只断开几秒钟)。
Powered By Cheug's Blog
Copyright Cheug Rights Reserved.