MySQL 支持延迟复制,这样副本服务器故意比源服务器晚至少指定的时间执行事务。本节介绍如何在副本上配置复制延迟以及如何监控复制延迟。
在 MySQL 8.4 中,延迟复制的方法取决于两个时间戳,immediate_commit_timestamp
和 original_commit_timestamp
(参见 复制延迟时间戳);延迟复制使用这些时间戳进行测量。如果直接源或副本没有使用这些时间戳,则使用 MySQL 5.7 中的延迟复制实现(参见 延迟复制)。本节介绍所有服务器都使用这些时间戳的延迟复制。
默认复制延迟为 0 秒。使用 CHANGE REPLICATION SOURCE TO SOURCE_DELAY=
语句将延迟设置为 N
N
秒。从源接收的事务在比其在直接源上的提交晚至少 N
秒之前不会执行。延迟在每个事务(而不是像以前版本的 MySQL 中那样在每个事件)发生,并且实际延迟仅对 gtid_log_event
或 anonymous_gtid_log_event
强加。事务中的其他事件始终跟随这些事件,没有任何等待时间强加于它们。
START REPLICA
和 STOP REPLICA
立即生效,忽略任何延迟。 RESET REPLICA
将延迟重置为 0。
replication_applier_configuration
性能模式表包含 DESIRED_DELAY
列,该列显示使用 SOURCE_DELAY
选项配置的延迟。 replication_applier_status
性能模式表包含 REMAINING_DELAY
列,该列显示剩余的延迟秒数。
延迟复制可用于多种目的
防止源上的用户错误。使用延迟,您可以将延迟副本回滚到错误发生之前的时刻。
测试系统在出现延迟时的行为。例如,在应用程序中,延迟可能是由副本上的繁重负载引起的。但是,生成此负载级别可能很困难。延迟复制可以在没有模拟负载的情况下模拟延迟。它还可以用于调试与延迟副本相关的条件。
检查数据库过去的样子,而无需重新加载备份。例如,通过将副本配置为延迟一周,如果您需要查看数据库在过去几天开发之前的样子,则可以检查延迟副本。
MySQL 8.4 提供了一种新的方法来测量复制拓扑中的延迟(也称为复制滞后),该方法依赖于与写入二进制日志的每个事务(而不是每个事件)的 GTID 关联的以下时间戳。
original_commit_timestamp
:事务写入(提交)到原始源二进制日志时的纪元后微秒数。immediate_commit_timestamp
:事务写入(提交)到直接源二进制日志时的纪元后微秒数。
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
对应于副本提交事务的时间。
在组复制设置中,当原始源是组的成员时,original_commit_timestamp
在事务准备提交时生成。换句话说,当它在原始源上完成执行并且其写入集已准备好发送到组的所有成员以进行认证时。当原始源是组外部的服务器时,original_commit_timestamp
会被保留。特定事务的相同 original_commit_timestamp
会被复制到组中的所有服务器,以及从成员复制的组外部的任何副本。事务的每个接收者也会使用 immediate_commit_timestamp
在其二进制日志中存储本地提交时间。
视图更改事件是组复制独有的,是一种特殊情况。包含这些事件的事务由每个组成员生成,但共享相同的 GTID(因此,它们不是先在源中执行,然后复制到组,而是组的所有成员执行并应用相同的事务)。组成员为与视图更改事件相关联的事务设置本地时间戳值。
在以前的 MySQL 版本中,监控复制延迟(滞后)最常见的方法之一是依赖于 SHOW REPLICA STATUS
输出中的 Seconds_Behind_Master
字段。但是,当使用比传统源-副本设置更复杂的复制拓扑(例如组复制)时,此指标不合适。在 MySQL 8 中添加 immediate_commit_timestamp
和 original_commit_timestamp
为复制延迟提供了更细粒度的信息。在支持这些时间戳的拓扑中监控复制延迟的推荐方法是使用以下 Performance Schema 表。
replication_connection_status
:与源的连接的当前状态,提供有关连接线程排队到中继日志的最后一个和当前事务的信息。replication_applier_status_by_coordinator
:仅在使用多线程副本时显示信息的协调器线程的当前状态,提供有关协调器线程缓冲到工作线程队列的最后一个事务以及当前正在缓冲的事务的信息。replication_applier_status_by_worker
:应用从源接收的事务的线程(s)的当前状态,提供有关复制 SQL 线程应用的事务的信息,或者在使用多线程副本时,每个工作线程应用的事务的信息。
使用这些表,您可以监控有关相应线程处理的最后一个事务以及该线程当前正在处理的事务的信息。这些信息包括
事务的 GTID
事务的
original_commit_timestamp
和immediate_commit_timestamp
,从副本的中继日志中检索线程开始处理事务的时间
对于最后一个处理的事务,线程完成处理它的时间
除了 Performance Schema 表之外,SHOW REPLICA STATUS
的输出还有三个字段显示
SQL_Delay
:一个非负整数,表示使用CHANGE REPLICATION SOURCE TO SOURCE_DELAY=
配置的复制延迟,其中N
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
)。该值与SHOW PROCESSLIST
显示的 SQL 线程的State
值相同。
当复制 SQL 线程在执行事件之前等待延迟过去时,SHOW PROCESSLIST
将其 State
值显示为 Waiting until SOURCE_DELAY seconds after master executed event
。