Seconds_Behind_Master越来越大,主从同步延迟

问题 现象

发现从库mysql_slave的参数Seconds_Behind_Master越来越大。已排除主从服务器时间不一致;那么主要就判断两点:是io thread慢还是 sql thread慢?先观察show slave status\G 。

判断3个参数(参数后面的值是默认空闲时候的正常值):

Slave_IO_State: Waiting for master to send event

Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it

Seconds_Behind_Master: 0

1.sql thread慢的表现:

Seconds_Behind_Master越来越大

Slave_SQL_Running_State: Reading event from the relay log

2.io thread慢的表现:

Seconds_Behind_Master为0

Slave_SQL_Running_State: 显示正常值

Slave_IO_State:显示忙碌状态

本文观察到的值:

Slave_IO_State: Queueing master event to the relay log

Seconds_Behind_Master: 30880

Slave_SQL_Running_State: Reading event from the relay log

上述三个参数,推断是sql thread慢

同步延迟信息详见如下:

mysql> show master status \G
*************************** 1. row ***************************
             File: mysql-bin.000057
         Position: 214873221
     Binlog_Do_DB:
 Binlog_Ignore_DB:
Executed_Gtid_Set: 838ad3df-a43d-11e8-8b02-6c92bf7daa8d:1,
efd10b43-a43c-11e8-85d8-6c92bf7d9fd1:1-134202381
1 row in set (0.00 sec)

从库延迟:

mysql> show slave status \G
*************************** 1. row ***************************
               Slave_IO_State: Queueing master event to the relay log
                  Master_Host: 192.168.10.111
                  Master_User: repl
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000057
          Read_Master_Log_Pos: 214813221
               Relay_Log_File: relay-bin.00045
                Relay_Log_Pos: 28055325
        Relay_Master_Log_File: mysql-bin.000057
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
          Exec_Master_Log_Pos: 94286319
              Relay_Log_Space: 956058939
             Seconds_Behind_Master: 30880
             Master_Server_Id: 113306
                  Master_UUID: efd10b43-a43c-11e8-85d8-6c92bf7d9fd1
             Master_Info_File: mysql.slave_master_info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: Reading event from the relay log
           Master_Retry_Count: 86400
           Retrieved_Gtid_Set: efd10b43-a43c-11e8-85d8-6c92bf7d9fd1:153917-55474510
            Executed_Gtid_Set: 838ad3df-a43d-11e8-8b02-6c92bf7daa8d:1,
efd10b43-a43c-11e8-85d8-6c92bf7d9fd1:1-54003557
                Auto_Position: 1
1 row in set (0.00 sec)

注意: Seconds_Behind_Master: 30880

分析步骤:

开始怀疑是参数配置的差异,比对/etc/my.cnf后发现,发现配置并无差异。

从库使用操作系统命令dstat观察,发现繁忙时候,slave的IO写速度上不去

[root@mysql ~]# dstat
You did not select any stats, using -cdngy by default.
----total-cpu-usage---- -dsk/total- -net/total- ---paging-- ---system--
usr sys idl wai hiq siq| read  writ| recv  send|  in   out | int   csw
  0   0 100   0   0   0|  19k  686k|   0     0 |   0     0 | 231   648
  0   0  99   1   0   0|   0  1388k| 798B  396B|   0     0 | 358  1596
  0   0  99   1   0   0|   0  1676k| 244B  170B|   0     0 | 397  1949
  0   0  99   1   0   0|   0  1796k|1490B  236B|   0     0 | 451  2107
  0   0  99   1   0   0|   0  1764k| 244B  170B|   0     0 | 414  2104
  0   0 100   0   0   0|   0  1536k|1068B  170B|   0     0 | 390  1649
  0   0  99   1   0   0|   0  1516k| 244B  170B|   0     0 | 373  1575
  0   0  99   1   0   0|   0  1552k|  34k  500B|   0     0 | 410  1602
  0   0 100   0   0   0|   0  1556k| 126B  236B|   0     0 | 363  1527
  0   0  99   1   0   0|   0  1384k|  60B  170B|   0     0 | 349  1369
  0   0  99   1   0   0|   0  1440k|  13k  434B|   0     0 | 400  1513
  0   0 100   0   0   0|   0  1800k| 612B  170B|   0     0 | 418  1905
  0   0  99   0   0   0|   0  1484k| 246B  236B|   0     0 | 622  1568
  0   0  99   1   0   0|   0  1272k|  60B  170B|   0     0 | 347  1294
  0   0  99   1   0   0|   0  1624k| 126B  236B|   0     0 | 400  1815
  0   0  99   1   0   0|   0  1580k|  60B  170B|   0     0 | 358  1712
  0   0 100   0   0   0|   0  1536k|  22k  302B|   0     0 | 395  1583
  0   0 100   0   0   0|   0  1440k| 514B  368B|   0     0 | 383  1765
  0   0  99   1   0   0|   0  1596k|  28k  500B|   0     0 | 446  2151
看到从库的写只能达到每秒1.5M左右,IO性能不是很好,也印证了初步的推测。

那么问题来了,

要如何优化IO性能比较差的slave呢?

简单,本文做了如下两个参数的修改:

mysql> set global innodb_flush_log_at_trx_commit=2;
Query OK, 0 rows affected (0.00 sec)
mysql> set global sync_binlog=20 ;
Query OK, 0 rows affected (0.00 sec)

innodb_flush_log_at_trx_commit和sync_binlog这两个参数又是个啥?

innodb_flush_log_at_trx_commit

  1. innodb_flush_log_at_trx_commit设置为0,log buffer将每秒一次地写入log file中,并且log file的flush(刷到磁盘)操作同时进行.该模式下,在事务提交的时候,不会主动触发写入磁盘的操作。

  2. innodb_flush_log_at_trx_commit设置为1,每次事务提交时MySQL都会把log buffer的数据写入log file,并且flush(刷到磁盘)中去.

  3. innodb_flush_log_at_trx_commit设置为2,每次事务提交时MySQL都会把log buffer的数据写入log file.但是flush(刷到磁盘)操作并不会同时进行。该模式下,MySQL会每秒执行一次 flush(刷到磁盘)操作。

注意:

由于进程调度策略问题,这个"每秒执行一次 flush(刷到磁盘)操作"并不是标准意义上的保证100%的"每秒"。

sync_binlog

sync_binlog 的默认值是0,像操作系统刷其他文件的机制一样,MySQL不会同步到磁盘中去而是依赖操作系统来刷新binary log。

当sync_binlog =N (N>0) ,MySQL 在每写 N次二进制日志binary log时,会使用fdatasync()函数将它的写二进制日志binary log同步到磁盘中去。

注意:

如果启用了autocommit,那么每一个语句statement就会有一次写操作;否则每个事务对应一个写操作。mysql服务默认是autocommit打开的。

如上sync_binlog,autocommit,innodb_flush_log_at_trx_commit三个参数,详见从库mysql_slave设置如下:

mysql> show variables like '%sync_binlog%';+---------------+-------+| Variable_name | Value |+---------------+-------+| sync_binlog   | 0     |+---------------+-------+1 row in set (0.01 sec)
mysql>mysql> show variables like '%innodb_flush_log_at_trx_commit%';+--------------------------------+-------+| Variable_name                  | Value |+--------------------------------+-------+| innodb_flush_log_at_trx_commit | 1     |+--------------------------------+-------+1 row in set (0.00 sec)
mysql> show variables like '%autocommit%';+---------------+-------+| Variable_name | Value |+---------------+-------+| autocommit    | ON    |+---------------+-------+1 row in set (0.00 sec)

根据上述分析过程,修改如下值:

mysql> set global sync_binlog=20;
`mysql> set global innodb_flush_log_at_trx_commit=2;`

接下来,我们观察和验证从库同步情况

  1. 使用dstat命令观察磁盘IO,下图可以看到从库的写有原来的每秒1.5M左右提升为4M以上,

    [root@mysql ~]# dstat
    You did not select any stats, using -cdngy by default.
    ----total-cpu-usage---- -dsk/total- -net/total- ---paging-- ---system--
    usr sys idl wai hiq siq| read writ| recv send| in out | int csw
    0 0 100 0 0 0| 19k 686k| 0 0 | 0 0 | 231 648
    0 0 99 1 0 0| 0 4756k| 882B 462B| 0 0 | 601 6690
    0 0 99 1 0 0| 0 4208k| 430B 236B| 0 0 | 642 8771
    0 0 99 1 0 0| 0 4452k| 428B 170B| 0 0 | 607 7803
    0 0 99 1 0 0| 0 7964k| 26k 500B| 0 0 | 589 6835
    0 0 99 1 0 0| 0 3832k|1166B 170B| 0 0 | 368 2467
    0 0 99 1 0 0| 0 4584k|2042B 236B| 0 0 | 523 4632
    0 0 99 1 0 0| 0 4972k|1296B 170B| 0 0 | 661 9298
    0 0 99 1 0 0| 0 4792k|1046B 236B| 0 0 | 606 9634
    0 0 99 1 0 0| 0 5244k|3032B 212B| 0 0 | 745 9965
    0 0 99 0 0 0| 0 4648k| 796B 170B| 0 0 |1166 19k
    0 0 99 1 0 0| 0 4608k| 21k 434B| 0 0 | 827 14k
    0 0 99 0 0 0| 0 4552k|1858B 236B| 0 0 | 971 17k
    0 0 99 0 0 0| 0 4580k| 980B 170B| 0 0 | 936 17k
    0 0 99 1 0 0| 0 8332k| 21k 434B| 0 0 | 940 13k
    0 0 99 0 0 0| 0 4136k|1112B 236B| 0 0 |1112 20k
    0 0 99 0 0 0| 0 4940k| 796B 170B| 0 0 |1045 19k
    0 0 99 0 0 0| 0 4496k| 22k 500B| 0 0 | 951 15k
    0 0 99 0 0 0| 0 4652k| 862B 170B| 0 0 |1022 18k
    0 0 99 0 0 0| 0 5472k|1546B 236B| 0 0 | 950 15k
    0 0 99 0 0 0| 0 2616k| 20k 434B| 0 0 | 901 15k
    0 0 99 1 0 0| 0 9564k|2410B 170B| 0 0 | 958 14

  2. 从库使用 show slave status \G,观察到Seconds_Behind_Master: 21202在持续缩小和主库的差距。Seconds_Behind_Master:由原来的30880降为21202,且在持续减少中。

    mysql> show slave status \G
    *************************** 1. row ***************************
    Slave_IO_State: Queueing master event to the relay log
    Master_Host: 192.168.10.111
    Master_User: repl
    Master_Port: 3306
    Connect_Retry: 60
    Master_Log_File: mysql-bin.000057
    Read_Master_Log_Pos: 214833221
    Relay_Log_File: relay-bin.00045
    Relay_Log_Pos: 28064325
    Relay_Master_Log_File: mysql-bin.000057
    Slave_IO_Running: Yes
    Slave_SQL_Running: Yes
    Exec_Master_Log_Pos: 544925182
    Relay_Log_Space: 973436169
    Master_SSL_Allowed: No
    Seconds_Behind_Master: 21202
    Replicate_Ignore_Server_Ids:
    Master_Server_Id: 113306
    Master_UUID: efd10b43-a43c-11e8-85d8-6c92bf7d9fd1
    Master_Info_File: mysql.slave_master_info
    SQL_Delay: 0
    SQL_Remaining_Delay: NULL
    Slave_SQL_Running_State: Waiting for dependent transaction to commit
    Master_Retry_Count: 86400
    Retrieved_Gtid_Set: efd10b43-a43c-11e8-85d8-6c92bf7d9fd1:153917-55504200
    Executed_Gtid_Set: 838ad3df-a43d-11e8-8b02-6c92bf7daa8d:1,
    efd10b43-a43c-11e8-85d8-6c92bf7d9fd1:1-54771730
    Auto_Position: 1
    1 row in set (4.98 sec)

至此,Seconds_Behind_Master越来越打的问题得到解决。

相关推荐
大白要努力!20 分钟前
android 使用SQLiteOpenHelper 如何优化数据库的性能
android·数据库·oracle
Estar.Lee26 分钟前
时间操作[取当前北京时间]免费API接口教程
android·网络·后端·网络协议·tcp/ip
Winston Wood38 分钟前
Perfetto学习大全
android·性能优化·perfetto
Dnelic-4 小时前
【单元测试】【Android】JUnit 4 和 JUnit 5 的差异记录
android·junit·单元测试·android studio·自学笔记
Eastsea.Chen6 小时前
MTK Android12 user版本MtkLogger
android·framework
长亭外的少年13 小时前
Kotlin 编译失败问题及解决方案:从守护进程到 Gradle 配置
android·开发语言·kotlin
建群新人小猿16 小时前
会员等级经验问题
android·开发语言·前端·javascript·php
1024小神17 小时前
tauri2.0版本开发苹果ios和安卓android应用,环境搭建和最后编译为apk
android·ios·tauri
兰琛17 小时前
20241121 android中树结构列表(使用recyclerView实现)
android·gitee
Y多了个想法18 小时前
RK3568 android11 适配敦泰触摸屏 FocalTech-ft5526
android·rk3568·触摸屏·tp·敦泰·focaltech·ft5526