一、MySQL主从复制基础
1.1 核心原理与架构
主从复制通过二进制日志(binlog)实现数据同步,核心依赖三个线程和两类日志:
主库 :binlog dump
线程(发送 binlog 事件)
从库 :IO线程
(接收 binlog 并写入中继日志 relay log)、SQL线程
(执行中继日志事件)
关键日志:主库的 binlog(记录所有变更)、从库的 relay log(暂存主库 binlog)
同步流程:
1.从库执行CHANGE REPLICATION SOURCE TO
配置主库信息及同步起点
2.从库 IO 线程与主库 binlog dump 线程建立连接
3.主库推送 binlog 事件至从库,从库写入 relay log
4.从库 SQL 线程解析 relay log 并重演操作
1.2 基础配置步骤
环境准备
|----|-----------------|-----------|
| | IP地址 | server-id |
| 主库 | 192.168.168.200 | 200 |
| 从库 | 192.168.168.129 | 129 |
主库配置
1.启用binlog并配置唯一标识:
修改/etc/my.cnf:
bash
[mysqld]
server_id=200 # 唯一标识,不可与从库重复
log_bin=/data/mysql/binlog # binlog存储路径
binlog_format=ROW # 推荐行级复制,避免语句级复制的兼容性问题
expire_logs_days=7 # binlog自动保留7天
重启主库:
bash
systemctl restart mysqld
2.创建复制专用用户
登录主库MySQL,创建具有复制权限的用户:
sql
-- 创建用户(允许从库IP访问)
CREATE USER 'repl_user'@'192.168.168.129' IDENTIFIED BY 'Repl@123';
-- 授予复制权限
GRANT REPLICATION SLAVE ON *.* TO 'repl_user'@'192.168.168.129';
-- 刷新权限
FLUSH PRIVILEGES;
3.获取主库同步起点
锁表防止数据写入,记录binlog文件名和位置:
bash
-- 锁表(只读,不影响查询)
FLUSH TABLES WITH READ LOCK;
-- 查看主库状态(记录File和Position)
SHOW MASTER STATUS;
输出示例:
bash
+---------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+---------------+----------+--------------+------------------+
| binlog.000001 | 156 | | |
+---------------+----------+--------------+------------------+
解锁表:
sql
UNLOCK TABLES;
从库配置:
1.配置从库唯一标识:
修改/etc/my.cnf:
sql
[mysqld]
server_id=129 # 唯一标识,与主库不同
relay_log=/data/mysql/relaylog # 中继日志路径
read_only=ON # 从库只读(仅对非SUPER用户生效)
重启从库:
bash
systemctl restart mysqld
2.配置主从连接信息
登录从库MySQL,设置主库地址、用户及同步起点:
sql
-- 配置主库信息(替换为实际值)
CHANGE REPLICATION SOURCE TO
SOURCE_HOST='192.168.168.200',
SOURCE_USER='repl_user',
SOURCE_PASSWORD='Repl@123',
SOURCE_LOG_FILE='binlog.000001', # 主库SHOW MASTER STATUS中的File
SOURCE_LOG_POS=156; # 主库SHOW MASTER STATUS中的Position
3.启动同步并验证
sql
-- 启动从库同步线程
START REPLICA;
-- 查看同步状态(关键参数:Replica_IO_Running和Replica_SQL_Running需为Yes)
SHOW REPLICA STATUS\G
关键输出验证:
sql
Replica_IO_Running: Yes
Replica_SQL_Running: Yes
Seconds_Behind_Master: 0 # 0表示无延迟
基础功能验证
1.主库创建测试数据:
sql
CREATE DATABASE test_repl;
USE test_repl;
CREATE TABLE t1 (id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(20));
INSERT INTO t1 (name) VALUES ('repl_test');
2.从库验证同步结果:
sql
SHOW DATABASES LIKE 'test_repl';
USE test_repl;
SELECT * FROM t1; # 应显示主库插入的数据
二、主从复制进阶配置
2.1 延时同步(数据容灾)
通过设置从库延迟同步主库数据,可应对误操作(如误删库表),提供数据恢复窗口。
配置步骤
1.从库设置延迟(单位:秒):
sql
-- 停止同步
STOP REPLICA;
-- 设置延迟300秒(5分钟)
CHANGE REPLICATION SOURCE TO SOURCE_DELAY = 300;
-- 重启同步
START REPLICA;
2.验证延迟配置:
sql
SHOW REPLICA STATUS\G
-- 查看SQL_Delay参数,应显示300
误操作回复流程
假设主库误删除test_repl
库,从库尚未同步该操作:
1.立即停止从库 SQL 线程(防止继续同步误操作):
sql
STOP REPLICA SQL_THREAD;
2.定位误操作在 relay log 中的位置:
sql
-- 查看当前relay log文件
SHOW REPLICA STATUS\G # 记录Relay_Log_File值,如relaylog.000002
-- 解析relay log,查找删除操作的位置
SHOW RELAYLOG EVENTS IN 'relaylog.000002';
3.恢复误删除数据:
bash
-- 导出误操作前的relay log内容
mysqlbinlog --start-position=4 --stop-position=999 /data/mysql/relaylog.000002 > /tmp/recover.sql
-- 导入恢复数据
mysql -uroot -p < /tmp/recover.sql
4.重置从库(如需脱离主从关系):
sql
STOP REPLICA;
RESET REPLICA ALL; # 清除主库信息
2.2 GTID复制(全局事务ID)
GTID(全局事务 ID)通过唯一标识每个事务,简化主从同步的位置管理,支持自动定位同步起点。
GTID 格式与原理
格式:server_uuid:transaction_id
(如a235ccb1-732b-11f0-971f-000c29d6adc7:1-5
)
原理:主库提交事务时生成 GTID,从库通过 GTID 判断是否已执行该事务,避免重复执行。
配置步骤(在线切换)
1.主从库启用 GTID 一致性检查:
bash
-- 先警告模式(检查兼容性)
SET GLOBAL enforce_gtid_consistency = WARN;
-- 无警告后启用严格检查
SET GLOBAL enforce_gtid_consistency = ON;
2.逐步切换 GTID 模式(主从库均执行):
bash
-- 从OFF -> OFF_PERMISSIVE(允许匿名事务)
SET GLOBAL gtid_mode = OFF_PERMISSIVE;
-- 再到ON_PERMISSIVE(允许GTID和匿名事务)
SET GLOBAL gtid_mode = ON_PERMISSIVE;
-- 等待所有匿名事务完成(值为0时继续)
SHOW STATUS LIKE 'ongoing_anonymous_transaction_count';
-- 最终启用GTID模式
SET GLOBAL gtid_mode = ON;
3.从库切换为 GTID 同步:
bash
-- 停止同步
STOP REPLICA;
-- 启用自动定位(基于GTID)
CHANGE REPLICATION SOURCE TO SOURCE_AUTO_POSITION = 1;
-- 重启同步
START REPLICA;
4.验证 GTID 配置:
sql
-- 主库查看已执行的GTID
SELECT @@GLOBAL.gtid_executed;
-- 从库查看同步状态(确认Retrieved_Gtid_Set和Executed_Gtid_Set非空)
SHOW REPLICA STATUS\G
2.3 半同步复制(数据可靠性增强)
半同步复制确保主库提交事务前,至少有一个从库已接收并写入 relay log,避免异步复制的数据丢失风险。
配置步骤
1.主库配置:
sql
-- 安装半同步插件
INSTALL PLUGIN rpl_semi_sync_source SONAME 'semisync_source.so';
-- 启用半同步
SET GLOBAL rpl_semi_sync_source_enabled = 1;
-- 设置超时时间(3秒,超时后降级为异步)
SET GLOBAL rpl_semi_sync_source_timeout = 3000;
2.从库配置:
sql
-- 安装半同步插件
INSTALL PLUGIN rpl_semi_sync_replica SONAME 'semisync_replica.so';
-- 启用半同步
SET GLOBAL rpl_semi_sync_replica_enabled = 1;
-- 重启IO线程
STOP REPLICA IO_THREAD;
START REPLICA IO_THREAD;
3.验证半同步状态:
sql
-- 主库查看状态(Rpl_semi_sync_source_status应为ON)
SHOW STATUS LIKE 'Rpl_semi_sync_source%';
-- 从库查看状态(Rpl_semi_sync_replica_status应为ON)
SHOW STATUS LIKE 'Rpl_semi_sync_replica%';
功能测试:
1.主库插入数据,观察响应时间(正常应立即返回):
sql
INSERT INTO test_repl.t1 (name) VALUES ('semi_sync_test');
2.模拟从库故障(停止从库半同步):
bash
-- 从库执行
SET GLOBAL rpl_semi_sync_replica_enabled = 0;
STOP REPLICA IO_THREAD;
3.主库再次插入数据,应等待 3 秒后超时(降级为异步):
sql
INSERT INTO test_repl.t1 (name) VALUES ('timeout_test');
-- 输出应显示 Query OK, 1 row affected (3.00 sec)
4.恢复从库半同步:
sql
-- 从库执行
SET GLOBAL rpl_semi_sync_replica_enabled = 1;
START REPLICA IO_THREAD;
三、主从复制监控与维护
3.1 关键监控指标
1.主库监控:
sql
-- 查看从库连接数
SHOW REPLICAS;
-- 查看binlog状态
SHOW MASTER STATUS;
2.从库监控:
sql
-- 同步延迟(Seconds_Behind_Master)
SHOW REPLICA STATUS\G
-- 中继日志应用状态
SHOW GLOBAL STATUS LIKE 'Slave_sql_running_state';
3.2常见问题处理
1.同步延迟:
原因:从库 SQL 线程执行慢、网络延迟。
解决:优化从库性能、增大innodb_buffer_pool_size
、避免大事务。
2.线程异常(IO/SQL线程为no):
查看错误日志:cat /data/mysql/[hostname].err
。
常见原因:网络不通、主库 binlog 文件丢失、权限错误。
总结
主从复制通过基础配置可实现数据同步,进阶功能(延时同步、GTID、半同步)分别解决了数据容灾、同步管理复杂度、数据可靠性问题。生产环境中建议结合 GTID 和半同步复制,同时做好监控与定期备份,确保集群稳定运行。