MySQL 两台服务器同步是数据库高可用、读写分离、数据灾备等场景中的核心需求,其实质是将一台服务器(主服务器)的数据变更实时或准实时地复制到另一台服务器(从服务器),确保数据的一致性和可用性,以下是关于 MySQL 两台服务器同步的详细实现方案、步骤及注意事项。

同步方案选择
MySQL 提供了多种同步技术,主流方案包括基于二进制日志(Binlog)的异步复制、半同步复制、基于 GTID 的复制以及基于组复制(Group Replication)的高可用方案,两台服务器场景中,常用的是 Binlog 异步复制和半同步复制,前者性能较高但存在数据丢失风险,后者通过确认机制降低数据丢失风险,适合对数据一致性要求较高的场景。
环境准备
假设两台服务器分别为:主服务器(Master,IP:192.168.1.100)和从服务器(Slave,IP:192.168.1.200),操作系统均为 Linux,MySQL 版本一致(建议 5.7+ 以获得更好的 GTID 支持)。
- 网络连通性:确保两台服务器可通过 IP 互相访问,关闭防火墙或开放 MySQL 端口(默认 3306)。
- MySQL 安装:两台服务器均安装 MySQL 服务,并确保服务正常运行。
- 数据一致性(首次同步时):若主服务器已有数据,需先锁表导出数据,再导入到从服务器,确保初始数据一致。
主服务器(Master)配置
-
启用二进制日志(Binlog)
编辑 MySQL 配置文件/etc/my.cnf,在[mysqld]部分添加以下配置:[mysqld] server-id = 1 # 唯一标识,主从服务器不能相同 log-bin = mysql-bin # 启用二进制日志,日志文件前缀 binlog-format = ROW # 推荐使用 ROW 模式,记录行级变更,避免主从数据不一致 binlog-row-image = FULL # 记录完整的行数据,确保从服务器能正确解析 expire_logs_days = 7 # 二进制日志保留天数,避免日志占满磁盘
配置完成后重启 MySQL 服务:
systemctl restart mysqld。
(图片来源网络,侵删) -
创建同步用户
登录主服务器 MySQL,创建用于同步的用户并授予 REPLICATION SLAVE 权限:CREATE USER 'repl_user'@'192.168.1.200' IDENTIFIED BY 'password123'; GRANT REPLICATION SLAVE ON *.* TO 'repl_user'@'192.168.1.200'; FLUSH PRIVILEGES;
说明:
'repl_user'@'192.168.1.200'表示仅允许从服务器 IP 连接,密码需设置复杂度。 -
获取 Binlog 位置信息
执行以下命令查看当前二进制日志文件名和位置:SHOW MASTER STATUS;
返回结果如下(记录 File 和 Position 值):
+------------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000003 | 154 | | |
+------------------+----------+--------------+------------------+
(图片来源网络,侵删)
从服务器(Slave)配置
-
配置服务器 ID
编辑从服务器/etc/my.cnf,在[mysqld]部分设置唯一 server-id:[mysqld] server-id = 2 relay-log = mysql-relay-bin # 中继日志文件前缀,用于存储主服务器 Binlog 信息 read-only = 1 # 设置为只读,防止直接写入(但具有 SUPER 权限的用户仍可写)
重启 MySQL 服务:
systemctl restart mysqld。 -
首次同步(若主服务器有数据)
- 锁定主服务器表(避免数据变更):
FLUSH TABLES WITH READ LOCK; - 导出主服务器数据(如全库导出):
mysqldump -u root -p --all-databases --master-data=2 > master_data.sql
--master-data=2会自动记录导出时的 Binlog 位置信息,并注释掉。 - 将导出文件传输到从服务器:
scp master_data.sql root@192.168.1.200:/tmp/ - 解锁主服务器表:
UNLOCK TABLES; - 在从服务器导入数据:
mysql -u root -p < /tmp/master_data.sql
- 锁定主服务器表(避免数据变更):
-
配置主从复制关系
登录从服务器 MySQL,执行以下命令(使用主服务器的 File、Position 及同步用户信息):CHANGE REPLICATION SOURCE TO SOURCE_HOST = '192.168.1.100', SOURCE_USER = 'repl_user', SOURCE_PASSWORD = 'password123', SOURCE_LOG_FILE = 'mysql-bin.000003', SOURCE_LOG_POS = 154;
若 MySQL 版本为 8.0 以下,命令为
CHANGE MASTER TO;8.0+ 版本推荐使用CHANGE REPLICATION SOURCE TO(简称CHANGE SOURCE TO)。 -
启动复制线程
START REPLICA;
查看复制状态:
SHOW REPLICA STATUS\G(8.0+)或SHOW SLAVE STATUS\G(5.7-),重点关注以下字段:Replica_IO_Running: Yes(IO 线程正常运行,接收主服务器 Binlog)Replica_SQL_Running: Yes(SQL 线程正常运行,执行 Binlog 事件)Seconds_Behind_Master: 0(表示从服务器与主服务器无延迟,非 0 表示延迟秒数)
同步验证与维护
-
验证同步
在主服务器创建数据库、表或插入数据,检查从服务器是否同步:-- 主服务器执行 CREATE DATABASE test_db; USE test_db; CREATE TABLE t1 (id INT PRIMARY KEY, name VARCHAR(20)); INSERT INTO t1 VALUES (1, 'test');
从服务器执行
SELECT * FROM test_db.t1;,若能查询到数据,则同步正常。 -
常见问题处理
- IO 线程或 SQL 线程停止:检查
Last_IO_Error或Last_SQL_Error错误信息,常见原因包括网络中断、密码错误、主服务器 Binlog 被清理等。 - 数据不一致:若因误操作导致数据不一致,可使用
RESET REPLICA重置复制关系后重新配置,或通过工具(如 pt-table-checksum)校验并修复数据。
- IO 线程或 SQL 线程停止:检查
-
GTID 同步(可选)
GTID(全局事务 ID)可简化主从切换和故障恢复,主服务器配置需添加:gtid_mode = ON enforce_gtid_consistency = ON
从服务器配置
gtid_mode = ON,复制命令改为:CHANGE REPLICATION SOURCE TO SOURCE_HOST='...', SOURCE_AUTO_POSITION=1;
此时无需手动指定 File 和 Position,MySQL 会自动通过 GTID 定位事务。
FAQs
Q1:MySQL 主从复制延迟如何优化?
A:主从延迟常见原因包括从服务器负载过高、SQL 线程执行慢、网络延迟等,优化方法:(1)提升从服务器硬件配置(CPU、内存、磁盘 I/O);(2)优化主服务器 Binlog 格式(ROW 模式下减少大事务);(3)避免在从服务器执行复杂查询或写入操作(设置 read-only);(4)使用多线程复制(MySQL 5.7+ 支持 slave_parallel_workers 参数)。
Q2:主服务器故障后,如何将从服务器提升为主服务器?
A:步骤如下:(1)停止从服务器复制线程:STOP REPLICA;;(2)检查从服务器是否已同步所有主服务器 Binlog(SHOW REPLICA STATUS\G 中 Executed_Gtid_Set 或 Relay_Master_Log_File、Exec_Master_Log_Pos 确认);(3)修改从服务器配置,移除 read-only 并设置 server-id 为主服务器;(4)应用业务连接新主服务器,若需恢复原主服务器,可将其作为从服务器接入新主复制链。
