Recommended
PDF
MySQL 5.7にやられないためにおぼえておいてほしいこと
PDF
アーキテクチャから理解するPostgreSQLのレプリケーション
PDF
PDF
PPTX
PostgreSQLクエリ実行の基礎知識 ~Explainを読み解こう~
PPTX
CEDEC2019 大規模モバイルゲーム運用におけるマスタデータ管理事例
PDF
PDF
PPTX
iostat await svctm の 見かた、考え方
PDF
binary log と 2PC と Group Commit
PPTX
オンライン物理バックアップの排他モードと非排他モードについて ~PostgreSQLバージョン15対応版~(第34回PostgreSQLアンカンファレンス...
PDF
PDF
PDF
Apache Kafka 0.11 の Exactly Once Semantics
PDF
PDF
PostgreSQLの運用・監視にまつわるエトセトラ
PDF
PDF
YugabyteDBを使ってみよう - part2 -(NewSQL/分散SQLデータベースよろず勉強会 #2 発表資料)
PDF
ネットワーク ゲームにおけるTCPとUDPの使い分け
PPTX
PPTX
PDF
YugabyteDBを使ってみよう(NewSQL/分散SQLデータベースよろず勉強会 #1 発表資料)
PDF
PostgreSQLのリカバリ超入門(もしくはWAL、CHECKPOINT、オンラインバックアップの仕組み)
PDF
PDF
PDF
トランザクション処理可能な分散DB 「YugabyteDB」入門(Open Source Conference 2022 Online/Fukuoka 発...
PPTX
BuildKitによる高速でセキュアなイメージビルド
PDF
At least onceってぶっちゃけ問題の先送りだったよね #kafkajp
PDF
PPTX
More Related Content
PDF
MySQL 5.7にやられないためにおぼえておいてほしいこと
PDF
アーキテクチャから理解するPostgreSQLのレプリケーション
PDF
PDF
PPTX
PostgreSQLクエリ実行の基礎知識 ~Explainを読み解こう~
PPTX
CEDEC2019 大規模モバイルゲーム運用におけるマスタデータ管理事例
PDF
PDF
What's hot
PPTX
iostat await svctm の 見かた、考え方
PDF
binary log と 2PC と Group Commit
PPTX
オンライン物理バックアップの排他モードと非排他モードについて ~PostgreSQLバージョン15対応版~(第34回PostgreSQLアンカンファレンス...
PDF
PDF
PDF
Apache Kafka 0.11 の Exactly Once Semantics
PDF
PDF
PostgreSQLの運用・監視にまつわるエトセトラ
PDF
PDF
YugabyteDBを使ってみよう - part2 -(NewSQL/分散SQLデータベースよろず勉強会 #2 発表資料)
PDF
ネットワーク ゲームにおけるTCPとUDPの使い分け
PPTX
PPTX
PDF
YugabyteDBを使ってみよう(NewSQL/分散SQLデータベースよろず勉強会 #1 発表資料)
PDF
PostgreSQLのリカバリ超入門(もしくはWAL、CHECKPOINT、オンラインバックアップの仕組み)
PDF
PDF
PDF
トランザクション処理可能な分散DB 「YugabyteDB」入門(Open Source Conference 2022 Online/Fukuoka 発...
PPTX
BuildKitによる高速でセキュアなイメージビルド
PDF
At least onceってぶっちゃけ問題の先送りだったよね #kafkajp
Similar to さいきんの InnoDB Adaptive Flushing (仮)
PDF
PPTX
PDF
Innodb Deep Talk #2 でお話したスライド
PDF
MySQL 5.5 Update #denatech
PDF
サバフェス上位入賞者にみる ioMemory×MySQL 最新チューニング教えます
PDF
PDF
Percona ServerをMySQL 5.6と5.7用に作るエンジニアリング(そしてMongoDBのヒント)
PDF
PDF
PDF
PDF
PDF
ODP
MySQl 5.6新機能解説@第一回 中国地方DB勉強会
PDF
[D37]MySQLの真のイノベーションはこれだ!MySQL 5.7と「実験室」 by Ryusuke Kajiyama
PDF
MySQL Cluster 新機能解説 7.5 and beyond
PDF
B-Treeのアーキテクチャ解説 (第49回PostgreSQLアンカンファレンス@東京 発表資料)
PPTX
PDF
各スペシャリストがお届け!データベース最新情報セミナー -PostgreSQL10-
PDF
MySQL5.7 GA の Multi-threaded slave
PDF
More from Takanori Sejima
PDF
NAND Flash から InnoDB にかけての話(仮)
PDF
PDF
PDF
PDF
PDF
PDF
PDF
PDF
さいきんの InnoDB Adaptive Flushing (仮) 1. 2. 3. 4. 今日のお題
- MySQL 5.7 に至るまでの InnoDB Adaptive
Flushing を振り返りつつ
- InnoDB Adaptive Flushing によって発生する
書き込み処理について整理して
- うまいこと書き込み処理を最適化できないか考
えます
4
5. 6. 7. InnoDB Adaptive Flushing とは
- MySQL5.1の時代に、InnoDB Plugin 1.0.4 で
追加されました。
- 5.5 でInnoDB本体に組み込まれ、5.6 、5.7でさ
らに良くなりました。
- ただ、公式ドキュメントで解説しきれてない部分
もあると思うので、そのあたりを振り返ってみま
す
7
8. 9. InnoDBの基本的なファイル群
- ibdata1
- internal data dictionary, undo log, change buffer,
double write buffer などが含まれます(今回は紙幅の都
合でそのあたり割愛します)
- ib_log_file*
- transaction log・・・REDO Logs(Write Ahead Log)
- *.ibd
- table space・・・table の data や index
9
10. ざっくりいうと、 InnoDB は
- Transaction で発生したデータの更新は
ib_log_file* に溜め込んで
- 裏でチマチマ *.ibd に flush
- ib_log_file* は固定長の(InnoDB起動時にサイ
ズが決まる)ログなので、使い切ると、
Transaction の更新内容をログに書けなくなり
ます。そうならないよう、裏で *.ibd に反映してい
るわけです 10
11. REDO Logs(Write Ahead Log)
- 更新内容は先ず log に書いて、 table space に
は裏でゆっくり反映
- WALはMySQL以外のRDBMS でも用いられる手法
- log への書き込みは sequential write になるの
で、HDDみたいな random I/O 遅い block
device でもそれなりに速い
- table space に反映するとき、更新処理をまとめ
ることもできる。 (write combining) 11
12. Log Sequence Number(LSN)
- transaction log(ib_log_file*) のサイズは
InnoDB の起動時に innodb_log_file_size で
指定して決める(固定長)
- transaction log は ring buffer というか cyclic
というか circular fashion
- InnoDB が transaction log を初期化して以降、
log の buffer に書いてきたバイト数が Log
Sequence Number。 12
13. Last checkpoint at
- buffer pool 上にある更新内容を、LSN 的に
*.ibd にどこまで反映したか示すものが Last
checkpoint at。
- SHOW ENGINE INNODB STATUS で見える
やつ
- 可能であれば、 (LSN - Last checkpoint at) は監視項
目に加えておくのがオススメ
- 実はかなり重要な情報です
13
14. oldest_modification
- ibdata1 や *.ibd は、page (default 16KB)という単位で管
理されており
- page の構造体には、 oldest_modification というメンバ変
数がある
- その page が dirty になった最初のイベントが書かれている
log の position(LSN) 、それが oldest_modification
- dirty page をflushしてdiskに同期させると、その page の
oldest_modification は 0 でリセット
14
15. write combining
- I/O が page 単位なので、同一の page への更
新は、まとめて disk に flush できる。
- 同一の page に格納されている複数の row
への更新を、一回で disk に書けることも
- log に溜めこみ、まとめて flush できるとお得
- Last checkpoint at の進み方と disk I/O は、必
ずしも比例しない。
15
16. 17. InnoDB Adaptive Flushing の必要性
- log は有限なので使いきってはいけない
- 具体的に言うと、(LSN - Last checkpoint at) が
75%くらいになると、強制的に dirty page の
flush 走る。そうなると刺さりがち。
- 75%というのは定数ではなく、 log/log0log.cc の
log_calc_max_ages() で計算してる
- なるべく強制 flush 走らないよう、 adaptive に
flushing する機能が必要だったのです
17
18. InnoDB Adaptive Flushing ない時代
- InnoDB Adaptive Flushing がない時代、(具体
的には InnoDB Plugin 1.0.4 より前の時代)い
ずれかの状況にならないと flush されにくかった
- buffer pool 上で dirty page の比率が
innodb_max_dirty_pages_pct(昔はdefault90、いまは
default 75)を超える
- REDO Logs の使用率が約75%超える
18
19. 原初の InnoDB Adaptive Flushing
- 5.1や5.5 の InnoDB Adaptive flushing は、
master_thread という background で動いてる
thread が、 innodb_io_capacity に応じて 他の
タスクの合間に flush してた
- むかしの master_thread は、単一の thread で複数の
background task を goto でこなしていた。
- InnoDB がどういう task を background でやってるかわ
かりやすいので、一度、 5.5 の master_thread 読んで
みるのオススメです。 19
20. 5.5以前の innodb_io_capacity
- io_capacity は正確にいうと iops ではない
- master thread が一秒間にどれくらい page の
I/O してもいいか、という値
- (SELECT が多いなどで) disk read が多いと
きは、 dirty page の flush を加減してた
- 例えば、ピークタイムに dirty page をあまり flush しない
ことがあったとしたら、それは read が多いことが原因
だったりした
20
21. - 5.5 以前の InnoDB Adaptive Flushing は、
innodb_io_capacity の範囲内で flush してた
ので
- 高速な block device だからといって
innodb_io_capacity 上げすぎると、 write combining
が効かない
- REDO Logs を溜めずにつどつどflushしてしまう
21
22. 23. 5.6以降の InnoDB Adaptive Flushing
- で、5.6 や5.7でかなり良くなったんですが
- MySQL Performance Architect のDimitriK の
資料 から図を拝借すると、現状こうです
23
24. 25. 26. 5.6 以降で何が変わったのか・その一
- 公式ドキュメントとソースコードの乖離が激しく
なった
- ただ、先日久々に https://dev.mysql.com/ みたら、だい
ぶ充実してきているように見えました
- 最近は https://github.com/mysql/mysql-server でも
change log が読めるし、change log から対応する
WorkLog を辿りやすくなった
- WorkLog にコードの修正方針などがまとめられている
ので、とても調査しやすい OSS ですね
26
27. 5.6 以降で何が変わったのか・その二
- back ground thread の種類が劇的に増えた
- 5.5以前だと master_thread でこなしていたタスクが複
数の thread で分散
- 特定のタスク(purge や dirty page の flush など)が重
い場合、他のタスクがそれに引っ張られてしまう場合が
あったが、それが軽減された
27
28. 5.6 以降で何が変わったのか・その三
- 関連する parameter 増えた&意味変わった
- 重要なのはこのあたり
- innodb_adaptive_flushing_lwm(lwmは low water
mark の略)
- innodb_io_capacity
- innodb_io_capacity_max
- innodb_max_dirty_pages_pct_lwm
- innodb_lru_scan_depth
28
29. page cleaner thread
- MySQL5.5までは、 InnoDB で master thread
と呼ばれる thread が色々やってた
- dirty page の flush
- change buffering
- purge
- 5.6 でこれらの機能が複数の thread に分割
- 5.6 で追加された thread の一つが page
cleaner thread
29
30. flush list と LRU list
- buffer pool 上の page は、昔から二種類の list
で管理されている
- flush list は更新された順(oldest_modification
順)に dirty page を管理
- LRU list は、すべての page を対象に、参照さ
れた順に管理
- 5.6 以降では page cleaner thread がこれらに
対して back ground でタスクをこなす 30
31. 5.5以前の LRU list
- 5.5 以前で LRU list が参照されるケースの一
つは、 buffer pool の page があふれたとき
- disk 上のデータを読み込むとき、空き page なかった
ら、最も参照されていない page を破棄する。
- もし、その page が dirty だったら、 disk に flush してか
ら破棄
- foreground の thread は flush 終わるまで待たされる
- flush 終わって page を破棄するまで、 disk から
データが読めない
31
32. page cleaner thread のタスク・その一
- 5.5以前は buffer pool をぜんぶ使い切る仕様
だったが、 5.6 からは innodb_lru_scan_depth
で指定されただけ、 予め buffer pool の free
page を確保しておくようになった
- 関数的には
- MySQL5.6 では buf_flush_LRU_tail()
32
33. buf_flush_LRU_tail()
- page cleaner thread は一定間隔でLRU listを
参照し、 innodb_lru_scan_depth で指定され
ただけ free page を確保しようとする。その際、
参照されてない page から破棄する。
- page を破棄する際、 その page が dirty であ
れば disk に flush する。複数あればまとめて
flush する
33
34. - 常時 free page 確保してあるので、他の thread
は free page 確保するために dirty page の
flush を待たなくて良くなった
- innodb_lru_scan_depth は、 free page 枯渇し
ないなら、そんなに上げなくてもよいのでは?
- buffer pool の miss hit が多くて free page 減りがちな
ら、増やすことを検討してもよいかも
34
35. 36. page cleaner thread のタスク・その二
- flush list を見て dirty page を flush する
- 5.6でここのアルゴリズムが賢くなった
- 関数的には
- MySQL5.6 だと
page_cleaner_flush_pages_if_needed()
36
37. page_cleaner_flush_pages_if_needed()
- MySQL 5.6から、 一秒間に flush する page
の数を REDO Logs の使用率に合わせてコント
ロールするようになった
- REDO Logs の使用率が
innodb_adaptive_flushing_lwm を超えない限りは積極
的に flush しない
- innodb_io_capacity_max 重要
- REDO Logs の使用率が(とてもざっくり) 60% くらいに
なると io_capacity_max で指定しただけ flush 37
38. - REDO Logs の使用率に比例して flush が激し
くなる == innodb_io_capacity_max に近づくの
で、書き込みの多いサーバに高性能な block
device を割り当てると、 default の設定でもそこ
そこ flush するようになった
- 逆に、書き込みの少ないDBだと、 REDO Logs の使用
率低いので、 dirty page はちょっとずつしか flush され
ない。安価なハードウェアでもそこそこ動く
38
39. (これは私見ですが)
- 設計を見る限り、 5.5 以前の InnoDB Adaptive
Flushing は、 HDD のような低速な block
device をメインターゲットにしてたのでは?
- 新しい高性能なハードウェアを活かすために
は、新しい MySQL へ移行していくのが無難。
39
40. 41. 42. 43. 44. しかし5.6の page cleaner は未完成
- page_cleaner: aggressive background
flushing というバグレポートがあります
- idle 気味なとき、 innodb_io_capacity(maxで
はない)全開まで flush してしまうケースがあり
える
- もしこれが困るなら、 innodb_io_capacity 下げ
ても良いのではないかと
44
45. 46. MySQL 5.7 での大きな変更点
- 5.7から、 flush する page の数を決めるとき、 REDO logs の使用率以
外も考慮するようになった。詳しくは こちらのWorkLog に
- 改善点はいくつかあるのだが、 InnoDB Adaptive Flushing 的にポイン
トは二つ。
- REDO Logs の使用率だけではなく、更新頻度も考慮
- もう一つは、buffer pool instance ごとの dirty page の偏りを考慮
- 関数的には、 5.6の page_cleaner_flush_pages_if_needed() が大幅
にリファクタリングされ、5.7では
page_cleaner_flush_pages_recommendation() になった
46
47. page_cleaner_flush_pages_recommendation()
47
- REDO Logs の使用率だけではなく、更新頻度も考慮。
- 「高頻度で REDO Logs に書いてるんだけど、 REDO Logs の使
用率が低いので innodb_io_capacity_max で指定しただけ flush
してくれない」という事態が回避できるようになる。
- REDO Logs の使用率が約75% くらいになると強制的に dirty
page が flush されるので、「REDO Logs 使い切りそうなペースで
更新されてるならば、innodb_io_capacity_max で指定されてるま
で flush して、 log 使い切るのを防ごう」という理由かな?
48. page_cleaner_flush_pages_recommendation()
- buffer pool instance ごとの dirty page の偏りを考慮。
- InnoDB の buffer pool は複数の instance に分割できるのだが、 5.7 か
ら、古い dirty page の多い instance は flush を多く、少ない instance は
flush を少なくするようになった。5.6以前は instance ごとに dirty page の
偏りができていた可能性があったけど、改善された。
- 5.6 は 複数の buffer pool instance があった場合、必ずしも「より古い
dirty page を flush する」という挙動になるとは限らなかった。「instance ご
とに dirty page を N page ずつ flush する」という挙動になっていた。5.7
から、「古い dirty page をたくさん持ってる buffer pool instance はたくさん
dirty page をflushする」という挙動になったので、 write combining 的に有
利なはず。
48
49. さらに MySQL5.7 では
- page cleaner thread が複数スレッドに対応し
た。
- buffer pool instance が複数あれば、最大で instance
の数だけ page cleaner thread が並列して flush できる
- innodb_page_cleaners というパラメータで、
dirty page を flush するスレッドの数をコント
ロールできる。
49
50. とりあえず、 5.6 以降では
- 5.5 以前から 5.6 に移行するだけで、 InnoDB
Adaptive Flushing が賢くなる
- 5.7 ならより賢い
- 高速な block device 使ってるなら、MySQLの
バージョン新しくした方がよい
- InnoDB Adaptive Flushing が賢くなってるので、
MySQLのバージョン新しくするだけで、 dirty page の
flush 周りが改善する
50
51. InnoDB Adaptive Flushing の勘所
- 使い方にあわせてチューニングできるパラメー
タが、たくさんあるのですが
- 基本はやはり、 innodb_log_file_size ですね。
必要なら、 innodb_log_file_size は GB単位で
指定してよいのでは。
- あとはinnodb_io_capacity_max ですかね。
51
52. まずは innodb_log_file_size
- REDO Logs を使い切ると、強制的に dirty
page が flush されまくって重いので、ピークタイ
ムに枯渇しない程度は欲しい
- ただ、REDO Logs 多すぎるとクラッシュリカバ
リに時間が掛かるし、ファイルシステムのキャッ
シュ(Linuxだとpage cache)にメモリをたくさん
使われてしまう
52
53. ピークタイムの REDO Logs の使用率
- (個人的見解ですが)ピークタイムでも使用率
は、 50~60% 以下でよいのでは?
- (LSN - Last checkpoint at) が REDO Logs の総量の
75% くらいまで行くと、 Transaction がブロックされる可
能性が出てくる。(5.6以降は)使用率60% くらいになる
と、 innodb_io_capacity_max まで flush するケースが
ある。余裕残してもよいのでは
- REDO Logs の残量を適度に残せるようチュー
ニングするのがオススメ。 53
54. 5.6 の方が 75% くらいになりやすい?
- 5.6 は REDO Logs の使用率が 60% くらいに
なるまで、 io_capacity_max まで flush しにく
かったので、 REDO Logs の使用率が 75% く
らいになりやすかったのでは?
- 5.7 は更新頻度高ければ、使用率低くても
innodb_io_capacity_max まで flush するの
で、 REDO Logs のサイズが 5.6 より少なくて
も、使用率上がりにくいのでは。 54
55. 5.7 と innodb_io_capacity_max
- 5.7 は REDO logs の使用率だけでなく、更新
頻度もみて dirty page をいくら flush するか決
める。故に、REDO logs の使用率低くても、
innodb_io_capacity_max まで flush する可能
性がある。上げすぎない方がよい
- ただ、innodb_flushing_avg_loops であるてい
ど調整可能。
55
56. innodb_flushing_avg_loops
- REDO logs の更新頻度も見て flush の頻度を
決めるのだが、(ざっくりいうと)そのサンプリン
グ周期は、innodb_flushing_avg_loops で調整
可能
- innodb_flushing_avg_loops をうんと大きくすれば、一
瞬だけ更新がバーストするDBでも、
innodb_io_capacity_max まで flush しにくいはず
56
57. 58. 59. おまけ
- 次期メジャーバージョンの MySQL 8.0でも、
InnoDB はいろいろ改善されるのですが
- Facebook からの feature request や、
Percona の patch が取り込まれるようです。
- 今後も引き続き InnoDB が進化していくのは、
ありがたい限りですね。
59
60. まとめ
- 最近の InnoDB Adaptive Flushing はかなり
賢いです。オススメです。
- 最近のハードウェア使ってる人は、少なくとも5.6以降、
できれば5.7を使うのが良いでしょう。
- (LSN - Last checkpoint at) を意識しましょう
- 高性能なハードウェア使ってるなら
innodb_io_capacity_max 上げてもOKですが、上げす
ぎないよう注意しましょう。特に 5.7 では気をつけましょ
う。
60
61. 参考
- Configuring InnoDB for MySQL 5.6:
innodb_io_capacity, innodb_lru_scan_depth
- MySQL 5.6: IO-bound, update-only
workloads
- InnoDB adaptive flushing in MySQL 5.6:
checkpoint age and io capacity
- InnoDB Deep Talk #2 (仮) に引っ張りだされま
した。 61
62.