今天下午,线上阿里云RDS的本地只读从库宕机了,还好,这个个服务器上的数据库实例只是提供了一部分的读需求,很快就复原了,但是上面所有的数据库实例都down掉了,启动实例并保证主从复制关系迫在眉睫。这个过程中发现有一个主从复制的问题值得研究一下,虽然最后我解决了,但是具体的原因没有找到,还请大家帮忙看看,也算是集思广益了,如果某一天找到原因了,再回来更新一下。
首先,当然先写一写服务器宕机恢复后,数据库层面需要做的工作了:
1、启动只读从库上所有的数据库实例;
2、查看所有实例上的主从复制关系是否断开;
3、查看目前是否有业务方的连接进来;
4、查看数据的一致性;
5、查看当前服务器的状态、CPU使用率、内存使用率,避免再次宕机
我们一步一步来看,服务器宕机恢复后,我首先使用mysqld_safe的方法,启动了线上大概13个只读从库实例,启动的过程还算比较顺利,13个实例都全部启动了。
第二步就是查看主从复制关系是否正常,在查看的时候,有两台主从复制关系断开了,大概的报错情况如下:
mysql--root@localhost:mysql.sock:(none) 16:50:31>>show slave status\G
*************************** 1. row ***************************
Slave_IO_State:
Master_Host: rm-2zeaXXXXXXXXbq.mysql.rds.aliyuncs.com
Master_User: dba_repl
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.001520
Read_Master_Log_Pos: 247209681
Relay_Log_File: slave-relay-bin.001306
Relay_Log_Pos: 76091724
Relay_Master_Log_File: mysql-bin.001520
Slave_IO_Running: No
Slave_SQL_Running: No
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table: mysql.%,information_schema.%,performance_schema.%,sys.%
Last_IO_Errno: 2013
Last_IO_Error: error connecting to master 'dba_repl@rm-
2zeXXXXXXXXXXbq.mysql.rds.aliyuncs.com:3306' - retry-time: 60 retries: 1
从这个报错信息来看,好像是防火墙没开一样,报超时,连接中断。但是细细一想,不可能,因为在服务器宕机之前连接是没有问题的,于是我仔细的查看了一下,使用stop slave ,start slave的方法进行复制关系重启,结果发现报错如下:
mysql--root@localhost:mysql.sock:(none) 16:42:28>>start slave;
ERROR 1201 (HY000): Could not initialize master info structure;
more error messages can be found in the MySQL error log
提示是无法初始化master info structure,然后让查看error log,我又乖乖的去查看error log中的内容,error log中的内容如下:
2019-10-22T16:39:39.277152+08:00 6 [ERROR] Error looking for file after /data/mysql_4801/log/slave-relay-bin.001307.
2019-10-22T16:42:34.038589+08:00 7 [Note] Slave: MTS group recovery relay log info based on Worker-Id 0, group_relay_log_name /data/mysql_4801/log/slave-relay-bin.001306, group_relay_log_pos 76100617 group_master_log_name mysql-bin.001520, group_master_log_pos 248461235
2019-10-22T16:42:34.038755+08:00 7 [ERROR] Error looking for file after /data/mysql_4801/log/slave-relay-bin.001307.
从提示信息来看,好像是slave-relay-bin.001307之后的relay log不存在,于是我立马去指定的目录下查看,发现
/data/mysql_4801/log/slave-relay-bin.001307
这个文件是存在的,后面确实没有其他的relay log了。当时忘了查询一个地方,就是mysql系统数据库中的slave_relay_log_info表,这个表里面的信息本身应该存了relay_log_name的位置,这是一个值得怀疑的点,由于没有查看,这个问题,所以修复完之后,这个问题没有办法复现了。
当时看到上面这些信息,我想着可能是没发通过常规的办法来解决这个问题了,所以就索性重新搭建主从复制关系,这个数据库上的数据大概有50G左右,万一复制关系断开了,其实修复起来还挺麻烦的,但是当时也没有更好的办法了,就直接进行了修复,修复的办法如下:
stop slave;
reset slave;
change master to master_host='rm-2zeXXXXXXXXXbq.mysql.rds.aliyuncs.com',
master_user='dba_repl',
master_password='XXXXXXXXX',
master_port=3306,
master_auto_position=1;
重新配置复制关系,结果直接没有报错,这个问题也就修复完成了。
虽然主从复制修复完成了,但是具体的原因还有待考证,怀疑是表slave_relay_log_info中的数值和真实的relay log文件序号不一致导致的。有好的想法欢迎大家讨论。
处理完成复制关系之后,查看了一下当前的业务方连接,看到有连接打进来,这才放心了。
接下来是查看数据的一致性,我查看一致性的时候,是挑选了经常使用的几个大表,查看了一下表的记录条数,发现两边的记录条数一致,主从复制也没有报错,这就算简单的检查完了,但是这样的方法并不可取,最好的方式可能是借助PT工具中的pt-table-checksum的方法,或者其他工具来检测,这样的结果更加具有说服力,由于时间着急,就先挑选了几个大表做了。
最后一步是查看当前服务器的状态,避免再次宕机,看了一眼内存和CPU使用率,发现都比较低,看着没有啥大问题。这里提醒一句,如果内存的使用率比较高,则需要适当降低buffer pool的值,如果CPU的使用率比较高,则需要看看,是否buffer pool的设置过低,在前几天的案例中就有一则,是由于buffer pool设置为0,导致多核CPU中的一个核心负载飙升到100%。
关于这次故障,跟系统那边聊过,他们也在评估中,目前排除机房断电的可能,关于硬件方面的问题排查,目前还在进行中,后续看看结果吧。