mysql 故障检测与处理
文章目录
- 故障检测
- 外部检测:心跳轮询
- 内部统计,时间检测
- 外部检测和内部统计对比
- 故障处理
- 主从切换:同步位点方案
- 从库C如何跳过重复日志
- 主从切换:GTID方案
- 同步位点方案和GTID方案对比
故障检测
外部检测:心跳轮询
检查方式 | 检测目标 | 适用场景 |
---|---|---|
select 1 | 服务进程存活 | 基础存活 |
建一个health_check表 select * from mysql.health_check | 并发进程没有达到上限(innodb_thread_concurrency) | 常规业务 |
update mysql.health_check set t_modified=now() | 验证能否正常进行写事务提交 | 关键业务 |
update:如果是双主架构,需要改成insert into mysql.health_check(id, t_modified) values (@@server_id, now()) on duplicate key update t_modified=now();
每个库分别执行自己的语句,避免更新同一条语句引发冲突。
内部统计,时间检测
开启performance_schema表中的相关统计项、redo log时间检测等
外部检测和内部统计对比
外部检测需要定时轮询,发现问题不及时;内部统计更准确,但开启会占用一定的性能。要注意搭配使用。
故障处理
自动故障转移:vip(virtual ip)漂移、DNS更新,可以用MHA自动管理
一主多从,主库A挂了,找出新的主库B后就要同步数据(主从切换)。可以通过位点、GTID等方式进行同步。
主从切换:同步位点方案
一主多从,主库A挂了,找出新的主库B后就要同步位点。因为原来节点B也是A的从库,本地记录的A的位点。但相同的日志,A的位点和B的位点是不同的。所以从库C要切换主库A=>B时,就需要先找到同步位点。
流程:
- 等待新主库B把中转日志(relay log)同步完;
- 在B上执行show master status得到当前B上最新的File和Position;
- 取原主库A故障的时刻T;
- 用mysqlbinlog解析B上的File,得到T时刻的位点;
从库C如何跳过重复日志
C收到重复的任务执行一般会返回错误,常见错误:
- 1062 插入时唯一键冲突
- 1032 删除时找不到
所以我们可以在一段时间内将slave_skip_errors设置为“1032,1062”,等待同步完成再恢复“”。// 不能一直不恢复,会跳过真正的错误
或者跳过所有错误跳过几次:
set global sql_slave_skip_counter=1;
start slave;
主从切换:GTID方案
GTID=source_id:gno // 全局唯一,gno值可以指定,也可以通过gtid_next=automatic设置使用默认值
-
从库C把自己的gtid list发给B,B发现不差,就不用给它发了
-
如果B在算差值时,发现有从库需要的日志但在B上没有,认为有问题,直接返回错误:Slave has more GTIDs than the master
比如:延迟从库被选为新主库,就会在主库删除数据宕机后,其他库的数据比延迟从库多,就会报错停下来需要人工处理,判断一下是误删还是正常删除再恢复主从关系。延迟从库正常不会被选为主库。
同步位点方案和GTID方案对比
同步位点方案和GTID方案在同步日志上思想不同:
- 同步位点:是从库决定从哪个位点开始要日志,主库不做完整性判断
- GTID:是主库计算差值,并判断从库需要日志是否完整,再向从库发送日志