MySQL 支持延迟复制,以便副本服务器故意执行事务晚于源服务器至少指定的时间量。本节描述如何在副本服务器上配置延迟复制,以及如何监控延迟复制。
在 MySQL 8.3 中,延迟复制的方法取决于两个时间戳:immediate_commit_timestamp
和 original_commit_timestamp
(见 延迟复制时间戳);延迟复制是使用这些时间戳测量的。如果 immediate 源或副本不使用这些时间戳,则使用 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.3 提供了一种新的方法来测量延迟(也称为复制延迟)在使用 GTID 的事务的复制拓扑结构中,该方法依赖于每个事务的以下时间戳写入二进制日志。
-
original_commit_timestamp
:事务写入(提交)到原始源服务器二进制日志的微秒数自 epoch。 -
immediate_commit_timestamp
:事务写入(提交)到 immediate 源服务器二进制日志的微秒数自 epoch。
mysqlbinlog 的输出显示了这些时间戳,以微秒自 epoch 和 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
。
视图更改事件是 Group Replication 的特殊情况,这些事件是由每个组成员生成的,但共享相同的 GTID(因此,它们不是首先在源上执行,然后复制到组中,而是所有组成员执行和应用相同的事务)。组成员为与视图更改事件相关的事务设置本地时间戳值。
在以前的 MySQL 版本中,监控复制延迟(lag)的最常见方法是依赖于 SHOW REPLICA STATUS
语句的输出中的 Seconds_Behind_Master
字段。然而,这个指标在使用复杂的复制拓扑结构时,如 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
,从副本的中继日志中检索 -
线程开始处理事务的时间
-
对于最后处理的事务,线程完成处理的时间
除了 Performance Schema 表外,SHOW REPLICA STATUS
的输出还包括三个字段,显示:
-
SQL_Delay
:一个非负整数,表示使用CHANGE REPLICATION SOURCE TO SOURCE_DELAY=
配置的复制延迟,N
N
以秒为单位。 -
SQL_Remaining_Delay
:当Replica_SQL_Running_State
是等待主服务器执行事件后的 MASTER_DELAY 秒
时,该字段包含一个整数,表示延迟剩余的秒数。在其他时候,该字段为NULL
。 -
Replica_SQL_Running_State
:一个字符串,指示 SQL 线程的状态(类似于Replica_IO_State
)。该值与State
值相同,如SHOW PROCESSLIST
所显示的 SQL 线程的状态。
当复制 SQL 线程等待延迟结束以执行事件时,SHOW PROCESSLIST
显示其 State
值为 等待主服务器执行事件后的 MASTER_DELAY 秒
。