MySQL 支持二进制日志事务压缩;启用此功能后,事务负载将使用 zstd
算法进行压缩,然后作为单个事件(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 版本可以处理压缩和未压缩事务负载的混合。
与二进制日志事务压缩相关的系统变量不需要在所有组复制组成员上设置相同,并且不会在复制拓扑中从源复制到副本。您可以决定二进制日志事务压缩是否适用于具有二进制日志的每个 MySQL Server 实例。
如果在服务器上启用事务压缩然后禁用,则不会对该服务器上发起的未来事务应用压缩,但仍然可以处理和显示已压缩的事务负载。
如果通过设置
binlog_transaction_compression
的会话值来为各个会话指定事务压缩,则二进制日志可以包含压缩和未压缩事务负载的混合。
当复制拓扑中的源及其副本都启用了二进制日志事务压缩时,副本会接收压缩的事务有效负载,并将它们压缩写入其中继日志。它会解压缩事务有效负载以应用事务,然后在应用于其二进制日志后再次对其进行压缩。任何下游副本都会接收压缩的事务有效负载。
当复制拓扑中的源启用了二进制日志事务压缩,但其副本没有启用时,副本会接收压缩的事务有效负载,并将它们压缩写入其中继日志。它会解压缩事务有效负载以应用事务,然后将其写入其自己的二进制日志(如果有)中,且不进行压缩。任何下游副本都会接收未压缩的事务有效负载。
当复制拓扑中的源未启用二进制日志事务压缩,但其副本启用了时,如果副本有二进制日志,它会在应用事务有效负载后对其进行压缩,并将压缩的事务有效负载写入其二进制日志。任何下游副本都会接收压缩的事务有效负载。
当 MySQL 服务器实例没有二进制日志时,它可以接收、处理和显示压缩的事务有效负载,而不管其 binlog_transaction_compression
的值如何。此类服务器实例接收的压缩事务有效负载会以其压缩状态写入中继日志,因此它们会间接受益于复制拓扑中其他服务器执行的压缩。
你可以使用性能模式表 binary_log_transaction_compression_stats
监视二进制日志事务压缩的效果。统计信息包括受监视时期的数据压缩比率,你还可以查看压缩对服务器上最后一个事务的影响。你可以通过截断表来重置统计信息。二进制日志和中继日志的统计信息是分开的,因此你可以看到压缩对每种日志类型的影响。MySQL 服务器实例必须有一个二进制日志才能生成这些统计信息。
性能模式表 events_stages_current
显示事务在其事务有效负载的解压缩或压缩阶段时的情况,并显示此阶段的进度。压缩由处理事务的工作线程在事务提交之前执行,前提是已完成捕获缓存中没有事件将事务排除在二进制日志事务压缩之外(例如,事件事件)。当需要解压缩时,它将一次针对有效负载中的一个事件执行。
mysqlbinlog 随 --verbose
选项一起包含注释,说明压缩事务有效负载的压缩大小和未压缩大小,以及所使用的压缩算法。
您可以使用 CHANGE REPLICATION SOURCE TO
语句的 SOURCE_COMPRESSION_ALGORITHMS
和 SOURCE_ZSTD_COMPRESSION_LEVEL
选项或 replica_compressed_protocol
系统变量,在协议级别为复制连接启用连接压缩。如果您在也启用了连接压缩的系统中启用二进制日志事务压缩,则连接压缩的影响会减小,因为进一步压缩压缩的事务有效负载的机会可能很小。但是,连接压缩仍然可以在未压缩事件和消息头上运行。如果您需要节省存储空间和网络带宽,则可以将二进制日志事务压缩与连接压缩结合使用。有关复制连接的连接压缩的更多信息,请参见 第 6.2.8 节“连接压缩控制”。
对于组复制,对于超过 group_replication_compression_threshold
系统变量设置的阈值的邮件,默认启用压缩。您还可以使用 group_replication_recovery_compression_algorithms
和 group_replication_recovery_zstd_compression_level
系统变量,为通过捐赠者的二进制日志的状态传输方法发送的分布式恢复邮件配置压缩。如果您在配置这些变量的系统中启用二进制日志事务压缩,组复制的邮件压缩仍然可以在未压缩的事件和邮件头中运行,但其影响会减小。有关组复制邮件压缩的更多信息,请参阅 第 20.7.4 节“邮件压缩”。