mysql主从同步延时问题
最近领导将MASTER的主库清空了最近几个月的数据,进行了大并发的操作.这导致了mysql的从库延时非常高的问题.zabbix报警如下:
延时一直飙升到23个小时.
解决过程
1.查看master库的慢查询条数:
1 | "root@localhost:mysql.sock [(none)]>show processlist; |
只截取了部分数据..慢查询条数并不多,而且binlog也已经全部send到slave了..主库这边一切正常.
2.查看从库的状态
1 | mysql> show slave status\G |
除了Seconds_Behind_Master参数的值非常高以外也没有太大问题
3.查看从库的慢查询情况
1 | mysql> show processlist; |
从库的select语句性能不是很好,
mysql数据文件目录存在大量的binlog日志.显然从库的数据写入有严重的滞后问题
1 | -rw-r----- 1 mysql mysql 257 Aug 19 11:04 server-6-relay-bin.004893 |
4.查看innoDB的相关配置:
1 | mysql> show global status like '%innodb_log%'; |
发现缓冲池有大量的空闲页等待被执行
5.初步怀疑是从库的sql语句读写速度比较慢,查看服务器磁盘IO情况:
1 | [root@server-6 ~]# iostat -d -x 2 |
磁盘IO负载已经达到了100%.
6.查看占用磁盘IO的主要进程:
1 | Total DISK READ : 25.90 M/s | Total DISK WRITE : 64.71 M/s |
7.查看mysql有关磁盘IO的主要配置参数:
1 | mysql> show variables like '%sync_bin%'; |
sync_binlog=1表示每次事务提交后MySQL将进行一次fsync之类的磁盘同步指令来将binlog_cache中的数据强制写入磁盘,频繁的写盘导致磁盘IO居高不下
innodb_flush_log_at_trx_commit=1时,log buffer 会被写入到日志文件并刷写到磁盘。这也是默认值。这是最安全的配置,但由于每次事务都需要进行磁盘I/O,所以也最慢
有关这两个参数的更多解释,请百度
8.修改参数配置:
1 | 编辑my.cnf配置文件: |
9.重启mysql服务,重启slave进程
1 | [root@server-6 ~]# service mysqld restart |
10.查看参数是否已经生效:
1 | mysql> show variables like '%sync_bin%'; |
11.但是查看磁盘IO还是居高不下
1 | [root@server-6 mysql]# iostat -d -x 2 |
此外,延时仍然在不断的上升,
1 | [root@server-6 mysql]# /usr/bin/pt-heartbeat --host=127.0.0.1 --user=heartbeat --password=xxxxxx -D dwd_analystic --master-server-id=63306 --check |
12.但是查看slave状态.仍然在不停的读取bin日志和log信息.但是读取速度非常慢
1 | mysql> show slave status\G |
13.查看mysql数据文件的binlog日志文件个数
1 | [root@server-6 mysql]# ls server-6-relay-bin.* | wc -l |
14.优化完sync磁盘写入机制后发现延时还是非常高,而且在不断上升,最高的时候达到了34个小时.slave读取binlog日志还是非常慢.
查看一下mysql数据库的关键性能配置参数,发现没有经过任何优化.这极大的限制了mysql的性能.
编辑my.cnf配置文件
1 | sync_binlog=0 |
重启mysql服务,启动slave进程
1 | service mysqld restart |
下面是修改过后的部分配置参数:
1 | #下面的参数是最关键的性能指标.默认值是148M.一般建议是服务器内存的70%-75% |
有关mysql的参数的配置和优化.请参考mysql的官方文档:Server Option, System Variable, and Status Variable Reference
此时,虽然延时还在上涨.但是slave读取binlog日志的速度明显快了很多,相比之前同步速度几乎是指数级的翻倍上涨.性能大幅提升.而且从库上的binlog日志文件在不断减少.1
2
3Binlog文件从300多个在逐渐减少:
[root@server-6 ~]# ls /data/mysql/server-6-relay-bin.* | wc -l
243
观察了1天之后,日志文件进一步减少,而且延时在不断的最近
1 | [root@server-6 ~]# /usr/bin/pt-heartbeat --host=127.0.0.1 --user=heartbeat --password=xxxx -D dwd_analystic --master-server-id=63306 --check |
再观察一个晚上后,延时故障消失,主从恢复正常.binlog文件几乎读完了.
1 | [root@server-6 ~]# ls /data/mysql/server-6-relay-bin.* | wc -l |
奇怪的是磁盘的IO负载还是非常高:
1 | [root@server-6 ~]# iostat -d -x 2 |
但是磁盘的读写速度并不高,而且是es和kafka进程在消耗磁盘IO.并不是mysql进程了
1 | Total DISK READ : 131.73 K/s | Total DISK WRITE : 11.93 M/s |
总结:
主从延时比较关键的地方:
1.确保slave库的服务器配置和master相当,或者比master更高.
2.确保网络延时较低.
3.sync_binlog和innodb_flush_log_at_trx_commit,这两个参数决定了磁盘写入机制.如果sync_binlog设置为1.则每次操作都要回写到磁盘日志,极大的增加磁盘IO负载和同步负担.
4.innodb_buffer_pool_size参数调整会将mysql的整体性能提高到好几个倍数.
5.如果是mysql5.7以上版本,尽量使用GTID主从复制机制代替传统的Binlog机制.因为Binlog的sql线程还是单线程工作模式.
6.完善的监控机制.如果第一时间发现延时较高,就要尽早介入处理.