MySQL支持二进制日志事务压缩;当启用时,事务payload将使用zstd
算法压缩,然后作为单个事件(Transaction_payload_event
)写入服务器的二进制日志文件中。
压缩的事务payload在传输到副本、其他组复制组成员或客户端(如mysqlbinlog)时保持压缩状态,不会被接收线程解压缩,而是以压缩状态写入中继日志中。因此,二进制日志事务压缩可以在originator和接收方(及其备份)上节省存储空间,并在服务器实例之间传输事务时节省网络带宽。
压缩的事务payload在需要检查其中的单个事件时被解压缩。例如,applier线程在应用事件时需要解压缩Transaction_payload_event
。在恢复过程中,mysqlbinlog也会在回放事务时解压缩,SHOW BINLOG EVENTS
和SHOW RELAYLOG EVENTS
语句也会在执行时解压缩。
您可以使用binlog_transaction_compression
系统变量在MySQL服务器实例上启用二进制日志事务压缩,该变量默认为OFF
。您也可以使用binlog_transaction_compression_level_zstd
系统变量设置zstd算法的压缩级别,该值确定压缩努力,从1(最低努力)到22(最高努力)。随着压缩级别的增加,压缩率增加,减少了事务payload所需的存储空间和网络带宽。但是,数据压缩所需的努力也增加,占用了originating服务器的时间、CPU和内存资源。压缩努力的增加与压缩率的增加之间没有线性关系。
您可以在运行时使用 NDB
存储引擎的 ndb_log_transaction_compression
系统变量启用二进制日志记录压缩事务,并使用 ndb_log_transaction_compression_level_zstd
控制压缩级别。从 mysqld 启动时使用 --binlog-transaction-compression
命令行选项或在 my.cnf
文件中启用二进制日志记录压缩事务,会自动启用 ndb_log_transaction_compression
,并忽略 --ndb-log-transaction-compression
选项的设置;要禁用二进制日志记录压缩事务仅对 NDB
存储引擎,在客户端会话中设置 ndb_log_transaction_compression=OFF
。
以下类型的事件将从二进制日志记录压缩中排除,因此总是以未压缩形式写入二进制日志:
-
与事务的 GTID 相关的事件(包括匿名 GTID 事件)。
-
其他类型的控制事件,如视图更改事件和心跳事件。
-
事件事件和包含它们的整个事务。
-
非事务事件和包含它们的整个事务。包含非事务和事务存储引擎的混合事务不会将其有效负载压缩。
-
使用基于语句的二进制日志记录格式记录的事件。二进制日志记录压缩仅适用于基于行的二进制日志记录格式。
可以在包含压缩事务的二进制日志文件上使用二进制日志加密。
具有压缩有效负载的事务可以像其他事务一样回滚,也可以使用通常的过滤选项在副本上过滤掉。二进制日志记录压缩也可以应用于 XA 事务。
启用二进制日志记录压缩时,服务器的 max_allowed_packet
和 replica_max_allowed_packet
限制仍然适用,并以压缩后的 Transaction_payload_event
大小加上事件头部使用的字节数为准。
压缩的事务负载以单个数据包的形式发送,而不是每个事务事件都以单个数据包的形式发送,这是在二进制日志事务压缩未启用时的情况。如果您的复制拓扑结构处理大型事务,请注意启用二进制日志事务压缩可能会由于事务大小而停止复制,而在未启用二进制日志事务压缩时,事务可以成功复制。
对于多线程工作器,每个事务(包括其GTID事件和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
作为单个单位打印,然后将其解包并打印其中的每个事件。
对于引用事件结束位置的操作,例如START REPLICA
带有UNTIL
子句、SOURCE_POS_WAIT()
和sql_replica_skip_counter
,您必须指定压缩事务负载的结束位置(即Transaction_payload_event
)。当使用sql_replica_skip_counter
跳过事件时,压缩事务负载将被计为单个计数器值,因此所有事件都将作为一个单元被跳过。
支持二进制日志事务压缩的 MySQL Server 版本可以处理混合的压缩和未压缩的事务Payload。
-
与二进制日志事务压缩相关的系统变量不需要在所有组复制组成员上设置相同,并且不会从源复制到副本中。在每个具有二进制日志的 MySQL Server 实例上,您可以决定是否适合使用二进制日志事务压缩。
-
如果事务压缩被启用然后禁用在服务器上,压缩将不再应用于未来的事务,但已经压缩的事务Payload仍然可以被处理和显示。
-
如果事务压缩被指定为个别会话通过设置会话值
binlog_transaction_compression
,二进制日志可以包含混合的压缩和未压缩的事务Payload。
当复制拓扑中的源和其副本都启用了二进制日志事务压缩时,副本将接收压缩的事务Payload,并将其写入中继日志。它将事务Payload解压缩以应用事务,然后将其重新压缩以写入其二进制日志。任何下游副本将接收压缩的事务Payload。
当复制拓扑中的源启用了二进制日志事务压缩但其副本没有时,副本将接收压缩的事务Payload,并将其写入中继日志。它将事务Payload解压缩以应用事务,然后将其写入其自己的二进制日志中,如果它有一个。任何下游副本将接收未压缩的事务Payload。
当复制拓扑中的源没有启用二进制日志事务压缩但其副本启用了时,如果副本有二进制日志,它将在应用事务后压缩事务Payload,然后将其写入其二进制日志中。任何下游副本将接收压缩的事务Payload。
当 MySQL Server 实例没有二进制日志时,它可以接收、处理和显示压缩的事务Payload,不管其binlog_transaction_compression
的值如何。压缩的事务Payload接收到的服务器实例将其写入中继日志中,因此它们间接地从复制拓扑中的其他服务器执行的压缩中受益。
您可以使用性能模式表 binary_log_transaction_compression_stats
监控二进制日志事务压缩的效果。统计数据包括监控期间的数据压缩比率,您还可以查看服务器上最后一个事务的压缩效果。您可以通过截断表来重置统计数据。二进制日志和中继日志的统计数据是分开的,因此您可以看到每种日志类型的压缩影响。MySQL 服务器实例必须具有二进制日志以生成这些统计数据。
性能模式表 events_stages_current
显示事务在解压缩或压缩事务有效负载阶段的状态,并显示该阶段的进度。压缩由处理事务的工作线程执行,在事务提交之前,前提是没有排除事务的事件在最终捕获缓存中(例如,事件事件)。当需要解压缩时,它将逐个事件地执行。
mysqlbinlog 使用 --verbose
选项包括注释,注释中包含压缩大小和未压缩大小的压缩事务有效负载,以及使用的压缩算法。
您可以使用 SOURCE_COMPRESSION_ALGORITHMS
和 SOURCE_ZSTD_COMPRESSION_LEVEL
选项的 CHANGE REPLICATION SOURCE TO
语句或 replica_compressed_protocol
系统变量在复制连接中启用连接压缩。如果您在启用二进制日志事务压缩的系统中启用连接压缩,连接压缩的影响将减少,因为可能没有机会进一步压缩压缩的事务有效负载。然而,连接压缩仍然可以对未压缩的事件和消息头进行操作。如果您需要节省存储空间和网络带宽,可以将二进制日志事务压缩与连接压缩结合使用。有关复制连接的连接压缩的更多信息,请参阅 第 6.2.8 节,“连接压缩控制”。
对于组复制,消息压缩默认启用,对于超过由group_replication_compression_threshold
系统变量设置的阈值的消息。你也可以通过使用group_replication_recovery_compression_algorithms
和group_replication_recovery_zstd_compression_level
系统变量来配置分布式恢复的状态传输的消息压缩。如果你在已经配置了这些变量的系统中启用二进制日志事务压缩,组复制的消息压缩仍然可以对未压缩的事件和消息头进行操作,但其影响将减少。有关组复制消息压缩的更多信息,请参见第 20.7.4 节,“消息压缩”。