Upgrade to Pro — share decks privately, control downloads, hide ads and more …

MariaDB_Performance_Tuning.pdf

Takeshi Agatsuma
January 30, 2018
380

 MariaDB_Performance_Tuning.pdf

Takeshi Agatsuma

January 30, 2018
Tweet

Transcript

  1. 環境 OS CentOS Linux release 7.3.1611 (Core) CPU Intel(R) Core(TM)

    i7-6700K CPU @ 4.00GHz (8 core) Memory 32GB SSD SC300 HFS256G32MND-3312A (メーカー:SK hynix) ×1 2015年8月発売当時 ツクモで9240円 容量:256GB シーケンシャルRead:530MB/s、Write:380MB/s MariaDB 10.2.12-MariaDB
  2. TPC-C Benchmark テーブル構成 • テーブル構成 table name 内容 rows data

    size (MB) index size (MB) stock 在庫 11,774,349 4,178 0 order_line 注文明細 35,850,016 2,956 0 customer 顧客 3,462,264 2,258 264 orders 注文 3,549,909 119 142 history 支払履歴 3,6351,00 310 0 new_order 新規注文 1,087,545 39 0 item 商品マスタ 99,385 9 0 district 地区 1,200 0.28 0 warehouse 倉庫 120 0.02 0 合計約10GB
  3. TPC-C Benchmark 処理 (44%)新規注文 new order (1注文あたり5~15個購入する) (1) 18秒スリープ (2)

    insert: 注文、新規注文、注文明細テーブル (3) update: 地区、在庫テーブル (4) 0~12秒スリープ (4%)注文状況確認 order status (1) 2秒スリープ (2) select: 顧客、新規注文、注文テーブル (3) 0~5秒スリープ (44%)支払い payment (未精算の注文に支払いする) (1) 3秒スリープ (2) insert: 注文履歴テーブル (3) update: 倉庫、地区、顧客テーブル (4) 0~12秒スリープ (4%)在庫確認 stock level (1) 2秒スリープ (2) select: 地区、新規注文テーブル (3) 0~5秒スリープ (4%)配送 delivery (10注文配送する) (1) 2秒スリープ (2) delete: 新規注文テーブル (3) update: 注文、注文明細、顧客テーブル (4) 0~10秒スリープ
  4. HammerDB注意点 WAREHOUSEカラムサイズ拡張 WAREHOUSE件数を増やすとエラーが発生する。 「mysqlexec/db server: Out of range value for

    column 'w_ytd' at row 1」 WAREHOUSE テーブルの w_ytd (年間売上)カラムを拡張拡張する。 /usr/local/HammerDB-2.23/hdb-components/hdb_tpcc.tcl (8838行) set sql(9) "CREATE TABLE `warehouse` ( `w_id` INT(4) NOT NULL, `w_ytd` DECIMAL(36, 2) NULL, `w_tax` DECIMAL(4, 4) NULL,
  5. HammerDB注意点 Transaction Per Minutes の間違い show global status where Variable_name

    = 'Handler_commit' or Variable_name = 'Handler_rollback' → MySQL, MariaDBにバグがある。 handler_commit is incremented for InnoDB SELECT queries https://bugs.mysql.com/bug.php?id=52453
  6. HammerDB注意点 Handler_commitのバグ MariaDB [tpcc]> show global status where Variable_name =

    'Handler_commit' or Variable_name = 'Handler_rollback' or Variable_name = 'Com_commit'; +------------------+-------+ | Variable_name | Value | +------------------+-------+ | Com_commit | 0 | | Handler_commit | 0 | | Handler_rollback | 0 | +------------------+-------+ MariaDB [tpcc]> select count(*) from warehouse; MariaDB [tpcc]> show global status where Variable_name = 'Handler_commit' or Variable_name = 'Handler_rollback' or Variable_name = 'Com_commit'; +------------------+-------+ | Variable_name | Value | +------------------+-------+ | Com_commit | 0 | | Handler_commit | 1 | | Handler_rollback | 0 | +------------------+-------+ MariaDB [tpcc]> update warehouse set w_id =120 where w_id=120; MariaDB [tpcc]> commit; MariaDB [tpcc]> show global status where Variable_name = 'Handler_commit' or Variable_name = 'Handler_rollback' or Variable_name = 'Com_commit'; +------------------+-------+ | Variable_name | Value | +------------------+-------+ | Com_commit | 1 | | Handler_commit | 3 | | Handler_rollback | 0 |
  7. HammerDB注意点 Handler_commitをCom_commitに変更 /usr/local/HammerDB-2.23/hdb-components/hdb_tpcc.tcl (4か所: 9640、9644、9664、9668行) show global status where Variable_name

    = 'Com_commit' or Variable_name = 'Handler_rollback' • Handler_commit 内部 COMMIT ステートメントの数。 • Com_commit COMMITステートメントが実行された回数。
  8. Innodb定番 • DBバッファ • innodb_buffer_pool_size=24G • REDOログ • innodb_log_file_size=10G •

    innodb_log_files_in_group=2 • innodb_log_buffer_size=1G • ファイルへのフラッシュ方法 • innodb_flush_method=O_DIRECT • トランザクション分離レベル • transaction-isolation = READ-COMMITTED
  9. innodb_buffer_pool_size メモリ SSD InnoDB Buffer Pool mysqld Log Buffer ibdata*

    / *.ibd ib_logfile* 12GiB/s 20GiB/s 315MiB/s 400MiB/s 物理メモリサイズの80% innodb_buffer_pool_size=128MB(default) → 24GB
  10. innodb_buffer_pool_size • innodb_buffer_pool_sizeを1GB以上にするとデフォルトが変わる パラメータ • innodb_buffer_pool_instances 1 → 8 •

    バッファプールを8つに分割して競合を解消する。 • innodb_page_cleaners 1 → 4 • ページクリーナーを4スレッドで動かす。durtyページがマルチスレッドでflushさ れる。
  11. innodb_buffer_pool_sizeの効果 MariaDB [(none)]> show global status; Innodb_buffer_pool_pages_flushed = 9,985 →

    621,150 Innodb_row_lock_time = 7,545,612 → 3,694,147 Innodb_row_lock_time_avg = 1,285 → 204 Innodb_row_lock_waits = 5,871 → 19,098 Innodb_buffer_pool_bytes_data = 132,841,472 → 9,151,987,712 Innodb_buffer_pool_pages_free = 0 → 1,004,177 (16,066,832,000 bytes) → innodb_buffer_pool_size=25GBは多すぎ Innodb_buffer_pool_bytes_dirty = 46,137,344 → 1,296,809,984
  12. innodb_buffer_pool_sizeの効果 MariaDB [(none)]> show engine innodb status; ---------------------- BUFFER POOL

    AND MEMORY ---------------------- ... Pages made young 2889, not young 934461 ... Buffer pool hit rate 861 / 1000, young-making rate 1 / 1000 not 306 / 1000 ↓ ---------------------- BUFFER POOL AND MEMORY ---------------------- ... Pages made young 53, not young 0 ... Buffer pool hit rate 996 / 1000, young-making rate 0 / 1000 not 0 / 1000 → 再利用されない追い出し候補のバッファ
  13. REDOログ(innodb_log_*) 設定値の根拠 innodb_log_file_size = 50MB(default) → 10GB MariaDB [(none)]> show

    global status より、 Innodb_os_log_written = 3,279,874,560 (3GB) ログスイッチしないのが一番パフォーマンスが良いので、 TPMが上がることも考えて、余裕をもって10GB。 innodb_log_files_in_group = 2 (default) → 2 1回のTPC-Cで書ききれない(ログスイッチしない)ので、2個。 innodb_log_buffer_size = 8MB(default) → 1GB TPC-C一回の総redoログ書き込み量=3,279,874,560 bytes で、実行時間約4分なので、 1分あたりのredoログ書き込み量は、 3,279,874,560/4 = 819,968,640=781MB。 余裕を見て1GB。
  14. DBバッファ(innodb_buffer_pool_size) 、REDOログ(innodb_log_*)の合わせ技 MariaDB [performance_schema]> select event_name, count_star, sum_timer_wait -> from

    events_waits_summary_by_account_by_event_name -> where count_star <> 0 and event_name <> 'idle' and user = 'root' order by sum_timer_wait desc limit 5; +--------------------------------------+------------+-------------------+ | event_name | count_star | sum_timer_wait | +--------------------------------------+------------+-------------------+ | wait/io/table/sql/handler | 3408766 | 42510835632968250 | | wait/io/file/innodb/innodb_data_file | 1810463 | 597258834945000 | | wait/io/file/innodb/innodb_log_file | 34680 | 153149057016500 | | wait/lock/table/sql/handler | 1184974 | 1170412270250 | | wait/io/file/myisam/dfile | 4183 | 7905654000 | +--------------------------------------+------------+-------------------+ デフォルト my.cnf の Wait Event → innodb_buffer_pool_size = 24GBに設定すると
  15. DBバッファ(innodb_buffer_pool_size) 、REDOログ(innodb_log_*)の合わせ技 MariaDB [performance_schema]> select event_name, count_star, sum_timer_wait -> from

    events_waits_summary_by_account_by_event_name -> where count_star <> 0 and event_name <> 'idle' and user = 'root' order by sum_timer_wait desc limit 5; +--------------------------------------+------------+-------------------+ | event_name | count_star | sum_timer_wait | +--------------------------------------+------------+-------------------+ | wait/io/table/sql/handler | 11707250 | 43313073565340750 | | wait/io/file/innodb/innodb_log_file | 28559 | 118337615488000 | | wait/io/file/innodb/innodb_data_file | 372455 | 13451588753250 | | wait/lock/table/sql/handler | 4281043 | 3189581059750 | | wait/io/file/myisam/dfile | 4182 | 13438506500 | +--------------------------------------+------------+-------------------+ innodb_buffer_pool_size = 24GB の Wait Event → REDOログ回りの設定を変更すると
  16. DBバッファ(innodb_buffer_pool_size) 、REDOログ(innodb_log_*)の合わせ技 MariaDB [performance_schema]> select event_name, count_star, sum_timer_wait -> from

    events_waits_summary_by_account_by_event_name -> where count_star <> 0 and event_name <> 'idle' and user = 'root' order by sum_timer_wait desc limit 5; +--------------------------------------+------------+-------------------+ | event_name | count_star | sum_timer_wait | +--------------------------------------+------------+-------------------+ | wait/io/table/sql/handler | 68217960 | 13681480839471750 | | wait/io/file/innodb/innodb_log_file | 58201 | 235886274592000 | | wait/lock/table/sql/handler | 25430189 | 10595424424750 | | wait/io/file/innodb/innodb_data_file | 106501 | 4538950475000 | | wait/io/file/myisam/dfile | 4181 | 16364870500 | +--------------------------------------+------------+-------------------+ DBバッファとREDOログ回りを両方設定した後の Wait Event
  17. トランザクション分離レベル 分離レベル ダーティーリード ファジーリード ファントムリード READ UNCOMMITTED 可能性あり 可能性あり 可能性あり

    READ COMMITED (一般的なRDBMS) 発生しない 可能性あり 可能性あり REPEATABLE READ (innodb デフォルト) 発生しない 発生しない innodbでは発生しない SERIALIZABLE 発生しない 発生しない 発生しない 概要 パフォーマンスの利点 ダーティーリード コミット前の更新が別トランザクションから見える 更新前のデータにロックがかからない ファジーリード トランザクション1がselectした結果を、 トランザクション2が更新・コミットした後、 トランザクション1が再度selectすると更新される。 他トランザクションがselectしたレコード の更新前のデータを保持しなくてよい。 ファントムリード トランザクション1がselectした範囲にあるレコードを、 トランザクション2が挿入・削除・コミットした後、 トランザクション1が再度selectすると更新される。 他トランザクションがselectした範囲のレ コードの更新前のデータを保持しなくて よい。 パフォーマンス 良 悪 transaction-isolation = REPEATABLE-READ(default) → READ-COMMITTED
  18. トランザクション分離レベルの効果 • しかし、本環境ではgap lock、next-key lock がかかっていないので、 効果なし。 MariaDB [(none)]> show

    engine innodb status; ------------ TRANSACTIONS ------------ ... RECORD LOCKS space id 9 page no 42731 n bits 328 index PRIMARY of table `tpcc`.`orders` trx id 16602294 lock_mode X locks rec but not gap ...
  19. Innodb SSDの定番 • ページサイズ • innodb_page_size=4K • IO効率化 • innodb_lo_capacity=2000

    • innodb_flush_neighbors=0 • マウントオプション • nobarrier • IOスケジューラ • deadline
  20. ページサイズ変更の効果 # iostat -t -x 1 (ページサイズ 16KB) Device: rrqm/s

    wrqm/s r/s w/s rkB/s wkB/s avgrq-sz avgqu-sz await r_await w_await svctm %util sda 0.00 977.00 981.00 8309.00 3924.00 79176.00 17.89 3.67 0.39 0.35 0.40 0.04 36.40 ↓ (ページサイズ 4KB) Device: rrqm/s wrqm/s r/s w/s rkB/s wkB/s avgrq-sz avgqu-sz await r_await w_await svctm %util sda 0.00 2016.00 2253.00 1676.00 9012.00 35680.00 22.75 4.97 1.27 1.32 1.20 0.25 97.90 → SSDがリクエスト数をさばききれなくなり、パフォーマンス低下?
  21. innodb_io_capacity • innodb_io_capacity=200(Default) → 2000 InnoDB バックグラウンドタスクで実行される I/O アクティビティー (バッファープールからのペー

    ジのフラッシュや挿入バッファーからのデータのマージなど) に上限を設定します。 ストレージのiopsに合わせて設定する。 Device: rrqm/s wrqm/s r/s w/s rkB/s wkB/s avgrq-sz avgqu-sz await r_await w_await svctm %util sda 0.00 1819.00 253.00 1523.00 4048.00 88776.00 104.53 2.57 1.45 1.53 1.43 0.53 94.00 2000は妥当。 → なぜ効果が無いかわからない
  22. 今回の検証結果 まとめ DBバッファサイズ拡張(innodb_buffer_pool_size) ◦効果あり REDOログ回り拡張(innodb_log_*) △効果なし DBバッファ + REDOログ 合わせ技

    ◎効果あり O_DIRECT ×悪化 トランザクション分離レベル △効果なし ページサイズをストレージに合わせる ×悪化 IOスケジューラ Deadline △効果なし マウントオプション nobarrier ◎効果あり innodb_flush_neighbors ×悪化 innodb_io_capacity △効果なし 全部 ◎効果あり!!