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越来越打的问题得到解决。

相关推荐
朱涛的自习室4 小时前
我给 Gemini 4 和 DeepSeek 搞了套「末位淘汰」,AI 干活会更猛吗?(Day 3)
android·前端·后端
应用市场10 小时前
离线小游戏做“每日挑战”:日期当随机种子,整局存成 JSON,再加一个“我不是机器人”
android·kotlin·游戏开发
一铭1119911 小时前
海豹办公 1.9.15 跨端办公软件实践 文档兼容 Access 数据库与移动 WebView 排错
android·数据库·electron·开源软件·access
geats人山人海11 小时前
java 7异常
android·java·开发语言
2601_9620710012 小时前
Kimi K3 vs DeepSeek V4-Pro实测对比:2026年同一入口十道题,耗时与token消耗差在哪
android·java·数据库
右手吉他14 小时前
高通平台IA APN问题分析之二
android·物联网
yeflx14 小时前
Ubuntu22.04安装Mysql Workbench
数据库·mysql·adb
夜雪一千14 小时前
MySQL 自增 ID 的底层原理与坑点
android·mysql·adb
不浪费一个字节14 小时前
一个纯 Python 实现的 APK 解析与设备操控工具箱
android
itmigrate15 小时前
PHP 导出大 CSV 时内存溢出的一次排查
android·开发语言·php