Mysql解决主从慢同步问题


一.简介

一般主从复制,有三个线程参与,都是单线程:Binlog Dump(主) —–>IO Thread (从) —–> SQL Thread(从)。复制出现延迟一般出在两个地方

1)SQL线程忙不过来(可能需要应用数据量较大,可能和从库本身的一些操作有锁和资源的冲突;主库可以并发写,SQL线程不可以;一个大的sql语句导致执行很慢;)

2)网络抖动导致IO线程复制延迟(次要原因)。

SQL thread在执行IO thread dump下来的relay log的时间差。大家都知道relay log中event记录的时间戳是主库上的时间戳,而SQL thread的时间戳是从库上的,也就是说,如果主库和从库的时间是一致的,那么这个SBM代表的确实是从库延后主库的一个时间差。但是如果主库和从库的时间不是一致的,那么这个SBM的意义就基本不存在了。将主库时间调快1小时,那从库默认慢一小时。

为何有延迟

1.网络延迟
若主从之间网络延迟到,会造成sql线程无法实时将主的binlog日志复制过来。

2.机器性能差
若主用的固态硬盘,从用的机械硬盘,那读取速度自然不一样,会造成主写入很快,从在慢慢读取,这样就不适合读写分离了。

3.高负载
若从机器还安装了别的服务,用top可以看出是否有其它进程在占用资源,导致从性能下降。

4.磁盘负载
iotop可以看到当前磁盘的负载,若正在复制某些东西,会导致将主的binlog复制过来了,但写入到从mysql中会很慢,数据不一致。

5.是否经常会有大事务?
这个可能DBA们会遇到比较多,比如在RBR模式下,执行带有大量的Delete操作,或者在MBR模式下删除时添加了不确定语句(类似limit)或一个表的Alter操作等,都会导致延迟情况的发生。

这种可通过查看Processlist相关信息,以及使用mysqlbinlog查看binlog中的SQL就能快速进行确认。这个设想也被排除。

6.死锁
锁冲突问题也可能导致从机的SQL线程执行慢,比如从机上有一些select …. for update的SQL,或者使用了MyISAM引擎等。此类问题,可以通过抓去Processlist以及查看information_schema下面和锁以及事务相关的表来查看。

二.观察

在主上用SHOW MASTER STATUS;查看最新的binlog日志,在从上用show slave status\G;查看Master_Log_File,如果是一样的,说明sql线程将主的binlog日志都复制过来了,这是没延迟的。如果Seconds_Behind_Master是0则IO线程将同步过来的binlog日志都加载了,那延迟为0。

seconds_behind_master如果一直为0,突然就很高,那是因为主库在执行一个大的事件,当事件执行完成后从才开始复制,sbm会突然很高。

三.解决办法

参数

关闭binlog日志可以减轻从库的负载

配置文件添加如下,将不缓冲直接写入,从而加速性能

sync_binlog=0
innodb_flushlog
innodb_flush_log_at_trx_commi=0

多线程

5.6开始MySQL正式支持多线程复制,如下命令查看有多少个线程在同步。
show variables like '%slave_parallel%'
file

slave_parallel_type
为DATABASE时,基于数据库的并发,也就是每一个数据库都有一个线程去同步,如果只有一个数据库,那其它线程不工作。不同库下的表并发提交时的数据不会相互影响,即slave节点可以用对relay log中不同的库各分配一个类似SQL功能的线程,来重放relay log中主库已经提交的事务,保持数据与主库一致。

为LOGICAL_CLOCK时,则可以一个数据库一个多线程同步。一个组提交的事务都是可以并行回放(配合binary log group commit)。

slave_parallel_workers
代表启动多少个线程用于同步,0就是默认1个。

静态设置:

slave_parallel_type='LOGICAL_CLOCK'
slave_parallel_workers=8

动态设置:
SET GLOBAL slave_parallel_type='LOGICAL_CLOCK';
SET GLOBAL slave_parallel_workers=8;

组提交

在5.7中,多线程复制的功能有很很大的改善,支持LOGICAL_CLOCK的方式,在这种方式下,并发执行的多个事务只要能在同一时刻commit,就说明线程之间没有锁冲突,那么Master就可以将这一组的事务标记并在slave机器上安全的进行并发执行。

因此,可以尽可能地使所有线程能在同一时刻提交,这样就能很大程度上提升从机的执行的并行度,从而减少从机的延迟。

有了这个猜想后,很自然想到了人为控制尽可能多地使所有线程在同一时刻提交,其实官方已经给我们提供了类似的参数,参数如下:
binlog_group_commit_sync_delay

备注:这个参数会对延迟SQL的响应,对延迟非常敏感的环境需要特别注意,单位是微秒。

由于是监控的DB,主要是load数据,然后进行展示,1秒左右的导入延迟对业务没什么影响,因此将两个参数调整为:
SET GLOBAL binlog_group_commit_sync_delay = 1000000;
SET GLOBAL binlog_group_commit_sync_no_delay_count = 20;

备注:这两个参数请根据业务特性进行调整,以免造成线上故障。

为了防止导入SQL堆积,设置SET GLOBAL binlog_group_commit_sync_no_delay_count为20,在达到20个事务时不管是否达到了1秒都进行提交,来减少对业务的影响。


 上一篇
CPU占用过高排查 CPU占用过高排查
CPU占用过高排查一.简介最近一段时间 某台服务器上的一个应用总是隔一段时间就自己挂掉 用top看了看 从重新部署应用开始没有多长时间CPU占用上升得很快 排查步骤 1.使用top 定位到占用CPU高的进程PIDtop 2.通过ps aux
2020-12-08
下一篇 
keepalived配置nfs高可用 keepalived配置nfs高可用
一.简介NFS是单点的,如果一个节点出现问题,那使用它挂载服务的都将出现问题。所以需要高可用,挂掉一台不影响。采用keepalived+rsync+inotify-tools 环境:ubuntu16.4nfs1 192.168.1.1 /m
2020-11-24
  目录