Documentation Home

5.4.4.5 二进制日志事务压缩

从 MySQL 8.0.20 开始,您可以在 MySQL 服务器实例上启用二进制日志事务压缩。当启用二进制日志事务压缩时,事务负载使用 zstd 算法进行压缩,然后作为单个事件 (a Transaction_payload_event) 写入服务器的二进制日志文件。

压缩事务负载在复制流中发送到副本、其他组复制组成员或客户端(如 mysqlbinlog )时保持压缩状态。它们不被接收线程解压缩,并且仍以压缩状态写入中继日志。因此,二进制日志事务压缩为事务的发起者和接收者(以及他们的备份)节省了存储空间,并在服务器实例之间发送事务时节省了网络带宽。

当需要检查其中包含的各个事件时,压缩事务有效负载将被解压缩。例如,Transaction_payload_event由应用程序线程解压缩,以便将它包含的事件应用到接收者上。解压也是在recovery的时候进行的,在replay transactions的时候通过mysqlbinlogSHOW BINLOG EVENTS ,通过andSHOW RELAYLOG EVENTS语句。

您可以使用系统变量在 MySQL 服务器实例上启用二进制日志事务压缩 binlog_transaction_compression ,默认为OFF. 您还可以使用 binlog_transaction_compression_level_zstd 系统变量来设置用于压缩的 zstd 算法的级别。此值确定压缩效果,从 1(最低效果)到 22(最高效果)。随着压缩级别的提高,压缩率也会提高,从而减少交易负载所需的存储空间和网络带宽。但是,数据压缩所需的工作量也会增加,占用源服务器上的时间以及 CPU 和内存资源。压缩力的增加与压缩比的增加没有线性关系。

笔记

在 NDB 8.0.31 之前:可以在 NDB Cluster 中启用二进制日志事务压缩,但只有在使用 --binlog-transaction-compression 选项启动服务器时(以及可能的 --binlog-transaction-compression-level-zstd ); 在运行时更改其中一个或两个系统变量的值 binlog_transaction_compressionbinlog_transaction_compression_level_zstd 的日志记录没有影响 NDB

NDB 8.0.31 及更高版本:您可以使用 该版本中引入的系统变量 NDB在运行时使用存储引擎 为表启用压缩事务的二进制日志记录 。在命令行或文件中启动 mysqld 会导致 自动 启用忽略该 选项的任何设置;仅对存储引擎 禁用二进制日志事务压缩,在启动后的客户端会话中设置 ndb_log_transaction_compressionndb_log_transaction_compression_level_zstd--binlog-transaction-compressionmy.cnfndb_log_transaction_compression--ndb-log-transaction-compressionNDBndb_log_transaction_compression=OFFmysqld

以下类型的事件被排除在二进制日志事务压缩之外,因此始终未压缩地写入二进制日志:

  • 与事务的 GTID 相关的事件(包括匿名 GTID 事件)。

  • 其他类型的控件事件,如视图变化事件和心跳事件。

  • 事件事件和包含它们的所有交易。

  • 非交易事件和包含它们的所有交易。涉及非事务和事务存储引擎混合的事务不会压缩其有效负载。

  • 使用基于语句的二进制日志记录的事件。二进制日志事务压缩仅适用于基于行的二进制日志记录格式。

二进制日志加密可用于包含压缩事务的二进制日志文件。

5.4.4.5.1 启用二进制日志事务压缩时的行为

具有压缩有效负载的事务可以像任何其他事务一样回滚,并且它们也可以通过通常的过滤选项在副本上被过滤掉。二进制日志事务压缩可以应用于 XA 事务。

当启用二进制日志事务压缩时,服务器的 max_allowed_packetreplica_max_allowed_packetslave_max_allowed_packet 限制仍然适用,并根据压缩后的大小 Transaction_payload_event以及用于事件标头的字节数进行测量。

重要的

压缩的事务有效负载作为单个数据包发送,而不是在单独的数据包中发送事务的每个事件,就像未使用二进制日志事务压缩时的情况一样。如果您的复制拓扑处理大型事务,请注意,在未使用二进制日志事务压缩时可以成功复制的大型事务可能会在使用二进制日志事务压缩时由于其大小而停止复制。

对于多线程工作者,每个事务(包括它的 GTID 事件和Transaction_payload_event)都分配给一个工作线程。工作线程解压缩事务有效负载并逐个应用其中的各个事件。如果在应用 中的任何事件时发现错误Transaction_payload_event,则整个事务将作为失败报告给协调器。当replica_parallel_typeslave_parallel_type设置为 时 DATABASE,所有受事务影响的数据库在事务被调度之前被映射。使用二进制日志事务压缩 DATABASE与为每个事件映射和调度的未压缩事务相比,策略可以减少并行性。

对于半同步复制(参见 第 17.4.10 节,“半同步复制”Transaction_payload_event ),副本在收到 完成时确认事务 。

当启用二进制日志校验和时(这是默认设置),复制源服务器不会为压缩事务负载中的单个事件写入校验和。相反,为完整 Transaction_payload_event的 写入校验和,为任何未压缩的事件写入单独的校验和,例如与 GTID 相关的事件。

对于SHOW BINLOG EVENTSand SHOW RELAYLOG EVENTS 语句,Transaction_payload_event 首先将其打印为一个单元,然后将其解包并打印其中的每个事件。

对于引用事件结束位置的操作,例如START REPLICA(或在 MySQL 8.0.22 之前 START SLAVE)使用UNTIL子句 SOURCE_POS_WAIT()or MASTER_POS_WAIT()sql_replica_skip_counteror sql_slave_skip_counter,您必须指定压缩事务负载的结束位置( the Transaction_payload_event)。sql_replica_skip_counter当使用or 跳过事件时 sql_slave_skip_counter,压缩的事务有效负载被计为单个计数器值,因此其中的所有事件都作为一个单元被跳过。

5.4.4.5.2 组合压缩和未压缩的交易有效载荷

支持二进制日志事务压缩的 MySQL 服务器版本可以处理压缩和未压缩事务负载的混合。

  • 与二进制日志事务压缩相关的系统变量不需要在所有 Group Replication 组成员上设置相同,并且不会在复制拓扑中从源复制到副本。您可以决定二进制日志事务压缩是否适用于每个具有二进制日志的 MySQL 服务器实例。

  • 如果在服务器上启用然后禁用事务压缩,则压缩不会应用于该服务器上发起的未来事务,但仍然可以处理和显示已压缩的事务有效负载。

  • 如果通过将会话值设置为 为单个会话指定事务压缩 binlog_transaction_compression,则二进制日志可以包含压缩和未压缩事务有效负载的混合。

当复制拓扑中的源及其副本都启用了二进制日志事务压缩时,副本接收压缩的事务有效负载并将它们压缩写入其中继日志。它解压缩交易负载以应用交易,然后在申请写入其二进制日志后再次压缩它们。任何下游副本都会收到压缩的事务有效负载。

当复制拓扑中的源启用了二进制日志事务压缩但其副本未启用时,副本接收压缩的事务有效负载并将它们压缩写入其中继日志。它解压缩事务有效负载以应用事务,然后将它们未压缩地写入自己的二进制日志(如果有的话)。任何下游副本都会收到未压缩的事务有效负载。

当复制拓扑中的源未启用二进制日志事务压缩但其副本启用时,如果副本具有二进制日志,则它会在应用事务负载后对其进行压缩,并将压缩的事务负载写入其二进制日志。任何下游副本都会收到压缩的事务有效负载。

当 MySQL 服务器实例没有二进制日志时,如果它是 MySQL 8.0.20 的版本,它可以接收、处理和显示压缩的事务有效负载,而不管它的 值 binlog_transaction_compression。此类服务器实例接收到的压缩事务​​负载以其压缩状态写入中继日志,因此它们间接受益于复制拓扑中其他服务器执行的压缩。

MySQL 8.0.20 之前版本的副本无法从启用二进制日志事务压缩的源复制。MySQL 8.0.20 或更高版本的副本可以从不支持二进制日志事务压缩的较早版本的源复制,并且可以在将事务写入自己的二进制日志时对从该源接收的事务执行自己的压缩。

5.4.4.5.3 监控二进制日志事务压缩

您可以使用 Performance Schema 表监视二进制日志事务压缩的效果 binary_log_transaction_compression_stats。统计数据包括监控期间的数据压缩率,还可以查看服务器上最后一个事务的压缩效果。您可以通过截断表来重置统计信息。二进制日志和中继日志的统计信息被分开,因此您可以看到压缩对每种日志类型的影响。MySQL 服务器实例必须有一个二进制日志来生成这些统计信息。

Performance Schema 表 events_stages_current显示事务何时处于其事务负载的解压缩或压缩阶段,并显示该阶段的进度。压缩由处理事务的工作线程执行,就在提交事务之前,前提是最终捕获缓存中没有将事务从二进制日志事务压缩中排除的事件(例如,事件事件)。当需要解压缩时,一次对有效载荷中的一个事件执行。

带有选项的 mysqlbinlog--verbose包括说明压缩事务有效负载的压缩大小和未压缩大小的注释,以及使用的压缩算法。

您可以在复制连接的协议级别启用连接压缩,使用 SOURCE_COMPRESSION_ALGORITHMS| MASTER_COMPRESSION_ALGORITHMSSOURCE_ZSTD_COMPRESSION_LEVEL| MASTER_ZSTD_COMPRESSION_LEVEL语句的选项 CHANGE REPLICATION SOURCE TO (来自 MySQL 8.0.23)或CHANGE MASTER TO语句(MySQL 8.0.23 之前),或者 replica_compressed_protocol orslave_compressed_protocol 系统变量。如果在同时启用连接压缩的系统中启用二进制日志事务压缩,则连接压缩的影响会降低,因为可能几乎没有机会进一步压缩压缩的事务负载。但是,连接压缩仍然可以对未压缩的事件和消息头进行操作。如果您需要节省存储空间和网络带宽,可以结合连接压缩启用二进制日志事务压缩。有关复制连接的连接压缩的更多信息,请参阅 第 4.2.8 节,“连接压缩控制”

group_replication_compression_threshold 对于 Group Replication,默认情况下会为超过系统变量 设置的阈值的消息启用压缩 。group_replication_recovery_compression_algorithms 您还可以使用和 group_replication_recovery_zstd_compression_level 系统变量,通过来自捐助者二进制日志的状态传输方法,为分布式恢复发送的消息配置压缩 。如果在配置了这些的系统中启用二进制日志事务压缩,Group Replication 的消息压缩仍然可以对未压缩的事件和消息头进行操作,但其影响会降低。有关组复制的消息压缩的更多信息,请参阅 第 18.7.4 节,“消息压缩”.