MySQL 主从同步功能概述
核心功能
- 数据冗余:提供实时数据备份
- 负载均衡:分离读写操作提升性能
- 高可用:主库故障时快速切换
- 数据分发:跨地域数据同步
复制模式对比
模式 | 数据一致性 | 性能影响 | 适用场景 |
---|---|---|---|
异步复制 | 最终一致 | 低延迟 | 通用场景 |
半同步复制 | 强一致(部分节点) | 中等延迟 | 金融交易 |
组复制 | 强一致 | 较高延迟 | 高可用集群 |
GTID复制 | 精确位点 | 低延迟 | 复杂拓扑 |
一、异步主从复制配置
1. 主库配置
bash
# 编辑主库配置文件
[root@localhost ~]# vi /etc/my.cnf
[mysqld]
server-id=1
log-bin=mysql-bin
binlog_format=ROW
binlog_do_db=app_db # 指定复制数据库
# 重启MySQL
[root@localhost ~]# systemctl restart mysqld
# 创建复制用户
[root@localhost ~]# mysql -u root -p
mysql> CREATE USER 'repl'@'192.168.1.%' IDENTIFIED BY 'ReplPass123!';
mysql> GRANT REPLICATION SLAVE ON *.* TO 'repl'@'192.168.1.%';
mysql> FLUSH PRIVILEGES;
# 查看二进制日志位置
mysql> SHOW MASTER STATUS;
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000001 | 785 | app_db | | |
+------------------+----------+--------------+------------------+-------------------+
2. 从库配置
bash
# 编辑从库配置文件
[root@localhost ~]# vi /etc/my.cnf
[mysqld]
server-id=2
relay-log=mysql-relay-bin
read-only=1
replicate-do-db=app_db
# 重启MySQL
[root@localhost ~]# systemctl restart mysqld
# 配置复制链路
[root@localhost ~]# mysql -u root -p
mysql> CHANGE MASTER TO
MASTER_HOST='192.168.1.100',
MASTER_USER='repl',
MASTER_PASSWORD='ReplPass123!',
MASTER_LOG_FILE='mysql-bin.000001',
MASTER_LOG_POS=785;
# 启动复制
mysql> START SLAVE;
# 检查复制状态
mysql> SHOW SLAVE STATUS\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.1.100
Master_User: repl
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000001
Read_Master_Log_Pos: 785
Relay_Log_File: mysql-relay-bin.000002
Relay_Log_Pos: 320
Relay_Master_Log_File: mysql-bin.000001
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB: app_db
Seconds_Behind_Master: 0
二、半同步复制配置
1. 主库安装插件
bash
mysql> INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
mysql> SET GLOBAL rpl_semi_sync_master_enabled=1;
mysql> SET GLOBAL rpl_semi_sync_master_timeout=1000; # 1秒超时
2. 从库安装插件
bash
mysql> INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';
mysql> SET GLOBAL rpl_semi_sync_slave_enabled=1;
mysql> STOP SLAVE IO_THREAD;
mysql> START SLAVE IO_THREAD;
3. 验证半同步
bash
# 主库查看状态
mysql> SHOW STATUS LIKE 'Rpl_semi_sync%';
+--------------------------------------------+-------+
| Variable_name | Value |
+--------------------------------------------+-------+
| Rpl_semi_sync_master_clients | 1 | # 从库数量
| Rpl_semi_sync_master_net_avg_wait_time | 0 |
| Rpl_semi_sync_master_status | ON | # 半同步状态
+--------------------------------------------+-------+
三、GTID 复制模式
1. 主库启用GTID
bash
# 编辑配置文件
[root@localhost ~]# vi /etc/my.cnf
[mysqld]
gtid_mode=ON
enforce_gtid_consistency=ON
# 重启生效
[root@localhost ~]# systemctl restart mysqld
2. 从库配置
bash
# 编辑配置文件
[root@localhost ~]# vi /etc/my.cnf
[mysqld]
gtid_mode=ON
enforce_gtid_consistency=ON
log_slave_updates=ON
# 重启生效
[root@localhost ~]# systemctl restart mysqld
# 配置复制
mysql> CHANGE MASTER TO
MASTER_HOST='192.168.1.100',
MASTER_USER='repl',
MASTER_PASSWORD='ReplPass123!',
MASTER_AUTO_POSITION=1; # 启用自动定位
mysql> START SLAVE;
3. 验证GTID
bash
mysql> SHOW SLAVE STATUS\G
...
Retrieved_Gtid_Set: 6d4c8a1e-71f9-11ed-9b7d-000c29be3a7d:1-100
Executed_Gtid_Set: 6d4c8a1e-71f9-11ed-9b7d-000c29be3a7d:1-100
Auto_Position: 1
...
四、多源复制配置
1. 从库配置
bash
# 配置主库1
mysql> CHANGE MASTER TO
MASTER_HOST='192.168.1.100',
MASTER_USER='repl',
MASTER_PASSWORD='ReplPass123!',
MASTER_LOG_FILE='mysql-bin.000001',
MASTER_LOG_POS=785
FOR CHANNEL 'master1';
# 配置主库2
mysql> CHANGE MASTER TO
MASTER_HOST='192.168.1.101',
MASTER_USER='repl',
MASTER_PASSWORD='ReplPass123!',
MASTER_LOG_FILE='mysql-bin.000002',
MASTER_LOG_POS=456
FOR CHANNEL 'master2';
# 启动复制通道
mysql> START SLAVE FOR CHANNEL 'master1';
mysql> START SLAVE FOR CHANNEL 'master2';
2. 查看通道状态
bash
mysql> SHOW SLAVE STATUS FOR CHANNEL 'master1'\G
...
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
...
命令总结表格
演示命令 | 功能描述 | 关键参数 |
---|---|---|
CHANGE MASTER TO ... |
配置复制链路 | MASTER_HOST , MASTER_LOG_FILE , MASTER_LOG_POS |
START SLAVE |
启动复制 | 无 |
STOP SLAVE |
停止复制 | 无 |
SHOW SLAVE STATUS\G |
查看复制状态 | \G 格式化输出 |
SET GLOBAL rpl_semi_sync_master_enabled=1 |
启用半同步 | 主库设置 |
INSTALL PLUGIN ... SONAME 'semisync_master.so' |
安装半同步插件 | 插件名称 |
SET GLOBAL gtid_mode=ON |
启用GTID | 全局事务标识 |
CHANGE MASTER TO MASTER_AUTO_POSITION=1 |
启用GTID自动定位 | 自动位点同步 |
START SLAVE FOR CHANNEL 'channel_name' |
多源复制启动 | 通道名称 |
RESET SLAVE ALL |
重置复制配置 | 清除所有复制信息 |
功能作用详解
1. 复制工作原理
二进制日志流程
写入 传输 重放 主库 Binary Log Relay Log 从库数据
线程模型
- 主库:Binlog Dump Thread 发送日志
- 从库:
- I/O Thread:接收日志写入Relay Log
- SQL Thread:重放Relay Log中的事件
2. 复制模式深度解析
异步复制
bash
# 优点:高性能
# 缺点:数据延迟,可能丢失事务
半同步复制
bash
# 配置要求
rpl_semi_sync_master_wait_point=AFTER_SYNC # 推荐设置
# 数据安全:至少一个从库确认才提交
GTID 复制
bash
# 全局事务标识格式
source_id:transaction_id # 例如 6d4c8a1e-71f9-11ed-9b7d-000c29be3a7d:100
# 优势:
1. 自动故障切换
2. 精确位点恢复
3. 简化复杂拓扑管理
3. 高级复制拓扑
级联复制
Master Slave1 Slave2 Slave3
- 应用场景:跨数据中心同步
- 配置要点 :从库需开启
log_slave_updates
双主复制
MasterA MasterB
-
配置要求:
iniauto_increment_increment=2 auto_increment_offset=1 # MasterA auto_increment_offset=2 # MasterB
-
风险:冲突处理需应用层解决
4. 故障处理指南
常见错误
- 1062 主键冲突:数据不一致导致
- 1236 日志丢失:主库日志被清除
- 1593 复制中断:网络故障或配置错误
修复步骤
bash
# 跳过错误(谨慎使用)
mysql> STOP SLAVE;
mysql> SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1;
mysql> START SLAVE;
# 重建复制
1. 主库全量备份
2. 从库恢复备份
3. 重新配置复制位点
监控指标
sql
SHOW SLAVE STATUS 关键字段:
Seconds_Behind_Master: 0 # 复制延迟秒数
Slave_SQL_Running_State: Slave has read all relay log # SQL线程状态
Last_IO_Error: # IO线程错误信息
5. 性能优化
并行复制
ini
# 配置从库
slave_parallel_type=LOGICAL_CLOCK
slave_parallel_workers=8
过滤规则
sql
# 复制指定表
REPLICATE_WILD_DO_TABLE=app_db.important_%
# 忽略系统表
REPLICATE_IGNORE_DB=mysql
延迟控制
sql
# 设置最大延迟
CHANGE MASTER TO MASTER_DELAY=3600; # 延迟1小时
# 适用场景:误操作恢复缓冲
6. 高可用集成
MHA 自动故障转移
bash
# 安装MHA
yum install mha4mysql-manager mha4mysql-node
# 配置管理节点
vi /etc/mha/app1.cnf
[server default]
manager_workdir=/var/log/mha/app1
manager_log=/var/log/mha/app1/manager.log
[server1]
hostname=master
[server2]
hostname=slave1
ProxySQL 读写分离
sql
-- 配置ProxySQL
INSERT INTO mysql_servers(hostgroup_id, hostname, port) VALUES
(10, '192.168.1.100', 3306), -- 主库
(20, '192.168.1.101', 3306); -- 从库
-- 读写规则
INSERT INTO mysql_query_rules(rule_id, active, match_pattern, destination_hostgroup) VALUES
(1, 1, '^SELECT', 20), -- 读操作路由到从库
(2, 1, '.*', 10); -- 其他操作到主库