41から始めました

文字通り41歳から始めたブログです。DB(MySQL)を使ってお仕事してるので、DB周りの話を中心に最近始めたこととかをTwitterのノリで書いています。なお、本サイトにおいて示されている見解は私個人の見解であり、所属団体や組織を代表するものではありません。

MySQL8.0.20で追加・変更されたパラメータを眺める

はじめに

MySQL8.0.20で追加・変更されたパラメータをなんとなく眺めてみました。

パラメータの説明については基本的にはドキュメントからの引用です。

変更されたパラメータ一覧

例によってとみたさんのパラメータ比較ツールをお借りしました。

Parameter 8.0.20 説明
binlog-transaction-compression FALSE バイナリログファイルに書き込まれるトランザクションの圧縮を有効にする
binlog-transaction_compression_level-zstd 3 バイナリログファイルの圧縮レベルを設定
innodb_doublewrite_batch_size 0 バッチで書き込むダブルライトバッファページの数
innodb_doublewrite_dir (No default value) ダブルライトバッファのファイルディレクト
innodb_doublewrite_files 0 ダブルライトファイルの数
innodb_doublewrite_pages 0 バッチ書き込みのスレッドあたりの二重書き込みページの最大数
mysqlx_deflate_default_compression_level 3 サーバが Xプロトコル接続で Deflate アルゴリズムに使用する既定の圧縮レベル
mysqlx_deflate_max_client_compression_level 5 サーバが X プロトコル接続上の Deflate アルゴリズムに対して許可する最大の圧縮レベル
mysqlx_lz4_default_compression_level 2 サーバが X プロトコル接続で LZ4 アルゴリズムに使用する既定の圧縮レベル
mysqlx_lz4_max_client_compression_level 8 サーバが X プロトコル接続上の LZ4 アルゴリズムに対して許可する最大の圧縮レベル
mysqlx_zstd_default_compression_level 3 X プロトコル接続でサーバーが zstd アルゴリズムに使用するデフォルトの圧縮レベル
mysqlx_zstd_max_client_compression_level 11 サーバが X プロトコル接続上の zstd アルゴリズムに対して許可する最大の圧縮レベル
performance_schema_error_size (number of server error codes) インスツルメント化されたサーバーエラーコードの数

バイナリログトランザクション圧縮

MySQL8.0.20からbinlogが圧縮できます。

これについてはけんつさんが検証してくれてますので、非常に参考になります。

パラメータについては以下の通り

binlog_transaction_compression

もしCPUはヒマしてるけど、大量にデータ更新してて、ネットワークがネックなMySQL環境があればONにして、次の圧縮レベルを調整すると良いかもしれませんね。

binlog_transaction_compression_level_zstd

  • このサーバのバイナリログトランザクション圧縮の圧縮レベルを設定します。
  • 値は、圧縮努力を決定する整数で、1 (最も低い) から 22 (最も高い) までの値を指定します。
  • このシステム変数を指定しない場合、圧縮レベルは3に設定されます。
  • 圧縮レベルが高くなると、データ圧縮率が高くなり、トランザクションペイロードに必要なストレージ・スペースとネットワーク帯域幅が削減されます。
  • しかし、データ圧縮に必要な労力も増加し、時間と発信元サーバのCPUおよびメモリリソースが必要となる。圧縮努力の増加は、データ圧縮率の増加と直線的な関係はありません。
  • このシステム変数は、トランザクションのコンテキスト内では変更できません。
  • このシステム変数のセッション値の設定は制限された操作です。
  • セッションユーザは、制限されたセッション変数を設定するのに十分な権限を持っていなければならない。
  • セクション5.1.9.1 「システム変数の特権」を参照してください。

けんつさんの記事から読むに、デフォルトの3でも半分くらいになるみたいなので、22とかどうなっちゃうの?とw

ダブルライトバッファの改良

  • 8.0.20以降、doublewriteバッファストレージ領域をInnoDBシステムテーブルスペースではなく、別途専用ファイルに分けることができるようになりました。
  • これにより書き込みレイテンシが減少するため、スループットを向上させることができ、ダブルライトバッファページの配置に関して柔軟性が提供されます。
  • 8.0.20では、ダブルライトバッファの構成用にパラメータが追加されました。

ドキュメントを読む限りはinnodb_doublewrite_dir以外はあまり変更する必要は無さそうですが、書き込み量やファイルサイズからデフォルト値だと…という場合に触ってみる可能性があるかも、でしょうか。

ダブルライトバッファについて

念のため、ダブルライトバッファについて軽く触れておくと、

  • InnoDBではデータファイル更新前にダブルライトバッファと呼ばれる領域(ファイル)にデータを書き込む。
  • マシンクラッシュでデータページが壊れていても、ダブルライトバッファからリカバリされる。
  • ダブルライトバッファが壊れていた場合は、そのデータは破棄。
  • ダブルライトバッファは連続した領域なので、書き込みのオーバーヘッドはデータファイルより少ない
    • とはいえ、書き込み量、利用領域が増えるので不要な場合は無効にできる

innodb_doublewrite_batch_size

  • バッチで書き込むダブルライトバッファページの数を定義します。
  • 基本的にはデフォルト値のままで問題ないはずですが、パフォーマンスチューニングしたい場合には調整するパラメータ。

innodb_doublewrite_dir

innodb_doublewrite_files

  • ダブルライトファイルの数を定義します。
  • デフォルトでは、バッファープールインスタンスごとに2つの二重書き込みファイルが作成されます。
  • 少なくとも、2つの二重書き込みファイルがあります。
  • doublewriteファイルの最大数は、バッファープールインスタンスの数の2倍です。(バッファー・プール・インスタンスの数はinnodb_buffer_pool_instances 変数によって制御されます。)
  • 二重書き込みファイル名の形式は次のとおりです 。
    • たとえば、次のdoublewriteファイルは、ページサイズが16KBで単一のバッファープールを持つMySQLインスタンス用に作成されたものです。
    • ib_page_size_file_number.dblwrInnoDB

#ib_16384_0.dblwr
#ib_16384_1.dblwr
  • 基本的にはデフォルト値のままで問題ないはずですが、パフォーマンスチューニングしたい場合には調整するパラメータ。

innodb_doublewrite_pages

  • バッチ書き込みのスレッドあたりの二重書き込みページの最大数を定義します。
  • 値が指定されていない場合は、innodb_doublewrite_pagesはinnodb_write_io_threadsの値に設定されます。
  • 基本的にはデフォルト値のままで問題ないはずですが、パフォーマンスチューニングしたい場合には調整するパラメータ。

Xプロトコル接続を介して送信されるメッセージの圧縮

MySQL 8.0.19以降、Xプロトコル接続を介して送信されるメッセージの圧縮がサポートされました。

サーバーとクライアントが使用する圧縮アルゴリズムに同意した場合、接続を圧縮でき、デフォルトでは、Deflate、LZ4、およびzstd圧縮アルゴリズムを許可します。

ところが、MySQL 8.0.19では、サーバー側で圧縮レベルがデフォルト設定化されていて、クライアントはこれを調整することができません。

それがMySQL 8.0.20以降、クライアントはXプロトコル接続のケイパビリティ ネゴシエーション(※)中に特定の圧縮レベルを要求できるようになったとのこと。

一方でアルゴリズムごとに最大圧縮レベルを設定できるようになっていて、サーバーが忙しい時に、クライアントが高圧縮レベルを要求しても、最大圧縮レベル以上の負荷をかけることを防ぎます。

ちなみに、この圧縮レベルの要求はMySQL Shell経由でのみ行われるため、現時点ではMySQLクライアントやその他のConnector系はサポートされていないようです。(20.5.5項 「X プラグインによる接続圧縮」より)

ちなみに、ケイパビリティ ネゴシエーション(capability negotiation)っていうのがよくわからんな、と思って調べたらドキュメントにありました。

ケイパビリティ ネゴシエーション(capability negotiation)

14.2.1.3 Capability Negotiation

要するに、サーバーとクライアントでやり取りするのに色んなもの使うし、使えますよ、と。(例えば、サーバーのバージョンや認証情報(認証方式)とか)

mysqlx_deflate_default_compression_level

  • サーバが X プロトコル接続で Deflate アルゴリズムに使用する既定の圧縮レベル。
  • レベルは、1 (最も低い圧縮率) から 9 (最も高い圧縮率) までの整数で指定。
  • このレベルは、クライアントがケイパビリティ ネゴシエーション中に圧縮レベルを要求しない場合に使用されます。
  • このシステム変数を指定しない場合、サーバーはレベル3を既定値として使用します。
  • 詳細については、20.5.5項 「X プラグインによる接続圧縮」を参照してください。

mysqlx_deflate_max_client_compression_level

  • サーバが X プロトコル接続上の Deflate アルゴリズムに対して許可する最大の圧縮レベル。
  • 範囲は、このアルゴリズムの既定の圧縮レベルと同じ(1から9)です。
  • クライアントがこれより高い圧縮レベルを要求した場合、サーバはここで設定したレベルを使用します。
  • このシステム変数を指定しない場合、サーバは最大圧縮レベルを 5 に設定します。

Deflateとは

Deflate(デフレート)とはLZ77とハフマン符号化を組み合わせた可逆データ圧縮アルゴリズム。フィル・カッツが開発した圧縮ツールPKZIPのバージョン2で使われていた。ZIPやgzipなどで使われている。1996年5月に RFC 1951 としてドキュメント化された。ヘッダーやフッターをつけた zlib (RFC 1950) 形式や gzip (RFC 1952) 形式とともに使われる事が多い。 Deflateアルゴリズムが利用されているソフトウェアの一例を挙げる。

zlib ZIP GZIP 7z Portable Network Graphics (PNG) また、ほとんどのプログラミング言語で利用できる。以下はその一例。

Java - Deflater クラスで nowrap を有効にすることにより素の deflate が扱え、別途 zlib 形式や gzip 形式のヘッターやフッターの付いた物も扱える。 Perl PHP Python Ruby C#、VB.NET等の.NET Framework 2.0以降対応言語 - DeflateStream クラスで素の deflate もしくは GZipStream クラスで gzip 形式。 Apache HTTP ServerなどのWebサーバでも圧縮通信を zlib 形式で Deflate を使って実装している。 (Wikipediaより)

というわけで普段からよくお世話になってる可逆圧縮方式のあいつらはDeflateだったわけでした。

mysqlx_lz4_default_compression_level

  • サーバが X プロトコル接続で LZ4 アルゴリズムに使用する既定の圧縮レベル。
  • レベルは、0 (最も低い圧縮率) から 16 (最も高い圧縮率) までの整数で指定します。
  • このレベルは、クライアントがケイパビリティ ネゴシエーション中に圧縮レベルを要求しない場合に使用されます。
  • このシステム変数を指定しない場合、サーバーはレベル2を既定値として使用します。
  • 詳細については、20.5.5項 「X プラグインによる接続圧縮」を参照してください。

LZ4とは

LZ4 は圧縮と展開の速さに焦点を当てた可逆圧縮アルゴリズムである。バイト指向の圧縮方法であるLZ77ファミリーに属する。 (Wikipediaより)

mysqlx_lz4_max_client_compression_level

  • サーバが X プロトコル接続上の LZ4 アルゴリズムに対して許可する最大の圧縮レベル。
  • 範囲は、このアルゴリズムの既定の圧縮レベルと同じです。
  • クライアントがこれより高い圧縮レベルを要求した場合、サーバはここで設定したレベルを使用します。
  • このシステム変数を指定しない場合、サーバは最大圧縮レベルを 8 に設定します。

mysqlx_zstd_default_compression_level

  • Xプロトコル接続でサーバーが zstd アルゴリズムに使用するデフォルトの圧縮レベル。
  • 1.4.0 以降の zstd ライブラリのバージョンでは、1 から 22 までの正の値 (最高の圧縮率)、または負の値 (圧縮率が徐々に低くなることを表す) を設定できます。
  • 0 の値は 1 の値に変換されます。
  • zstd ライブラリの以前のバージョンでは、3 の値しか指定できません。
  • このレベルは、ケイパビリティ・ネゴシエーション中にクライアントが圧縮レベルを要求しない場合に使用されます。
  • このシステム変数を指定しない場合、サーバーはレベル3をデフォルトとして使用します。
  • 詳細については、20.5.5項 「X プラグインによる接続圧縮」を参照してください。

Zstandard (Zstd)

Zstandard (Zstd) は、2015年からFacebookに所属しているYann Colletによって開発された可逆圧縮アルゴリズムである。またCで書かれた前述のアルゴリズムのリファレンス実装の名前でもある。 Zstandardは現在主流であるDeflate (ZIP, gzip) アルゴリズムによるものと遜色ない圧縮を、より高速に行えるように設計されている。 Zstandardは大きな検索窓の辞書式圧縮アルゴリズム (LZ77) とエントロピー符号化を併用しており、エントロピー符号化ステージで有限状態エントロピー(FSE)のtANS(英語版) あるいはハフマン符号化を使用している。Zstandardの実装で特徴的なのはエントロピー復号化時に逆方向から読み取ることである。 (Wikipediaより)

mysqlx_zstd_max_client_compression_level

  • サーバが X プロトコル接続上の zstd アルゴリズムに対して許可する最大の圧縮レベル。
  • 範囲は、このアルゴリズムの既定の圧縮レベルと同じです。
  • クライアントがこれより高い圧縮レベルを要求した場合、サーバはここで設定したレベルを使用します。
  • このシステム変数を指定しない場合、サーバは最大圧縮レベルを 11 に設定します。

performance_schema_error_size

  • インスツルメント化されたサーバーエラーコードの数。
  • デフォルト値はサーバーエラーコードの実際の数なので、サーバーエラーコードが増えたことで変更となりました。
  • 値は0から最大値まで設定できますが、使用目的は、デフォルト(すべてのエラーを計測する)または0(エラーなしを計測する)に設定することです。
  • エラー情報は要約テーブルに集約されます。セクション26.12.18.11「エラーサマリーテーブル」を参照してください。

まとめ

  • MySQL8.0.20では圧縮形の機能追加が二つあったことがパラメータから見て取れました。
    • binlogの圧縮はZstdのみ。
    • Xプロトコルの圧縮はDeflate、LZ4、Zstdの三つの圧縮レベルのデフォルト値と最大値がパラメータとして追加
      • クライアントが要求した圧縮レベル>サーバーのmax値だったときはサーバのmax値のほうが使われる
      • Xプロトコルの圧縮はMySQL Shell専用なので注意
    • 圧縮形はCPU使用率が上がり、CPU使用率+圧縮時間とネットワーク転送時間とのトレードオフとなります。
  • ダブルライトバッファ系パラメータはinnodb_doublewrite_dir以外はあまり変更する必要は無さそうです。
    • innodb_doublewrite_dirを高速なディスクに設定すると良さそうです。

さいごに

  • 和訳部分についてはドキュメントをDeepLやGoogle翻訳を使って訳したものを一部引用してます。
  • 日本語がおかしい部分は自分で訳しましたが、合ってなかったらごめんなさい。