MySQL 支持延迟复制,这样副本服务器在至少指定的时间量之后才执行事务,而不是立即执行。本节介绍如何在副本上配置复制延迟,以及如何监控复制延迟。
在 MySQL 9.0 中,延迟复制的方法取决于两个时间戳,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 9.0 提供了一种新的方法来衡量复制拓扑中的延迟(也称为复制滞后),该方法依赖于与写入二进制日志的每个事务(而不是每个事件)的 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
。