More Related Content Similar to Innodb Deep Talk #2 でお話したスライド (20) Innodb Deep Talk #2 でお話したスライド1. Copyright 2015 Scigineer Inc. All rights reserved.©
InnoDB Deep Talk #2 (仮)
石の上にも前回から三年 (仮)
サイジニア株式会社
木下 靖文
2015年3月7日
2. Copyright 2015 Scigineer Inc. All rights reserved.©
まずは自己紹介
前回#1(3年前)では、話さなくて良いことまで話しました。
その後InnoDBの中の人を3年やりました。
近年は次期バージョン5.7の性能スケーラビリティ改善を目的に色々し
ました。
⇒ 5.7が近い将来GAになって、使ったユーザーに喜ばれると想像。
⇒ 「俺も5.7つかいたい。ずるい。」 (想像)
⇒ 使う側に戻るの。
⇒ 折角だから新しいことに使いたいの。
⇒ MySQL導入検討中(前かも?)の新しい企業へ (ぇ)
2
5. 2006年
2006.8
Peter Zaitsev、Vadim Tkachenko が
MySQL AB(High Performance Group)離籍して
Percona 設立
※当時、S商情報システムのS原さんがMySQLの性能の将来を危惧していた。
※S原さんは日本に有力なハッカーが居ないことも当時危惧していたと思う。
(世界のMySQLコミュニティにおける日本ユーザーのプレゼンスが低くなってしまうから)
多少影響を受けた。
2006.8
Bug#15815: Very poor performance with multiple queries running concurrently
(http://www.mysqlperformanceblog.com/2006/07/28/returning-to-innodb-scalability/)
の議論に参加
※これがInnoDBハック人生のスタート
※buf_pool_mutex に最初に手を付け始めたのは Vadim
2006.11
MySQL-5.0.30
Bug#15815の修正 (block->mutex 使用)
※実はここで致命的なバグが混入している。
この時点では、「直った筈なのに思ったよりスケールしない」感
体感2個+αくらい
CPUスケーラビリティ↑
3年前の資料
5
6. 2007年前半
2007.2
Bug#26442: Adaptive Hash Index's CPU scalability is low.
アセンブラを利用したNativeなrw_lockの実装を提案
2007.4
MySQL Conference & Expo 2007
「InnoDB performance potential in high-end environments」
master thread 等の IO 量のチューニング
block->lock (#15815),
native rw_lock (#26442) に言及
「InnoDBは速くなる」
※某K.J氏 に会う。
その後、英語がダメダメなので雇えないと言われる。(>_<)
※Peter, Vadim とも面識を得る
2007.6
Bug#29413: Maximum performance of OLTP benchmark
is not so scalable on multi-cpu
・バックグラウンドスレッドからの各種IO量調整パラメータ
・rw_lock(#26442と同様の主旨)
・read_ahead の制御
3年前の資料
6
7. 2007年後半(1)
2007.7
Bug#29560: InnoDB >= 5.0.30 hangs on adaptive hash rw-lock
'waiting for an X-lock'
5.0.30で混入した、os_event(ロック待ち)がロック解放イベントを
取りこぼす問題を指摘して議論開始
2007.8
Bug#29413
・IOスレッドのスケーラビリティ修正
・free_list管理でmutex確保を最低限にする修正
・flush_lits_mutex、page_hash_latch、free_list_mutex
を buf_pool_mutex から分ける案
を追加提案
2007.9
Bug#29560(os_event)
某 斯波さんと某所で議論して解決 (Thanks 某 斯波さん)
3年前の資料
7
8. 2007年後半(2)
2007.9
MySQL Users Conference Japan 2007
「InnoDBがハードウェアを活かし切るために」
#29413 での提案について言及
「InnoDBはまだまだ速くなる」
2007.12
MySQL-5.0.54
史上最悪な致命的バグ #29560 が修正される
(※5.0.30〜5.0.53 は絶対に使っては行けないバージョン。念のため)
※CPUスケールが改善。8個くらいは行けたはず。
※これ以降、builtin InnoDB に対する性能改善は無い。(5.1.xも)
Pluginができて、それが5.5でデフォルトになって、GAになるまで
(2010.12 5.5.8)
#####################################################
詳しくない一般ユーザーには全く進歩が見えない冬の時代に突入。
#####################################################
CPUスケーラビリティ↑
3年前の資料
8
9. 2008年前半
Sun Microsystems、MySQL を買収
2008.1
Bug#26442(native rw_lock)
互換性対策として、GCC の atomic builtin を使う提案
2008.5
Bug#36681: Insufficient plans for huge tables
※直接InnoDBではないけれども、5.0 range optimizer の修正を提案
(最近確認してないけど直ったのだろうか?)
2008.6
某 松信さんに誘われるが、最終段階で、
もっと上の人に「今、組織再編で大変だから無理」と断られる。
3年前の資料
9
11. 2009年前半
2009.3
FaceBook の意向で XtraBackup を作らされる。
InnoDBのリカバリパスをそのまま利用
---> InnoDB のリカバリの性能問題が明るみに。
(もう既にあったBug#29847が再燃)
flush_listへの挿入がなんとバブルソート。。。。
いろいろな人が色々な意見を出したが。
ここでは、oldest_modification が小さい場合にリストの最大で上書きして
ソートしないやりかたで実装。
公式には red-black tree を使って
2010.4 plugin-1.0.7 で修正。
(builtin では直さず)
※ちなみにXtraBackupの名付け親はPeterZ
2009.4
Oracle Corp.、Sun買収を発表
2009.6
GoogleのMySQLチーム Mark Callaghan が FaceBook へ移籍
※お金も、手も、口も、世界で今一番出しているであろう、
FaceBookがいろんな意味で世界最強のMySQLユーザー化した瞬間です。
3年前の資料
11
12. 2009年後半(1)
2009.9
InnoDB Plugin 1.0.4 リリース
過去のbugs.mysql.comでの議論の成果が取り込まれている。
※これ以降、性能改善変更はPluginに対してだけは積極的に行われる
(e.g.) IO thread スケール (私の案)
native rw_lock (結局 MarkC の実装が採用された。)
※ここでユーザーが分岐
→マニアック plugin ベースで性能議論続行
→一般 builtin ベースで付いて行けずに停止
2009.10
XtraDB 1.0.4 リリース
パッチを整理してPluginに含まれてない物を当てた XtraDB を作成
性能改善提案はXtraDBに直接実装する形
※評判が良ければ、本家も受け入れざるを得ないはず。
2009.9
InnoDB-Plugin@MySQL-5.1.38
innodb_adaptive_flushing
innodb_read_ahead_threshold
CPUスケーラビリティ↑
(公式人柱向け)
3年前の資料
12
13. 2009年後半(2)
2009.11
OpenSQL Camp 2009
「XtraDB for Performance」
※InnoDBパフォーマンスパッチまとめ
innodb_split_buf_pool_mutex.patch
---> 2010.4: flush_list_mutex の切り出し (5.5.4)
---> 2011.4: (+α) rw_lock for page_hash (5.6.2?)
innodb_show_lock_name.patch
innodb_extra_rsegments
---> 2010.4: 128個固定 (5.5.4)
---> 2011.4: innodb_rollback_segments (5.5.11)
innodb_stats_method
---> 2011.3: innodb_stats_method (5.1.56, 5.5.10)
innodb_adaptive_checkpoint
---> 2009.9: (似) innodb_adaptive_flushing (Plugin-5.1.38)
innodb_use_purge_thread
---> 2010.4: innodb_purge_threads (5.5.4)
innodb_read_ahead (for SSD)
---> 2009.9: innodb_read_ahead_threshold (Plugin-5.1.38)
innodb_flush_neighbor_pages (for SSD)
---> 2011.10: innodb_flush_neighbors (5.6.3)
innodb_fast_recovery
---> 2010.4: (+α) red black tree (Plugin-5.1.46)
3年前の資料
13
15. 2010年前半(2)
2010.4
MySQL Conference & Expo 2010
「How to Fulfill the Potential of InnoDB's Performance and Scalability」
※スケーラビリティの問題解析、対処法の集大成
結論としては、buf_pool_mutexの競合じゃない限りは
XtraDBじゃなくて InnoDB-Pluginで十分(ぉ)というもの
この内容によって、マニアユーザーはスケーラビリティ問題を、
より明確に把握出来るようになって、改善要求が具体的になり、
進歩に繋がったと思う。
※今振り返れば、5.6 ではもう解決済みの物も多い。
この発表内容の必要性はもうすぐ無くなると思う。良い意味で。
2010.4
Plugin-5.1.46
InnoDB Plugin のリカバリ性能の公式改善
MySQL-5.5.4
flush_list_mutex の切り出し
(buf_pool_mutex競合が少し減る)
1個だけだったロールバックセグメントを 128個に
innodb_purge_threads
機能改善で性能↑
(公式人柱向け)
CPUスケーラビリティ↑
(開発版人柱向け)
3年前の資料
15
17. 2011年前半
2011.4
O'Reilly MySQL
Community Contributor of the year 2011
(行けなかったけど。)
<(確かに過去の議論は2010年後半で本家に反映されて結実してるので、
全てのユーザーが恩恵を受けたタイミングでの受賞なのかも。)
2011.4
開発版MySQL-5.6.2-m5
rw_lock for page_hash
(buf_pool_mutex競合が結構減る)
さらに、kernel_mutexの分割 (lock_sys->mutex等)
<(見えているやるべき事は大体終わった?)(スケーラビリティ)
CPUスケーラビリティ↑
(開発版人柱向け)
3年前の資料
17
20. 改善したい点
contiguous limited neighbor flush
http://www.mysqlperformanceblog.com/2012/01/17
/benchmarks-of-new-innodb_flush_neighbor_pages/
Percona在籍中の最後の「小手先」パッチ
index->lock の競合解消
研究中(秘密)
問題はより高次のレイヤーへ(統計情報とか実行計画とか)
3年前の資料
20
21. Copyright 2015 Scigineer Inc. All rights reserved.©
2012年
2012.6
唯一の日本人開発者だから、
(外国人が見ても破綻していた)日本語エラーメッセージ
の大幅見直しをさせられる。
(MySQL-5.6以降の日本語は気持ち悪くないはず。)
⇒ しばらく腰痛に苦しめられる。
21
22. Copyright 2015 Scigineer Inc. All rights reserved.©
2013年(1)
2013.2
MySQL-5.6.10 GA
(印象的なものを振り返ると…)
- innodb_buffer_pool_[dump/load]*
Percona時代に Baron Schwartz に言われて作った機能(ウォームアップ要らず)。
好評につき正式実装版
- innodb_change_buffer_max_size
insert bufferのサイズ制限方法が遂に正式実装。(個人的には最小の1がお薦め)
- innodb_checksum_algorithm
データベース新規作成なら黙って「crc32」
- innodb_flush_neighbors
HDDなら1、SSDなら0 推奨。(5.5以前の従来動作は2だが、非効率)
- innodb_lru_scan_depth
謎が謎を呼び、二転三転したパラメータ。(当初私もよくわからなかった)
結局後のバージョンでは、各BPインスタンス毎のFree Block確保のターゲットでFA
- innodb_purge_threads (> 1)
更新ユーザースレッドが多いと、CPUリソース争いでpurgeが負け続けて、処理が
追いつかないundoレコードが肥大化する。数には数で対抗する!というパラメータ
(5.7ではpurgeのスケーラビリティが上がって効率UP)
未実装のものは〜 5.7以降に持ち越し〜
22
23. Copyright 2015 Scigineer Inc. All rights reserved.©
2013年(2)
2013.7
性能改善リーダー Inaam Rana がInnoDBチームを去る。
(5.6は彼の考え方がベースのバージョンであったと言える。)
⇒ 私が後任で、性能改善リーダーになる。
Sunny Bains (InnoDBチームのプレイングマネージャー)
Dimitri Kravtchuk (http://dimitrik.free.fr/blog/、
MySQL Performance Architect)
と議論しながら5.7でのさらなる性能改善に取り組むことになる。
23
24. Copyright 2015 Scigineer Inc. All rights reserved.©
2014年
2014.1
2014.7
Buffer Pool のオンラインサイズ変更機能がやっと完成する
十分安定。実装による性能劣化も無し〜 〜
- 2回作り直し
- 3ヶ月以上毎日のような コアファイルvs修正 のラリー
24
MySQL-5.6.16 (5.7.4)
単ページ多重参照処理のスケーラビリティー改善
「[Note] InnoDB: Using atomics to ref count buffer pool pages」とログに出る
(5.7ではデフォルト。最新ではログは出ない。
結構な変更量だが5.6から直さざるを得なかったのは大人の事情。)
5.7特有の改善じゃないので
ここで紹介
25. Copyright 2015 Scigineer Inc. All rights reserved.©
2015年
2015.2
Oracle/InnoDBチームを離れ、
サイジニア株式会社(http://www.scigineer.co.jp/) へ
- レコメンデーションエンジンを使った広告支援サービス。
- 大学時代の研究室の先輩が
研究テーマをベースに作った技術で起業
培ってきた技術で化学反応を起こして、
できるだけ社会に還元していきたい!
25
27. Copyright 2015 Scigineer Inc. All rights reserved.©
MySQL-5.7 性能関連概要
◎ スケーラビリティの大幅向上 (参照系・更新系ともに)
通常のSMP構成で一般的な処理の場合にはスケーラビリティー問題は…
もう発生しない!(と思う)
○ 更新系スループットの安定性・制御性の向上
古い更新が溜まった時の同期flush(の嵐)で固まることはない。
(flush速度に合わせて遅くなるだけ。)
flush量を制御するためのオプションもちゃんと数値指定通りに動作。
(サボらない。やりすぎない。)
× シングルセッション性能が少し重くなった (と思う)
mutex/rw_lockを細かく整理すると、競合は減るが、mutex/rw_lockの操作は増える。
27
28. Copyright 2015 Scigineer Inc. All rights reserved.©
index->lock 競合改善
BTR_MODIFY_TREE時、従来 index全体が X-lock され、すべての同時検索が
ブロックされていたのを、必要な範囲・レベルに限定して、ツリー構造更新に関係の
ない範囲は同時検索可能とした。
28
29. Copyright 2015 Scigineer Inc. All rights reserved.©
Page Cleaner Thread 最適化
新オプション innodb_page_cleaners
更新ユーザースレッドが多いと、page cleanerもCPUリソース争いで負けて、
Free Blockが不足したり、Flushが滞ったりする。複数のpage cleaner thread
を用意すれば、Buffer Poolインスタンス単位で並列処理できる。
これでも足りない場合もあるので、5.7.6ではさらに修正 (後述)
29
30. Copyright 2015 Scigineer Inc. All rights reserved.©
MERGE_THRESHOLD (5.7.6〜?)
ページのデータ量が基準値まで減った場合、InnoDBは隣接ページヘのマージを試
みる。その基準が従来50%で固定だったものを、各索引毎に指定可能にした。
50%の場合、マージ後は100%それだけ近いデータ量になり、少しのデータ増でも
ページ再分割が発生してしまう。少し減らしたほうがいい。
⇒ 不必要なマージ 分割の繰り返しが発生すると、↔ BTR_MODIFY_TREEなので
それだけ、他の処理をブロックする可能性がある。
まず直すのが先なので、DDLの'COMMENT='句でとりあえず実装した。
※経験上インターフェースから議論したら何年かかるかわからないので後回し。
使い方、設定値確認、効果確認など 詳しくはWebで。(^^;)
http://dev.mysql.com/doc/refman/5.7/en/index-page-merge-threshold.html
30
31. Copyright 2015 Scigineer Inc. All rights reserved.©
Adaptive_flushing等flush関係最適化 (5.7.6〜?)
Adaptive flushing の挙動変更
innodb_io_capacity_max が正確に! ⇒ 設定しやすい。
flushの必要性をより適切に判断
max_modified_age_sync 到達時の挙動修正
従来動作は、各ユーザースレッドが各々flushバッチを自分が成功するまでリトライ。とい
うflushの嵐が発生。
各ユーザースレッドはターゲットLSNまでflushされるのを待つように変更。(Adaptive
flushの挙動が適切なので、こちらが正解。)
Page cleaner thread の優先
(とりあえずLinuxのみ。起動ユーザーに権限がある場合のみ自動で。)
31
32. Copyright 2015 Scigineer Inc. All rights reserved.©
その他、性能関係の小さな修正@5.7
log_sys->mutex 周り最適化
特に innodb_flush_log_at_trx_commit = 2 の設定に恩恵
※Windows版では書き込みsync中の書き込みリクエストを許すと遅くなる模様なので、
Windows版だけ少し戻している。
innodb_log_write_ahead_size
InnoDBのlogブロックサイズ(512bytes)がデバイスのブロックサイズよりも小さい場合、
書き込み時にそのブロックがOSでキャッシュされていないと、読み込みが発生して書き
込みが遅くなる。(Read on Write 問題)
このパラメータは、指定サイズの最初の512byte書き込み時にパッディングして読み込み
を回避する。(書き込みが増えるのでSSDでは無効化すべし。)
逆方向カーソルの再開時の挙動の最適化
ある種の逆方向スキャンが効率化されたかも。
BTR_MODIFY_LEAF失敗時点での左右ページの先読み
そのあとのBTR_MODIFY_TREE時にどうせ必要になるので、その時(index->lock取得中
)のIO待ちを最低限にするために、先に非同期read IOを発行しておく。
32
35. Copyright 2015 Scigineer Inc. All rights reserved.©
InnoDB以外の設定 (追加)
jemalloc の使用
限界スケーラビリティーを目指すには必須
my.cnf
metadata_locks_hash_instances
MDL関連のmutex競合が目立つなら増やすといいかも
table_open_cache_instances
table cacheのmutex競合が目立つなら増やすといいかも
performance_schema = OFF
最新版では以前ほど問題にはならないが、気になるなら。使わないなら。
35
36. InnoDBの設定
innodb_file_per_table = true
(何故かまだデフォルトじゃないので。。。)
innodb_flush_method = O_DIRECT
(データファイルアクセスにメモリを無駄に喰わないため)
innodb_doublewrite = false
(なんとか、ページ単位の中途書き込み状態が発生しないようにして無効化したい)
innodb_buffer_pool_size
(できるだけ大きくするが他の処理のためのディスクキャッシュ分手加減推奨)
innodb_log_file_size
(リカバリ時間とのトレードオフだができるだけ大きくする)
innodb_log_files_in_group
(OracleDBと違って、archiveの問題はないので 2でいい)
3年前の資料
今はデフォルト。気にしない
36
ユーザーデータならファイル単位でオンラインで
破損ファイルの無効化・復旧ができそうだが…
バックアップからのファイル単位復旧はどうする?
(XtraBackupではできた筈:もう記憶曖昧)
37. Copyright 2015 Scigineer Inc. All rights reserved.©
InnoDBの設定 (追加)
innodb_change_buffer_max_size = 1(というか小さい値)
性能に有効な機能だけど、溜め込んでBuffer Poolを浪費しないように。
innodb_checksum_algorithm = crc32
速いに越したことはない
innodb_purge_threads
ユーザースレッドの更新に押し負けない個数設定
innodb_sync_array_size
sync arrayのmutex競合が多い場合は増やす
innodb_page_cleaners
ユーザースレッドに負けないように。(実質並列度の最大はbuffer_pool_instancesの数)
innodb_io_capacity_max の見直し(5.7.6以降)
必要な事態にはちゃんと設定page/sの書き込みが起こるので、大き目にしてる場合注意。
各表への MERGE_THRESHOLD 指定 (5.7.6以降)
デフォルトの50(%)より少し下げて、BTR_MODIFY_TREEの発生を抑える。(45くらい?)
37
38. SSDを使うなら
Linux native AIO (use 5.5~)
(アクセスが速いから)
innodb_flush_neighbors = false
innodb_random_read_ahead = false
innodb_read_ahead_threshold = 0
(シーケンシャルアクセスの利点がないから)
3年前の資料
=0
38
39. Copyright 2015 Scigineer Inc. All rights reserved.©
SSDを使うなら (追加)
innodb_log_write_ahead_size = 0
これは、HDD系のストレージのために追加された機能。
読み込みが速く、Read on Writeの影響が少ないSSD系では無効にする。
39
41. Copyright 2015 Scigineer Inc. All rights reserved.©
InnoDBとのインターフェース再検討するかも
SQLレイヤーのバイパス
いろいろあるけど、一番高機能な Transactd を試して、
SQLをバイパスすることの有効性を確認。
最短のバルクロード・アンロード模索
import tablespace用のファイルを直接CSVなどから作れないか?
またはその逆
バックアップ・リカバリ再検証
(在職中、MEBとは何の関係も無かったので、最新の事情はよくわからない…)
まずは、XtraBackupみたいなのを5.7で作りなおすか?
41
42. Copyright 2015 Scigineer Inc. All rights reserved.©
InnoDB内部の性能調整するかも
シングルセッション限定特殊モード
1セッションまたはセッションが少ない場合は、ロック範囲大、ロック操作少の
反スケーラビリティーの挙動をするようにする。
※昔、某DB2を触った時に1セッション時だけ速くて違和感があったが、
こういうモードだったのかもしれない。
Adaptive Hash Index の新次元スケーラビリティ問題
が将来超ハイエンドサーバーで起こるかもしれない。
が、その超ハイエンドサーバーが無ければ何もできないので、覚悟だけしておく。
…など考えているだけ。必要/余裕が無ければやらないかも。
私を待つより自分でやったほうが速いかも。(^^;
42
44. Copyright 2015 Scigineer Inc. All rights reserved.©
0 2 4 6 8 10 12
0
5000
10000
15000
20000
25000
30000
35000
C prepared Transactd C++
sessions
TpmC的な指標
例のTPC-C likeベンチマークを完全移植してみた(だけ)
5種類のトランザクションはなんとか全部移植できた。
環境は手持ちの普通のPC。WHが小さいとスケールしない処理は元でもカット。
純粋なCPU性能比較のためramfs上で、ローカル接続。
Transactdの対応は現在5.6まで。なので5.6でテスト。
(5.7に無理やり使っても動作が怪しかったので…)
44
何故かこのノートPCでの結果。
※長年開発に使ってたPC(linux-2.6)だと
TCP/IP周りが盛大にボトルネックになり、
昨晩のテスト結果はお蔵入りに…
※このノートでは3.4です…
45. Copyright 2015 Scigineer Inc. All rights reserved.©
Transactdの特性 (私の主観)
◎ 主キー操作の場合、「Prepared Statementの」 ざっくり倍程度速い。
(New-Order トランザクションだけなら本当に倍速い。最悪でも同程度/微増。)
○ 埋め込みSQLよりスッキリ書ける。(表定義を整理しておけば。)
カーソルレコードに対する複雑な変更・参照などいちいちSQL呼ばなくていい。
(それぞれのSQLで変数をいちいちbindとか面倒だったので。)
でも、index指定、レコードが検索条件に合っているかのチェックも逐次必要。
△ NULL値が扱えない。 (ゼロ扱い)
△ セカンダリキー操作は必ず主キー検索を伴う (常に全列対象なので)
それでもまだ速いが、主キー操作ほど性能アップしない。
⇒ 改造は可能か? (readonly時のみ効くindexOnlyオプションとか。。)
× 集計とか結合とかはRDBMS側だけでできないため、さらに性能メリットは薄い。
(リモート接続だとかなり遅いと思われる。)
⇒ 条件付きcount()的なものだけなら改造で加えられるか?
? 性能問題を解析するとき、クライアント側のどの処理かどう特定する?
45