2020年12月31日木曜日

MySQL 8.0 の InnoDB の log_sys周り の話

思い出せるうちに思い出せる範囲で…

例によって世に出る頃には全く違うことに取り組んでいるので、忙しくしてると何も書かずに終わってしまうのですが、こんなご時世、年末年始休暇があっても何も用事がなく折角なのですこし書き残します。本来は本家開発者のブログで英語で書くべきなんですが、込み入った話を英語で書く労力をかけるくらいなら次の問題解決にかけたほうがいいので、とりあえず日本語で書き残します…

私がMySQL界を離れている間にリリースされた8.0になってlog_sysのデザインが新しくなり、スケールが良くなったのですが、既存のハードを利用する大半のユーザーには、未だ荒かった実装のせいでデメリットの方が大きかったと思います。2019末くらいには悪い挙動と原因はある程度分かっていましたが、修正リリースは2020後半になってしまいました。

既存のスペックのハードウェアと、CPUコア多数搭載の最新ハードとでは、ベストの性能を出すために共通している部分も多いのですが、違う部分もどうしてもあります。8.0.22での log_sys の大半の修正は共通にできたのですが、writer_thread と flusher_thread の利用に関してだけは、どうしても利害が相反してしまったので仕方なくinnodb_log_writer_threads というオプションを導入せざるを得ませんでした。

CPUコア数が(死ぬほど)多いとCPUコアが余ったり各コアのCPU使用率に余裕があったりするわけで、
CPUコアや使用率を無駄にしてでも余ったCPUコアに仕事を振ってスケールを上げる
というのが目先のベストの戦略かと思います。しかし、CPUコア数の余剰分が無い(まぁ、普通予算が余らなければオーバースペックなCPUにはしないので普通無い)場合はCPUは十分使い切れるので、その戦略で設計されたソフトウェアは「只遅いだけ」のものとなります。

というわけで、共通部分のCPU無駄食いは直したのですが、writer_thread と flusher_thread については「高スペックで必要」、「低スペックでは邪魔」なので、innodb_log_writer_threads オプションがあります。

問題はCPUリソースなので、IOがボトルネックの場合にはON/OFFで差は出ないと思いますが、
全体でのCPU使用率が高い(つまり、全CPUが元々ちゃんと働いている。又は他のコンポーネントと相乗り)場合に、
innodb_log_writer_threads はOFFにしたほうが良いでしょう。

実は、innodb_log_writer_threads 以外で修正した部分の方が影響は大きいので、基本8.0.22にしさえすれば更新系の性能問題は減ると思います。

細かい話では、
logのflushとcheckpointの頻度が環境のスペックが高いほど激増してたのですが、(writeも増えるが、InnoDBでlogのwriteは必ずOSのIOレイヤーでバッファリングされるので問題はない。 というか細かく書き出したほうが下位レイヤーでの最適化が働く余地があるのでいいこともあるらしい。)flushとchoekpointを5.7相当のストラテジーに戻した。
ということや、あとは、
8.0では5.7とは違ってlog_bufferへの書き込みは常に並列化されているので(innodb_log_writer_threads=OFFでも常に)、その書き込みがどこまで連続で終了しているか(最初の未書き込み手前までしかwriteできない)確認していく別スレッド(closer_thread)も存在したのですが、高スペックハードでもCPU無駄食いが酷かったので工夫して廃止しています。

まぁ、性能ギリギリで利用している人は居ないのでだれも気づかないのでしょうかね。
とにかくこれで、log_sys は当面直す箇所は無いと思います。

以前も log_sys の書き込み量が8.0で増えていたのを調査して直したこともありますが(8.0.20)、そもそもユーザーは誰も気づいていなかったようで直しても性能に関する反響は聞きません。
(InnoDBのログの32ビット整数表現は、上位ビットが0で埋まっているほど少ないバイト数で収まります。UNDO spaceのIDは5.7では1バイト表現できたのが、8.0になってマイナス表現側のIDを使うようになったので、UNDO space IDが4バイトになってしまってログの量が結構増えてたので、フォーマットを拡張して、マイナス表現側も2バイト程度には収まるように拡張しました。UNDO space ID自体は同じ長さまで戻ったわけではないですが、全体としてログのバイト数は5.7程度に戻ったと思います。)

自分で探して自分で直すのみですね。

なにはともあれ、念願のlog_sys修正が一段落したので次にすすめるわけです。(まだ、8.0新機能やInnoDB以外の8.0更新部分との相性が悪い部分はあるかも知れないですが)

何故「念願」だったかというと。。。。
前述の「CPU無駄食いスケール優先」は単純な性能の問題だけではなく、「他の性能劣化を隠してしまう」特性もあるからです。リソース消費と性能がちゃんと比例していないモッサリとした特性だと、裏でシングルスレッド性能劣化し放題だからです。

というわけで次の話題もあるのですが、ここまで。

次の話題は、リリースまでソースコード修正の話は書けないのですが、一般技術論は書いてもいいような気もするのだけれども、それが核心だから…さてどうしましょうかね。

0 件のコメント:

コメントを投稿