19.4.11 延迟复制
MySQL 支持延迟复制,使得副本服务器在指定的时间后执行事务。这部分描述了如何在副本上配置延迟复制,以及如何监控延迟复制。
在 MySQL 8.4 中,延迟复制的方法取决于两个时间戳:immediate_commit_timestamp
和 original_commit_timestamp
(见Replication Delay Timestamps);延迟复制使用这些时间戳测量。 如果源或副本不使用这些时间戳,MySQL 5.7 中的延迟复制实现将被使用(见Delayed Replication)。这部分描述了使用这些时间戳的副本之间的延迟复制。
默认的复制延迟是 0 秒。使用CHANGE REPLICATION SOURCE TO SOURCE_DELAY=
语句将延迟设置为 N
N
秒。从源接收的事务直到至少 N
秒后才执行。延迟发生在每个事务(而不是事件)中,并且实际延迟只对 gtid_log_event
或 anonymous_gtid_log_event
事件施加。其他事件在事务中总是跟随这些事件,而不需要延迟。
START REPLICA
和 STOP REPLICA
立即生效,忽略延迟。 RESET REPLICA
将延迟重置为 0。
Performance Schema 表 replication_applier_configuration
中的 DESIRED_DELAY
列显示使用 SOURCE_DELAY
选项配置的延迟。Performance Schema 表 replication_applier_status
中的 REMAINING_DELAY
列显示剩余延迟秒数。
延迟复制可以用于以下目的:
-
保护源上的用户错误。使用延迟,您可以将延迟副本回滚到错误发生前的时间。
-
模拟系统在延迟情况下的行为。例如,在应用程序中,延迟可能是由副本上的负载引起的。然而,可以很难生成这种负载水平。延迟复制可以模拟延迟,而不需要模拟负载。它也可以用来调试与延迟副本相关的条件。
-
为了查看过去数据库的状态,而不需要重新加载备份。例如,可以配置一个延迟副本,延迟为一周。如果需要查看最近几天的开发前数据库状态,可以检查延迟副本。
复制延迟时间戳
MySQL 8.4 提供了一个新的方法来衡量复制延迟(也称为复制延迟),该方法基于每个事务的GTID(Global Transaction Identifier)中的时间戳,而不是每个事件的时间戳。
-
original_commit_timestamp
: 该时间戳表示自_epoch_以来的微秒数,表示事务被写入(提交)到原始源的二进制日志中。 -
immediate_commit_timestamp
: 该时间戳表示自_epoch_以来的微秒数,表示事务被写入(提交)到直接源的二进制日志中。
mysqlbinlog 工具的输出将这些时间戳显示在两个格式中:以微秒为单位的时间戳和以TIMESTAMP格式的时间戳,该格式基于用户定义的时区以提高可读性。例如:
#170404 10:48:05 server id 1 end_log_pos 233 CRC32 0x016ce647 GTID last_committed=0
\ sequence_number=1 original_committed_timestamp=1491299285661130 immediate_commit_timestamp=1491299285843771
# original_commit_timestamp=1491299285661130 (2017-04-04 10:48:05.661130 WEST)
# immediate_commit_timestamp=1491299285843771 (2017-04-04 10:48:05.843771 WEST)
/*!80001 SET @@SESSION.original_commit_timestamp=1491299285661130*//*!*/;
SET @@SESSION.GTID_NEXT= 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa:1'/*!*/;
# at 233
通常情况下,original_commit_timestamp
在所有应用事务的副本中都是相同的。在源副本复制中,事务在原始源的二进制日志中的original_commit_timestamp
总是与其在直接源的二进制日志中的immediate_commit_timestamp
相同。在副本的中继日志中,事务的original_commit_timestamp
和immediate_commit_timestamp
与原始源的二进制日志中的相同,而在其自己的二进制日志中,事务的immediate_commit_timestamp
对应于副本提交事务的时间。
在 Group Replication 设置中,当原始源是群组的一部分时,original_commit_timestamp
在事务准备提交时生成,即事务在原始源上执行完成并且写入集准备发送到群组所有成员进行认证时。否则,原始源是一个外部服务器,original_commit_timestamp
将被保留。同一个事务的original_commit_timestamp
将被复制到群组中的所有服务器,并且到任何外部副本中,该副本从群组成员复制。每个事务的接收者也将在其二进制日志中使用immediate_commit_timestamp
记录本地提交时间。
查看更改事件,这些事件是 Group Replication 的专有特性。包含这些事件的事务由每个群组成员生成,但它们共享相同的GTID(因此,它们不是首先在源上执行,然后在群组中复制,而是所有群组成员都执行和应用相同的事务)。群组成员将本地时间戳值设置为与事务相关的事件。
监控复制延迟
在 MySQL 之前的版本中,监控复制延迟(lag)的常见方法是依赖于 Seconds_Behind_Master
字段在 SHOW REPLICA STATUS
的输出结果。然而,这个指标不适用于使用复杂拓扑结构的复制,例如 Group Replication。MySQL 8 中添加了 immediate_commit_timestamp
和 original_commit_timestamp
,提供了更高的复制延迟信息。为了在支持这些时间戳的拓扑结构中监控复制延迟,推荐使用以下 Performance Schema 表。
-
replication_connection_status
:当前连接到源的状态,提供了连接线程队列中最后一个和当前一个事务的信息。 -
replication_applier_status_by_coordinator
:当前协调线程的状态,只在使用多线程复制时显示,提供了协调线程将要队列的最后一个事务和当前事务的信息,以及当前正在队列的事务。 -
replication_applier_status_by_worker
:当前线程正在应用来自源的事务,提供了复制 SQL 线程或每个工作线程在多线程复制时应用的事务信息。
使用这些表,您可以监控对应线程处理的最后一个事务和当前事务的信息。这包括:
-
事务的 GTID
-
事务的
original_commit_timestamp
和immediate_commit_timestamp
,来自复制的日志 -
线程开始处理事务的时间
-
最后处理的事务的完成时间
此外,SHOW REPLICA STATUS
的输出结果还包含三个字段:
-
SQL_Delay
:一个非负整数,表示使用CHANGE REPLICATION SOURCE TO SOURCE_DELAY=
配置的复制延迟, measured in seconds.N
-
SQL_Remaining_Delay
:当Replica_SQL_Running_State
是Waiting until SOURCE_DELAY seconds after master executed event
时,这个字段包含一个整数,表示剩余的延迟时间。在其他情况下,这个字段是NULL
. -
Replica_SQL_Running_State
: 表示 SQL 线程的状态(与Replica_IO_State
类似)。该值与 SQL 线程的State
值相同,显示在SHOW PROCESSLIST
中。
当复制 SQL 线程等待延迟期满后执行事件时,SHOW PROCESSLIST
将显示其 State
值为 等待 SOURCE_DELAY 秒后 master 执行事件
。