MySQL 支持二进制日志事务压缩;启用此功能后,事务有效负载将使用 zstd
算法压缩,然后作为单个事件 (a Transaction_payload_event
) 写入服务器的二进制日志文件。
压缩的事务有效负载在通过复制流发送到副本、其他组复制组成员或客户端(如 mysqlbinlog)时,仍处于压缩状态。它们不会被接收线程解压缩,并且仍然处于压缩状态写入中继日志。因此,二进制日志事务压缩在事务发起者和接收者(及其备份)上都节省了存储空间,并在事务在服务器实例之间发送时节省了网络带宽。
当需要检查其中包含的单个事件时,将解压缩压缩的事务有效负载。例如,Transaction_payload_event
被应用线程解压缩,以便将其中包含的事件应用于接收方。在恢复期间,mysqlbinlog 在重放事务时,以及 SHOW BINLOG EVENTS
和 SHOW RELAYLOG EVENTS
语句在进行解压缩。
您可以使用 binlog_transaction_compression
系统变量在 MySQL 服务器实例上启用二进制日志事务压缩,该变量默认为 OFF
。您还可以使用 binlog_transaction_compression_level_zstd
系统变量设置用于压缩的 zstd 算法的级别。此值确定压缩工作量,从 1(最低工作量)到 22(最高工作量)。随着压缩级别的提高,压缩率也会提高,这会减少事务有效负载所需的存储空间和网络带宽。但是,数据压缩所需的工作量也会增加,从而占用源服务器上的时间以及 CPU 和内存资源。压缩工作量的增加与压缩率的增加之间没有线性关系。
设置 binlog_transaction_compression
或 binlog_transaction_compression_level_zstd
(或两者)不会立即生效,而是应用于所有后续的 START REPLICA
语句。
您可以使用 ndb_log_transaction_compression
系统变量在运行时为使用 NDB
存储引擎的表启用压缩事务的二进制日志记录,并使用 ndb_log_transaction_compression_level_zstd
控制压缩级别。从命令行或 my.cnf
文件中使用 --binlog-transaction-compression
启动 mysqld 会导致自动启用 ndb_log_transaction_compression
,并且会忽略 --ndb-log-transaction-compression
选项的任何设置;要仅为 NDB
存储引擎禁用二进制日志事务压缩,请在启动 mysqld 后在客户端会话中设置 ndb_log_transaction_compression=OFF
。
以下类型的事件不包含在二进制日志事务压缩中,因此始终以未压缩的方式写入二进制日志
与事务 GTID 相关的事件(包括匿名 GTID 事件)。
其他类型的控制事件,例如视图更改事件和心跳事件。
事件和包含它们的任何事务的全部内容。
非事务性事件和包含它们的任何事务的全部内容。涉及混合了非事务性存储引擎和事务性存储引擎的事务不会压缩其有效负载。
使用基于语句的二进制日志记录的事件。二进制日志事务压缩仅适用于基于行的二进制日志格式。
二进制日志加密可用于包含压缩事务的二进制日志文件。
具有压缩有效负载的事务可以像任何其他事务一样回滚,并且还可以通过通常的过滤选项在副本上进行过滤。二进制日志事务压缩可以应用于 XA 事务。
启用二进制日志事务压缩后,服务器的max_allowed_packet
和replica_max_allowed_packet
限制仍然适用,并且是根据Transaction_payload_event
的压缩大小以及事件头使用的字节数来衡量的。
压缩的事务有效负载作为单个数据包发送,而不是像未启用二进制日志事务压缩时那样,事务的每个事件都以单个数据包发送。如果您的复制拓扑处理大型事务,请注意,在未启用二进制日志事务压缩时可以成功复制的大型事务,可能会在启用二进制日志事务压缩后由于其大小而停止复制。
对于多线程工作线程,每个事务(包括其 GTID 事件和Transaction_payload_event
)都分配给一个工作线程。工作线程解压缩事务有效负载并逐个应用其中的单个事件。如果在应用Transaction_payload_event
中的任何事件时发现错误,则整个事务将被报告给协调器,表明它已失败。当replica_parallel_type
或replica_parallel_type
设置为DATABASE
时,事务被安排之前会映射受事务影响的所有数据库。与未压缩的事务相比,使用二进制日志事务压缩与DATABASE
策略结合使用可能会降低并行性,因为未压缩的事务会为每个事件进行映射和安排。
对于半同步复制(参见第 19.4.10 节,“半同步复制”),副本在收到完整的Transaction_payload_event
后确认事务。
启用二进制日志校验和(默认情况下启用)时,复制源服务器不会为压缩事务有效负载中的单个事件写入校验和。相反,会为完整的Transaction_payload_event
写入校验和,并且会为任何未压缩的事件(例如与 GTID 相关的事件)写入单个校验和。
对于SHOW BINLOG EVENTS
和SHOW RELAYLOG EVENTS
语句,Transaction_payload_event
首先作为单个单元打印,然后解压缩并打印其内部的每个事件。
对于引用事件结束位置的操作,例如带有UNTIL
子句的START REPLICA
、SOURCE_POS_WAIT()
和sql_replica_skip_counter
,您必须指定压缩事务有效负载(Transaction_payload_event
)的结束位置。当使用sql_replica_skip_counter
跳过事件时,压缩事务有效负载被计算为一个计数器值,因此其内部的所有事件都作为一个单元跳过。
支持二进制日志事务压缩的 MySQL Server 版本可以处理压缩和未压缩事务有效负载的混合。
与二进制日志事务压缩相关的系统变量不需要在所有 Group Replication 组成员上设置相同的值,并且不会在复制拓扑中从源复制到副本。您可以决定二进制日志事务压缩是否适合具有二进制日志的每个 MySQL Server 实例。
如果在服务器上启用然后禁用事务压缩,则不会对该服务器上以后发起的的事务应用压缩,但仍然可以处理和显示已压缩的事务有效负载。
如果通过设置
binlog_transaction_compression
的会话值,为单个会话指定事务压缩,则二进制日志可以包含压缩和未压缩事务有效负载的混合。
当复制拓扑中的源及其副本都启用了二进制日志事务压缩时,副本会接收压缩的事务有效负载并将它们压缩到其中继日志中。它解压缩事务有效负载以应用事务,然后在应用完成后再次压缩以写入其二进制日志。任何下游副本都会收到压缩的事务有效负载。
当复制拓扑中的源启用了二进制日志事务压缩,但其副本没有启用时,副本会接收压缩的事务有效负载并将它们压缩到其中继日志中。它解压缩事务有效负载以应用事务,然后将其以未压缩的形式写入其自己的二进制日志(如果有)。任何下游副本都会收到未压缩的事务有效负载。
当复制拓扑中的源没有启用二进制日志事务压缩,但其副本启用了二进制日志事务压缩时,如果副本有二进制日志,它会在应用事务后压缩事务有效负载,并将压缩的事务有效负载写入其二进制日志。任何下游副本都会收到压缩的事务有效负载。
当 MySQL Server 实例没有二进制日志时,无论其binlog_transaction_compression
的值如何,它都可以接收、处理和显示压缩的事务有效负载。这些服务器实例接收的压缩事务有效负载以其压缩状态写入中继日志,因此它们间接受益于复制拓扑中其他服务器执行的压缩。
您可以使用 Performance Schema 表binary_log_transaction_compression_stats
监控二进制日志事务压缩的影响。统计信息包括监控期间的数据压缩率,您还可以查看压缩对服务器上最后一个事务的影响。您可以通过截断表来重置统计信息。二进制日志和中继日志的统计信息是分开显示的,因此您可以查看每种日志类型的压缩影响。MySQL Server 实例必须有二进制日志才能生成这些统计信息。
Performance Schema 表events_stages_current
显示事务何时处于其事务有效负载的解压缩或压缩阶段,并显示其在此阶段的进度。压缩由处理事务的工作线程执行,在事务提交之前执行,前提是已完成捕获缓存中没有事件将事务排除在二进制日志事务压缩之外(例如,事件事件)。需要解压缩时,会一次解压缩有效负载中的一个事件。
mysqlbinlog 带有--verbose
选项包括注释,说明压缩事务有效负载的压缩大小和未压缩大小,以及使用的压缩算法。
您可以使用CHANGE REPLICATION SOURCE TO
语句的SOURCE_COMPRESSION_ALGORITHMS
和SOURCE_ZSTD_COMPRESSION_LEVEL
选项,或replica_compressed_protocol
系统变量,在协议级别为复制连接启用连接压缩。如果您在也启用了连接压缩的系统中启用二进制日志事务压缩,则连接压缩的影响会降低,因为可能没有太多机会进一步压缩压缩的事务有效负载。但是,连接压缩仍然可以在未压缩的事件和消息头中运行。如果您需要节省存储空间和网络带宽,则可以将二进制日志事务压缩与连接压缩结合使用。有关复制连接的连接压缩的更多信息,请参见第 6.2.8 节,“连接压缩控制”。
对于 Group Replication,默认情况下会为超过group_replication_compression_threshold
系统变量设置的阈值的消息启用压缩。您还可以使用group_replication_recovery_compression_algorithms
和group_replication_recovery_zstd_compression_level
系统变量,为通过从捐赠者二进制日志进行状态转移的方式发送的分布式恢复消息配置压缩。如果您在配置了这些变量的系统中启用二进制日志事务压缩,则 Group Replication 的消息压缩仍然可以在未压缩的事件和消息头中运行,但其影响会降低。有关 Group Replication 的消息压缩的更多信息,请参见第 20.7.4 节,“消息压缩”。