MySQL 复制 - 从站一直落后于主站

ade*_*har 12 mysql replication mysql-5.1

我正在使用 MySQL-5.1.50 和主从复制设置。

大多数情况下,slave 落后于 master。

当我运行时show processlist;,没有需要很长时间的查询。我也启用slow_log了。但是,它没有发现任何运行缓慢的查询。

从站不断发出警报,指出复制落后于主站几秒钟。有时,滞后时间会增加。

如何诊断问题的原因?

我需要紧急帮助,因为这个问题已经持续了 20 天。

Rol*_*DBA 21

Seconds_Behind_Master 真的就像通过时间旅行查看过去。

可以这样想:

  • 太阳距离地球 93,000,000 英里
  • 光速是 186,000 英里/秒
  • 简单的划分表明,太阳光到达地球大约需要 500 秒(8 分 20 秒)
  • 当你看太阳时,你实际上看不到太阳。您会看到 8 分 20 秒前的位置。

同样,Master 似乎在同时处理很多查询。

你回头看看 Slave,运行SHOW SLAVE STATUS\G,它说 200 for Seconds_Behind_Master。这个数字是怎么计算的?Slave 的时钟时间 (UNIX_TIMESTAMP(NOW()) - 查询完成并记录在 Master 的二进制日志中时的 TIMESTAMP。

除了 ,还有另一个衡量标准Seconds_Behind_Master。该指标称为Relay_Log_Space。这表示从站上所有中继文件的所有字节的总和。默认情况下,最大的单个中继日志限制为 1GB。如果Relay_Log_Space小于 1GB,这表明在 Master 上并行执行了许多长时间运行的查询。不幸的是,由于复制的 SQL 线程的单线程性质,查询是一个接一个地执行的。

例如,假设您在 Master 上有以下场景:

  • 慢查询日志已启用
  • 在 Master 上并行执行 20 个查询
  • 每个查询需要 3 秒
  • 每个查询都以相同的时间戳记录在主二进制日志中

当 Slave 从其中继日志中读取这些查询并一一处理时

  • 奴隶的时钟将移动
  • 20 个查询中每个查询的 TIMESTAMP 将相同
  • 完成查询的差异将增加 3 秒
  • 这导致 60 秒 Seconds_Behind_Master

关于慢日志,long_query_time的默认值为 10 秒。如果您在中继日志中的所有查询都少于 10 秒,您将永远不会在慢查询日志中捕获任何内容。

我对主服务器和从服务器都有以下建议

进一步的故障排除

如果要查看导致复制延迟的查询,请执行以下操作:

  • SHOW SLAVE STATUS\G
  • 从中获取中继日志的名称 Relay_Log_File
  • STOP SLAVE;
  • START SLAVE;
  • 在操作系统中,cd /var/lib/mysql或写入中继日志的任何地方
  • 将中继日志转储到文本文件

例如,让我们做 SHOW SLAVE STATUS\G

               Slave_IO_State: Waiting for master to send event
                  Master_Host: 10.64.51.149
                  Master_User: replicant
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000009
          Read_Master_Log_Pos: 1024035856
               Relay_Log_File: relay-bin.000030
                Relay_Log_Pos: 794732078
        Relay_Master_Log_File: mysql-bin.000009
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB:
          Replicate_Ignore_DB: search_cache
           Replicate_Do_Table:
       Replicate_Ignore_Table:
      Replicate_Wild_Do_Table:
  Replicate_Wild_Ignore_Table:
                   Last_Errno: 0
                   Last_Error:
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 1024035856
              Relay_Log_Space: 794732271
              Until_Condition: None
               Until_Log_File:
                Until_Log_Pos: 0
           Master_SSL_Allowed: No
           Master_SSL_CA_File:
           Master_SSL_CA_Path:
              Master_SSL_Cert:
            Master_SSL_Cipher:
               Master_SSL_Key:
        Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error:
               Last_SQL_Errno: 0
               Last_SQL_Error:
  Replicate_Ignore_Server_Ids:
             Master_Server_Id: 106451149
Run Code Online (Sandbox Code Playgroud)

如果我运行STOP SLAVE; START SLAVE;,中继日志将关闭并打开一个新日志。然而,你想要relay-bin.000030.

转储内容如下:

cd /var/lib/mysql
mysqlbinlog relay-bin.000030 > /root/RelayLogQueries.txt
less /root/RelayLogQueries.txt
Run Code Online (Sandbox Code Playgroud)

您现在可以看到 Slave 当前尝试处理的查询。您可以使用这些查询作为调整的起点。


Mic*_*bot 0

SHOW SLAVE STATUS 中的 secondary_behind_master 值是主服务器上的系统时间(事件最初执行并记录在二进制日志中时存储的)与从服务器上执行事件时的系统时间之间的差异。

如果两个系统的时钟不同步,则落后于主系统的秒数将给出不正确的值。