主从异常情况
1、IO线程故障
网络故障: IP地址错误、端口错误、用户或密码错误、防火墙、链接数到达上限
排查故障方法:
使用同步用户在命令行之间连接主库
mysql -urepl -h -p
1007: 对象已存在
1032: 无法执行DML
1062: 主键冲突,或约束冲突
解决从服务器故障
stop slave
reset slave
change master to
start slave
2、SQL线程故障
SQL线程功能
1)读写relay-log.info
2) relay-log 损坏,断节、找不到
3)接受的SQL无法执行
方法一:
stop slave;
set global sql_slave_skip_counter = 1;
start slave
方法二:
slave-skip-errors=1032,1062,1007
1007 对象已存在
1032 无法执行DML
1062: 主键冲突
但是,以上操作有时是有风险的,最安全的做法就是重新够建主从。
最好的解决方案:
一劳永逸的解决问题的方式是:
(1)、从库只需要用户读操作。
在配置文件中添加read-only=1 (对root无效)
(2) 加中间件(自动实现读写分离)
读写分离
主从延时的监控及原因
(1)、外在因素(网络、硬件配置、数据库版本、参数、)
(2) 主库
1、二进制日志写入不及时
设置:
sync_binlog = 1
2、二进制传输方式
dump线程在传统的主从复制中,binlog_dump线程,以事件为单元,串行传送(5.5,5.6)。有严格的逻辑结构。
在下面情况下容易产生延时:
1、主库并发事务量大时,主库可以并行,传送时是串行
2、主库发生了大事务,由于是串行传送,会产生阻塞后续的事务。
解决方案:
5.6 开始,加入了GTID,实现了GC(group commit)机制,可以并行传输日志给从库IO
5.7 开始,不开启GTID,会自动维护匿名的GTID,也能实现GC(group commit),我们建议还是开启GTID。
大事务拆成多个小事务,可以有效的减少主从延时。
(3) 从库
影响主从延时的情况:
1)、硬件(网速、服务器配置)
2)SQL 线程导致的主从延时
在传统的主从复制情况下。主库并发而从库默认情况下只有一个SQL,只能串行回放事务SQL
1、主库如果并发了事务量比较大,从库只能串行回访
2、主库发生了大事务,会阻塞后续的所有的事务的运行。
解决方案:
1)、5.6 版本开启GTID之后,加入了SQL多线程的特性,但是只能针对不同库(database)下的食物进行并发回放
2)、5.7 版本开启GTID之后,在SQL方面,提供了基于逻辑时钟(logical_clock),
binlog 加入了seq_no机制,真正实现了基于事务级别的并发回放,这种技术我们把它称之为MTS(enhanced multi-threaded slave)。
3)、大事务拆分成多个小事务,可以解决从库SQL阻塞的问题。
mysql 主从延时复制
1、延时从库 (从库延时主库3--6h,具体看公司运维人员对于故障的反应时间)
1、1 介绍
人为的设置从库延时指定时间的从库。
1.2 为什么要有延时从库
延时配置方法:
在从库上
> stop slave;
> change master to master_delay = 300;
>show slave status\G
>
逻辑故障的恢复思路
1、及时发现主库发生了逻辑损坏
2、立即停止延时从库的sql 线程
3、挂维护页
4、截取relay 进行恢复(人为模拟SQL 线程工作,直到drop 之前)
起点:stop sql 线程时的relaylog位置点
终点: drop 之前的位置点
5、截取的日志恢复到从库
6、从库替代主库工作
故障模拟及恢复
1、停止 stop slave sql_thread;
2、show slave stauts\G (查找截取binlog的起点)
3、show relaylog events in 'relay-bin.000002'; (查找截取binlog的终点)
4、截取日志
mysqlbinlog --start-position= --stop-position -d /data/relaylog/relaybin.000002 > 20160602.sql
5、导入从库
6、接触从库身份
stop slave
reset slave all
7、还原环境
半同步复制(了解)
解决主从数据一致性问题
5.5 版本出现,5.6 增强 5.7 比较完善,5.7.17 以后MGR复制
主从上产生的binlog 发送给从库,从库必须把binlog 写入磁盘后,返回给主库ack确定信息给主库的ack_res
复制过滤策略:
复制过来策略最佳实战是在从库上进行设置:
replicate_do_db=test (每行写一个库,如果有多个库就写多行)
replicate_ignore_db=
replicate_do_table=
replicate_ignore_table=
配置参数使用小写:
REPLICATE_DO_DB = (db_list) |
REPLICATE_IGNORE_DB = (db_list) |
REPLICATE_DO_TABLE = (tbl_list) |
REPLICATE_IGNORE_TABLE = (tbl_list) |
REPLICATE_WILD_DO_TABLE = (wild_tbl_list) |
REPLICATE_WILD_IGNORE_TABLE = (wild_tbl_list) |
REPLICATE_REWRITE_DB = (db_pair_list)
CHANGE REPLICATION FILTER REPLICATE_WILD_DO_TABLE = ('db1.old%'); CHANGE REPLICATION FILTER REPLICATE_WILD_IGNORE_TABLE = ('db1.new%', 'db2.new%');
GTID 复制
介绍GTID (Global Transaction ID) 是对于一个已提交事务的唯一编号,并且是一个全局(主从复制)唯一的编号。
配置参数:
主库:
gtid-mode=on;
enforce-gtid-consistency=true;
从库配置:
gtid-mode=on;
enforce-gtid-consistency=true;
log-slave-updates=1;
change master to
master_host='192.168.1.130',
master_port=3306,
master_user='rep',
master_password='123.com',
master_auto_position=1; (开启gtid模式复制,自动寻找position)
GTID 复制模式环境下,如果从库出现了写操作,在进行主从同步时,因从无法执行sql而报错。传统的主从复制模式,可以跳过某个position 号,但是GTID模式下不能执行跳过操作(要保持GTID的连续性)。
注入空的事务:(操作可能会给环境带来隐患,不建议生产上使用)
stop slave;
set gtid_next='211b7e4a-95b3-11e9-86fb-000c29cdc53a:5';
set gtid_next='automatic';
注意: 这里的'211b7e4a-95b3-11e9-86fb-000c29cdc53a:5' 也就是slave sql thread 报错的GTID,
或者需要跳过的gtid。最好的解决方案: 重新构建主从环境。
> restart master;(在从库上删除binlog的信息)
总结:
1)、在主从复制环境中,主库发生过的事务,在全局都是有唯一GTID记录的,更方便failover;
2)、额外功能参数(3)
gtid-mode=on
inforce-gtid-consistency=true
log-slave-updates=1
3)、change master to 的时候不再需要binlog 文件名和position 号,需要master_auto_position=1;
4)、在复制过程中,从库不再依赖master info 文件,而是直接读取最后一个relaylog的GTID号;
5)mysqldump 备份时,默认会将备份中包含的事务操作,以下方式:
告诉从库,我的备份中已经有以上事务,你就不用运行了,直接从下一个GTID开始请求binlog就行。
总结:
1、复制环境
2、复制原理
3、复制故障
4、主从监控(show slave status\G 一定记得各个选项)
主库相关信息、库表过滤、线程、延时、GTID、binlog、relay_log等
5、主从复制异常
故障(IO、SQL)
延时(dump、SQL、大事务(一个事务插入几万条数据,大事务进行拆分)
event(数据事件相当于系统的计划任务,需要开发确定)
6、如果参数和硬件都进行升级,但是还是无法解决。可以考虑版本升级