Mysql主从复制
目录
警告
本文最后更新于 2022-06-28,文中内容可能已过时。
1. 前提
- 需要多个实例
- 每台实例
server_id不同 - 需要开启二进制日志
- 主库需要提供复制相关的用户权限(
replication slave) - 从库需要将和主库相差的数据进行追加,一般先备份主库数据恢复到从库,然后在进行同步
- 从库应该从恢复之后的时间点开始自动从主库获取最新的二进制日志
2. 复制中的线程
- 主库
Dump thread: 在复制过程中,主库发送二进制日志的线程binlog文件 : 主库的二进制文件
- 从库
IO thread: 向主库请求二进制日志,并接收二进制日志的线程SQL thread: 执行请求过来的二进制的线程relaylog: 中继日志,存储请求过来的二进制日志master.info: 从库连接主库的重要参数(user,passwd,ip,port);上次获取过的主库的二进制日志位置relay-log.info: 存储从库SQL线程已经执行过的relaylog日志位置
3. 主从复制原理
从库通过IO线程,读取master.info中的信息,获取到连接及上次请求主库的binlog的位置,然后IO线程使用获取到的连接连接到主库,主库获取到从库发来的位置信息和现有二进制日志进行对比,如果有新二进制日志,会通过dump thread发送给相关信息给从库,从库通过IO线程,接受主库发来的二进制日志后,存储到TCP/IP缓存中,并返回ACK确认给主库,主库收到ACK后,就认为任务复制完成了,可以继续其他工作。从库此时将更新master.info的二进制位置信息,IO线程会将TCP/IP缓存中的日志,会存储到relay-log日志文件中。然后SQL线程读取relay-log.info上次执行到的日志位置(此位置信息不一定与binlog日志位置相同),以这个日志位置为起点继续执行relay-log日志。SQL线程执行完成所有relay之后,会更新relay-log.info信息为新的位置信息。(至此一次复制完成)
4. 主从复制实践
4.1. my.cnf
|
|
4.2. 备份
|
|
4.3. 授权
|
|
4.4. 备库导入数据
|
|
4.5. 备库指定与主库的同步信息并启动同步
|
|
4.6. 主从状态信息介绍
|
|
4.6.1. IO线程故障
- 主库连接不上: 防火墙、网络、连接信息错误(
ip、passwd、port、user)、域名解析(skip-name-resolve)
- 解决方案:
|
|
- 主库二进制日志文件丢失或损坏
- 解决方案: 重新备份恢复,在重新构建主从
4.6.1.1. 案例1
- 主从同步出现IO故障。导致原因,主库修改了端口号
- 解决方案:
- 从库
slow slave status\G,确认故障 - 记录
Master_Log_File和Read_Master_Log_Pos值 stop slavereset slave allchange master to ...start slave
- 从库
4.6.1.2. 案例2
- 主库的二进制日志被清理(1.
reset master;2.binlog文件找不到/损坏/断节/物理删除/名字被修改等),从库请求日志出现Slave_IO_Running: No(Last_IO_Error: xxxx could not find next log;the first evnet 'mysql-bin.xxxxx') - 解决方案:
- 使用备份恢复,重新初始化主从
4.6.2. SQL 线程故障
- 执行
replaylog日志新事件时,比如增加、删除库或数据时,从库已经存在或已经丢失了将要操作的数据
- 解决方案:
|
|
4.7. 延迟同步(故障)
show slave status\GSeconds_Behind_Master: 主从延时时间(s)
4.7.1. 如何避免延迟同步
-
sync_binlog=1,0(默认):事务提交不立即写入磁盘,靠操作系统判断什么时候写入;1:每次提交事务都立即刷新binlong到磁盘; -
主库大事务很多,拆分为小事务,多事务隔离
-
主库并发事务很多,使用多(sql)线程复制,针对不同库的事务来进行并发(有局限性)
-
使用多级主从,分库分表架构
-
将
binlog|relaylog放到高性能(ssd)磁盘上 -
主备硬件尽量一致
-
从库越多,压力越大(dump 线程压力越大)
-
sql 线程慢
- 默认只有一个sql线程,从库中的事务都是一个一个来执行的
- 如果主库的并发事务很多和大事务,都会造成从库延时
- 多(sql)线程复制,有局限性,针对不同库的事务来进行并发
4.8. 延迟同步(高级)
4.8.1. 逻辑损坏
- 延迟从库:从库落后于主库一段时间
- SQL线程延时,数据已经写入到relaylog,SQL线程慢点执行
1 2 3 4-- 从库执行 mysql> stop slave ; mysql> CHANGE MASTER TO MASTER_DELAY = 3600; -- 建议3-6小时 mysql> start slave ; - 案例: 主库误操作,删库
- 停止主库业务
- 立即停止从库SQL线程
stop slave sql_thread; - 手工模拟sql线程工作,并截止到误操作之前
- 读取relay-log.info,获取到上次执行到的位置,作为继续执行relay-log的起点,分析relay-log内容,获取到误操作的位置点,截取这段日志,恢复到从库
- 找到起点位置
show slave status\G,Relay_Log_file:db01-relay-bin.000002;Relay_Log_Pos:283 - 找到误删除的位置,
show relaylog events in 'db01-relay-bin.000002',找到误删行的Pos值 - 截取同步日志
mysqlbinlog --start-position=283 --stop-position=693 db01-relay-bin.000002 > relay.sql - 恢复relaylog
- 切换从库为主库
4.9. 过滤复制
从库只想复制主库的那些库
|
|
4.10. 半同步复制
- 尽可能保证主从数据一致性问题,牺牲主库一定的业务性能。实现过程,保证IO线程将日志从TCP/IP缓存,写入到relaylog才会返回ACK给主库。因此回阻塞主库的commit操作,这里会有个超时时间,10秒,如果从库还没有返回ACK,将会强制切换为一部复制过程。
|
|
4.11. 主从复制GTID(5.6以上才有)
对于二进制日志中,每提交的一个事务都有一个全局的唯一编号,多主从一样,全局唯一,在处理恢复的时候,就可以只读取缺失的GIID事务
- GTID == source_id == transaction_id
- 什么是server_id
- source_id 也叫server_uuid,默认是在数据库第一次启动时自动生成(/pathto/data/auto.cnf),手动删除后重启数据库可重新生成.
- GTID 复制要求必须是连续性事务
|
|
4.11.1. GTID 从库误写入操作处理
- 注入空事务的方法:
|
|
- 最好的解决方案是:重新构建主从环境
4.11.2. 构建一主2从的GTID的复制环境
|
|
4.12. 基本的复制主从结构
4.12.1. 一主一从
graph TD; 主节点 --> 从节点
graph TD; 主节点 --> 从节点
graph TD; 主节点 --> 从节点
graph TD; 主节点 --> 从节点
4.12.2. 一主多从
graph TD; 主节点 --> 从节点1 主节点 --> 从节点2 主节点 --> 从节点3
graph TD; 主节点 --> 从节点1 主节点 --> 从节点2 主节点 --> 从节点3
graph TD; 主节点 --> 从节点1 主节点 --> 从节点2 主节点 --> 从节点3
graph TD; 主节点 --> 从节点1 主节点 --> 从节点2 主节点 --> 从节点3
4.12.3. 多级主从
graph TD;
主节点 -->|全复制| 子主节点
subgraph ''
子主节点 -->|分段复制| 子从节点1
子主节点 -->|分段复制| 子从节点2
子主节点 -->|分段复制| 子从节点3
end
graph TD;
主节点 -->|全复制| 子主节点
subgraph ''
子主节点 -->|分段复制| 子从节点1
子主节点 -->|分段复制| 子从节点2
子主节点 -->|分段复制| 子从节点3
end
graph TD;
主节点 -->|全复制| 子主节点
subgraph ''
子主节点 -->|分段复制| 子从节点1
子主节点 -->|分段复制| 子从节点2
子主节点 -->|分段复制| 子从节点3
endgraph TD;
主节点 -->|全复制| 子主节点
subgraph ''
子主节点 -->|分段复制| 子从节点1
子主节点 -->|分段复制| 子从节点2
子主节点 -->|分段复制| 子从节点3
end
4.12.4. 双主
graph TD; 主节点 -->|全复制| 子主节点 子主节点 -->|全复制| 主节点
graph TD; 主节点 -->|全复制| 子主节点 子主节点 -->|全复制| 主节点
graph TD; 主节点 -->|全复制| 子主节点 子主节点 -->|全复制| 主节点
graph TD; 主节点 -->|全复制| 子主节点 子主节点 -->|全复制| 主节点
4.13. 高性能架构
- 读写分离中间件–
Mysql proxy(atlas,mysql router,proxySQL(percona),maxscale)、amoeba(taobao)、xx-dbproxy
- 自动判断前端sql(select、update),实现读写分离
- 分库分表—cobar、Mycat,自主研发等。
4.14. 高可用架构
单活: 主机宕机后需要手动切换 多活: 主机宕机不需要切换
- 单活:MMM架构 – mysql – mmm (google)
- 单活:MHA架构 – mysql-master-ha (日本DeNa)
- 多活:MGR(组复制) - 5.7 新特性 MySQL Group replication(5.7.17+) –> Innodb Cluster
- 多活: MariaDB Galera Cluster架构, PXC(Percona XtraDB Cluster)、MySQL Cluster 架构