地方エンジニアの学習日記

興味ある技術の雑なメモだったりを書いてくブログ。たまに日記とガジェット紹介。

【MySQL】RDSのアップデートで書き込みスループットが2倍になるケースを考えてみる

帰宅前に以下の記事を読んですごい!となったがジムのランニングマシン使用中に「2倍ってどうやったら行くん?」ってなったので調べた。

dev.classmethod.jp

という機能がリリースされていた。中身自体はMySQLのDoublewrite Bufferの機能をオフにするというもの。Doublewrite Bufferを軽くふりかえるとシステムテーブルスペースに含まれる領域の一つで、バッファープールの内容が書き込まれます。バッファーと言いつつもメモリではなくディスクへの書き込みです。瞬断等により中途半端にデータが書き込まれた状態になった際にredoログから復元するかDoublewrite Bufferから修復するかという処理をするために用いられます。詳しくは公式を参照してください。(ZFSとかファイルシステムでアトミックな書き込みを保証されているのであれば実はすでにオフで運用しているケースも多くありそう)

dev.mysql.com

ここでアップデートの記事を見てみると以下のような記述があります。Doublewrite Bufferを用いた書き込みは最大2倍の時間がかかると述べられている。ここでのポイントはDoublewrite Bufferはシーケンシャルの追記で書き込みが行われる。.ibdへはランダムWriteになるという点。仮に前者のシーケンシャルIOをなくした所で2倍にはならんのでは?と思ったのだった。

But this method of writing takes up to twice as long, consumes twice as much I/O bandwidth, and reduces the throughput and performance of your database.

Doublewrite Bufferのパフォーマンスへの影響

載せれるデータが無かったが前にオンオフで大量Writeをしたときはだいたい10%も早くならなかった。というのも公式ドキュメントでもデータは 2 回書き込まれますが、二重書込みバッファには I/O オーバーヘッドの 2 倍や I/O 操作の 2 倍は必要ありません。と書かれている。ダーティ ページからの Doublewrite bufferのfsync(2)とDoublewrite bufferの内容をfsync(2)する際は前者はシーケンシャルIOで後者はランダムIOであるためだと思われる。

innodb_page_cleanersで指定されたスレッドはinnodb_doublewrite_pagesで指定された数だけDoublewrite Bufferへ書き込みます。このへんはバックグラウンドスレッドでやるのでIOPSの制御innodb_io_capacityやinnodb_io_capacity_maxあたりも効いてきます。バックグラウンドに潤沢にリソースを渡しているケースであればこの辺はよさそうです。(書き込まれた回数とかはInnodb_dblwr_pages_writtenで確認することが出来る)

2倍になるケースはあるのか

www.percona.com

PerconaがDoublewrite Bufferのパフォーマンスへの影響について言及しているブログを見つけました。

In usual workloads the performance impact is low-5% or so. 

5%程度のパフォーマンス劣化はあるかもと言っています。

But if you experience a heavy workload, especially if your data does not fit in the buffer pool, the writes in the doublewrite buffer will compete against the random reads to access the disk. In this case, you can see a sharp performance drop compared to the same workload without the doublewrite buffer-a 30% performance degradation is not uncommon.

データがバッファー プールに収まらない場合はワークロードのランダムリードと競合してパフォーマンス劣化するかもとも言っています。なるほど。それでも30%程度の劣化だとも書かれています。innodb_io_capacityの設定が甘いケースだと起きうるかも知れない。(めちゃめちゃWriteした直後にバックグラウンドスレッドが大量IOPSで動いているタイミングでbuffer poolに乗っていない場合など?)

Another case when you can see a big performance impact is when the doublewrite buffer is full. Then new writes must wait until entries in the doublewrite buffer are freed.

最後はこれ。doublewrite bufferが満杯になるケース。buffer自体は128 ページ*16KB(ページサイズ)が確保されているのでここがあふれるケースとdirty pageが増えcheckpointが走る。実行中のトランザクションを一時停止/新規トランザクションの開始を抑制につながる。このケースでは確かにスループットが2倍近くになるかもしれない。

感想

どこかで実験してみたい!!