MySQL道普請便り

第207回binlog_transaction_compressionを使ったMySQLバイナリログの圧縮について

MySQLのバイナリログ(binlog)は、レプリケーションやデータリカバリの目的で変更履歴を記録します。しかし、更新量が多い、またはbinlog_expire_logs_secondsを適切に設定していない場合、ストレージを圧迫するリスクが高まります。

第165回 MySQLの圧縮の詳細ですでに触れられているように、MySQL 8.0.20からはバイナリログの圧縮機能が導入されました。今回はその機能に焦点を当てて解説します。使用するMySQLのバージョンは8.0.32です。

binlog_transaction_compressionについて

binlog_transaction_compressionを使用すると、バイナリログのトランザクションペイロードを圧縮して出力することができます。デフォルト設定ではこの機能はOFFになっていますが、SET SESSIONやGLOBALコマンドを用いて有効化することができます。

mysql> SHOW VARIABLES LIKE 'binlog_transaction_compression%';
+-------------------------------------------+-------+
| Variable_name                             | Value |
+-------------------------------------------+-------+
| binlog_transaction_compression            | OFF   |
| binlog_transaction_compression_level_zstd | 3     |
+-------------------------------------------+-------+
2 rows in set (0.02 sec)

mysql> SET GLOBAL binlog_transaction_compression = 1;
Query OK, 0 rows affected (0.00 sec)

binlog_transaction_compressionを有効にすると、トランザクションペイロードはbinlog_transaction_compression_level_zstdの設定に従い圧縮され、その後バイナリログファイルに書き込まれます。ただし、これはバイナリログファイルそのものを圧縮するものではありません。圧縮されたトランザクションペイロードが出力されたバイナリログは、レプリケーションやmysqlbinlogコマンドを使用して、以前と同様に利用できます。

さらに、この機能で圧縮されたトランザクションペイロードは、レプリケーション先でも圧縮されたままリレーログに書き込まれるため、レプリカ側のストレージ使用量も節約することができます。

mysqlbinlogを使用して出力したバイナリログを調べると、圧縮されたトランザクションペイロードはコメント部分に明記されており、その内容を確認することができます。

#231004  0:46:05 server id 39355  end_log_pos 557 CRC32 0xcea35168      Transaction_Payload             payload_size=206        compression_type=ZSTD   uncompressed_size=706
# Start of compressed events!
# at 557
...

COMMIT/*!*/;
# End of compressed events!

binlog_transaction_compression_level_zstd

binlog_transaction_compression_level_zstdは圧縮レベルを設定します。デフォルトでは3になっており、1~22の値で設定することができます。圧縮レベルが高い場合はデータの圧縮率が高くなり、トランザクションペイロードを圧縮する際によりストレージおよびネットワーク帯域幅を削減することができます。ただし、その分多くのCPUおよびメモリのリソースを利用することになります。

performance_schemaのbinary_log_transaction_compression_stats

performance_schemaにはbinary_log_transaction_compression_statsというテーブルが存在し、これを利用することでbinlogの圧縮前後のサイズや、その圧縮率を確認することができます。

mysql> SELECT * FROM binary_log_transaction_compression_stats\G
*************************** 1. row ***************************
                            LOG_TYPE: BINARY
                    COMPRESSION_TYPE: ZSTD
                 TRANSACTION_COUNTER: 217
            COMPRESSED_BYTES_COUNTER: 88750
          UNCOMPRESSED_BYTES_COUNTER: 119380
              COMPRESSION_PERCENTAGE: 26
                FIRST_TRANSACTION_ID: 7d2772a5-8987-11e8-a6a6-0201858272ab:711970
  FIRST_TRANSACTION_COMPRESSED_BYTES: 199
FIRST_TRANSACTION_UNCOMPRESSED_BYTES: 218
         FIRST_TRANSACTION_TIMESTAMP: 2023-10-04 00:18:48.577526
                 LAST_TRANSACTION_ID: 7d2772a5-8987-11e8-a6a6-0201858272ab:712195
   LAST_TRANSACTION_COMPRESSED_BYTES: 237
 LAST_TRANSACTION_UNCOMPRESSED_BYTES: 706
          LAST_TRANSACTION_TIMESTAMP: 2023-10-04 00:46:05.816707

検証

実際にmysqlslapを使用して、binlog_transaction_compressionが有効化された場合の圧縮効果を検証しました。以下のコマンドを利用して、binlog_transaction_compressionがONとOFFの状態でそれぞれ3回ずつ実行し、その平均を計測しました。binlog_transaction_compression_level_zstdはデフォルトの3を用いています。

time mysqlslap -h 127.0.0.1 -u root -p --auto-generate-sql --auto-generate-sql-add-autoincrement --number-int-cols=5  --number-char-cols=5  --iterations=10  --concurrency=1  --auto-generate-sql-write-number=1000

結果は以下の通りです。

binlog_transaction_compression binarylog file size exec time
OFF 17MB 16.605 sec
ON 9.4MB 17.56 sec

このワークロードの条件下でbinlog_transaction_compressionをONにすることで、binlogのファイルサイズが大幅に縮小されることが確認できます。また、実行時間はOFFの場合に比べてわずかに増加しています。

注意実際のワークロードの条件や状況は異なる可能性があるため、この結果が常に適用されるわけではありませんので注意してください。

注意すること

このオプションは非常に便利ですが、利用する際に考慮すべき点がいくつかあります。

CPUの負荷
binlogの圧縮や解凍にはCPUリソースが必要です。この設定を有効にした後、CPUの使用状況を確認して、過剰な負荷がかかっていないかをチェックしましょう。
ツールの対応状況
binlogを扱うツールを使用する場合、そのツールがbinlogの圧縮に対応しているかを事前に確認する必要があります。
ROWベースのバイナリロギング形式にのみ有効
binlog_transaction_compressionが適用されるのは、binlog_formatがROWベースの場合のみです。STATEMENTベースでbinlogを出力している場合、この設定は有効になりません。
mysqlbinlogのバージョン
mysqlbinlogコマンドでbinlogの内容を確認する際は、binlog圧縮に対応しているバージョンを使用する必要があります。MySQL Serverのバージョンに合わせてmysqlbinlogのバージョンも選択すれば、問題は生じません。

まとめ

binlog_transaction_compressionは、バイナリログのサイズを効果的に削減するための有力な手段として導入されました。この機能は、特にデータ変更が頻繁な大規模なデータベース環境でのストレージコストとネットワーク負荷を軽減するのに役立ちます。しかし、この機能を利用する際には、CPUのオーバーヘッドや互換性の問題に注意する必要があります。

利用する際は、公式ドキュメントのバイナリログトランザクション圧縮も確認のうえ、利用してみてください。

おすすめ記事

記事・ニュース一覧