Diese Präsentation wurde erfolgreich gemeldet.
Wir verwenden Ihre LinkedIn Profilangaben und Informationen zu Ihren Aktivitäten, um Anzeigen zu personalisieren und Ihnen relevantere Inhalte anzuzeigen. Sie können Ihre Anzeigeneinstellungen jederzeit ändern.
チューニンガソン5の復讐
~SH2さんの宿題をやってみた~
2013/07/29
MyNA July in 2013
yoku0825
SH2さんのブログ記事
チューニンガソン5の復習
MySQL 5.5 チート編&勉強会のお知らせ
http://d.hatena.ne.jp/sh2/20130304
に敬意を表して
\こんばんは/
• I'm yoku0825, working as DBA for the
company which provides web-services.
• Husband of my wife :)
• Father of my...
今日のテーマ
• LTなので、チューニンガソン5の説明は省
略します。
– レギュレーションとかはゼロスタートさんの
広報ブログを
http://pr.zero-start.jp/archives/65730135.html
• 今回のチューニ...
SH2さんのチューニング(?)
やってみましょう
握 り つ ぶ し て い ま
す
同じ文字列を返すようにできます
まあなんというか
( ´-`).oO(MySQL Proxyでクエリ
書き換えはいくらなんでもあん
まりだろう
と思ったのは俺だけではないはず
そんなアナタに贈る
MySQL Proxyを使わずに
mysqldを改造して
クエリキャッシュに載せるライフ
ハック
Let's 魔改造
用意したもの
• CentOS 6.3の仮想マシン。
– 1vCPU
– 1GiB Memory
– 230IOPSしかでなかった仮想DISK
• MySQL 5.6.12 Source-Distributed
• 男らしい潔さと大胆さ。
• ...
まずは吊るしのスコアを測定
$ python tgbench_mysql_2.py localhost
Q0:0.00024
Q1:31.04855
Q2:21.24284
Q3:20.81227
Q4:81.48403
Q5:77.68560...
うわっ…私のMySQL、遅すぎ
…?
My MySQL is slower than your MySQL :(
まあ、行きます。
まずはRESET QUERY CACHEを何とかしようず。
RESET QUERY CACHEの回避
• RESET QUERY CACHEを処理する関数は
Query_cache::flush()
2063 /* Remove all queries from cache */
2064
2065 v...
RESET QUERY CACHEの回避
• 男らしい潔さと大胆さを発揮。
***************
*** 2064,2085 ****
void Query_cache::flush()
{
- DBUG_ENTER("Query_c...
Q3, Q4, Q5がクエリキャッシュから返るよう
に
$ python tgbench_mysql_2.py localhost
Q0:0.00024
Q1:27.84138
Q2:20.36092
Q3:20.98092
Q4:81.709...
はい次。
NOW()関数を何とかしようず。
NOW()関数の回避
• クエリーがクエリーキャッシュにのるべ
きか否かを判定するのは
Query_cache::is_cacheable
3702 TABLE_COUNTER_TYPE
3703 Query_cache::is_cacheab...
NOW()関数の回避
• 本当はNOW()だけ華麗にスルーしたかった
けど、手が込みそうなので後ろを振り返
らない勇ましさを発揮。
***************
*** 3707,3716 ****
TABLE_COUNTER_TYPE ta...
Q2もクエリキャッシュから返るように
$ python tgbench_mysql_2.py localhost
Q0:0.00030
Q1:32.63952
Q2:21.20478
Q3:21.08606
Q4:82.93199
Q5:78....
はい次。
AUTOCOMMITを何とかしようず。
AUTOCOMMITの壁
• Bug #42197の壁
http://bugs.mysql.com/bug.php?id=42197
• 正直色々無理。
• 俺が直せるならとっくに直ってるだろ。
• vioでautocommitフラグを握りつぶ...
結局
謙虚に初心に返ってみた
• ALTER TABLE page Engine = MyISAM;
• ALTER TABLE revision Engine = MyISAM;
'`,、'`,、( ´∀`)'`,、'`,、
これで全てがクエリキャッシュから返る
$ python tgbench_mysql_2.py localhost
Q0:0.00031
Q1:3.44232
Q2:2.98533
Q3:2.97978
Q4:29.55061
Q5:25.793...
副作用
$ time mysql -e "SELECT rev_id FROM wikipedia.revision ORDER BY RAND() LIMIT 5"
+----------+
| rev_id |
+----------+
|...
ORDER BY RAND()でもクエリ
キャッシュから返るからDISKに優
しい!
orz
副作用
$ time mysql -e "SELECT rev_id, NOW() FROM wikipedia.revision LIMIT 5"
+---------+---------------------+
| rev_id | NO...
まるでREPEATABLE-READ!!
orz
日本よ、これがMySQL 5.6
だッ!!
(c) @nippondanji
http://nippondanji.blogspot.jp/2012/
10/mysql-56.html
すいません調子乗りましたorz
今回の魔改造の副産物
というか、魔改造が副産物だけど
information_schema.QUERY_CACHE_INFO
• MariaDB 10.0.2, 5.5.31にもバックポートさ
れた、クエリーキャッシュの中身を覗け
るinformation_schemaプラグイン
• 自力で書こう...
こんな感じ
mysql55> SELECT * FROM information_schema.query_cache_info LIMIT 3G
*************************** 1. row *************...
パッチはこちら
https://github.com/yoku0825/qc_info
MariaDBのJIRAに
インプリメントのパッチがあるので
そのうち追加するかも
あと5.6で動かないのでそれも
MySQL 5.6ではデフォルトでoffに
なりましたが
しかも(for performance reasons)って
中の人に書かれてたり。
知ってるけどさ(つд`)
http://bugs.mysql.com/bug.php?id=68241
読んでみると意外と面白かっ
たりします
よく知られたところだから、
想定する動作が判るってのが大き
い
\宣伝/
スパスパMySQLやりたい
( ´∀`)y-~~
↑このへんがス
パスパ
本家
• 過去のイベントです。
• http://atnd.org/events/33779
• ハッシュタグなんてあったんですね!? #gdgdmysql
• 参加されている面子的に、煙草飲みには肩身が狭そうな気配。
• 煙草もやめられないけ...
じゃあ作るしかない
というわけでスパスパMySQL
9月上旬にやるつもりです。
参加しても良いよって方は
@yoku0825までメンション下さい。
ご清聴ありがとうございまし
た
チューニンガソン5の復讐
Nächste SlideShare
Wird geladen in …5
×

チューニンガソン5の復讐

3.782 Aufrufe

Veröffentlicht am

2013/07/29のMyNA会の資料です。
奥野さんのブログ記事の一部(CC-BY-NC-SA)を含んでいるため、CC-BY-NC-SAです。

Veröffentlicht in: Technologie
  • Als Erste(r) kommentieren

チューニンガソン5の復讐

  1. 1. チューニンガソン5の復讐 ~SH2さんの宿題をやってみた~ 2013/07/29 MyNA July in 2013 yoku0825
  2. 2. SH2さんのブログ記事 チューニンガソン5の復習 MySQL 5.5 チート編&勉強会のお知らせ http://d.hatena.ne.jp/sh2/20130304 に敬意を表して
  3. 3. \こんばんは/ • I'm yoku0825, working as DBA for the company which provides web-services. • Husband of my wife :) • Father of my son :) • I love sushi more than yakiniku :) Of cource, I love yakiniku well. • MySQL? It's my delight :)
  4. 4. 今日のテーマ • LTなので、チューニンガソン5の説明は省 略します。 – レギュレーションとかはゼロスタートさんの 広報ブログを http://pr.zero-start.jp/archives/65730135.html • 今回のチューニングはSH2さんのブログ記 事がベースです。 – http://d.hatena.ne.jp/sh2/20130304
  5. 5. SH2さんのチューニング(?)
  6. 6. やってみましょう
  7. 7. 握 り つ ぶ し て い ま す
  8. 8. 同じ文字列を返すようにできます
  9. 9. まあなんというか
  10. 10. ( ´-`).oO(MySQL Proxyでクエリ 書き換えはいくらなんでもあん まりだろう と思ったのは俺だけではないはず
  11. 11. そんなアナタに贈る
  12. 12. MySQL Proxyを使わずに mysqldを改造して クエリキャッシュに載せるライフ ハック Let's 魔改造
  13. 13. 用意したもの • CentOS 6.3の仮想マシン。 – 1vCPU – 1GiB Memory – 230IOPSしかでなかった仮想DISK • MySQL 5.6.12 Source-Distributed • 男らしい潔さと大胆さ。 • 後ろを振り返らない勇ましさ。 • 最後は初心に返る謙虚さ。
  14. 14. まずは吊るしのスコアを測定 $ python tgbench_mysql_2.py localhost Q0:0.00024 Q1:31.04855 Q2:21.24284 Q3:20.81227 Q4:81.48403 Q5:77.68560 Total:232.27354 $ python tgbench_mysql_2.py localhost Q0:0.00034 Q1:19.70425 Q2:19.93358 Q3:20.23704 Q4:76.66882 Q5:76.79747 Total:213.34149
  15. 15. うわっ…私のMySQL、遅すぎ …? My MySQL is slower than your MySQL :(
  16. 16. まあ、行きます。 まずはRESET QUERY CACHEを何とかしようず。
  17. 17. RESET QUERY CACHEの回避 • RESET QUERY CACHEを処理する関数は Query_cache::flush() 2063 /* Remove all queries from cache */ 2064 2065 void Query_cache::flush() 2066 { 2067 DBUG_ENTER("Query_cache::flush"); 2068 if (is_disabled()) 2069 DBUG_VOID_RETURN; 2070 2071 QC_DEBUG_SYNC("wait_in_query_cache_flush1"); 2072 2073 lock_and_suspend(); 2074 if (query_cache_size > 0) 2075 { 2076 DUMP(this); 2077 flush_cache(); 2078 DUMP(this); 2079 } 2080 2081 DBUG_EXECUTE("check_querycache",query_cache.check_integrity(1);); 2082 unlock(); 2083 DBUG_VOID_RETURN; 2084 }
  18. 18. RESET QUERY CACHEの回避 • 男らしい潔さと大胆さを発揮。 *************** *** 2064,2085 **** void Query_cache::flush() { - DBUG_ENTER("Query_cache::flush"); - if (is_disabled()) - DBUG_VOID_RETURN; - - QC_DEBUG_SYNC("wait_in_query_cache_flush1"); - - lock_and_suspend(); - if (query_cache_size > 0) - { - DUMP(this); - flush_cache(); - DUMP(this); - } - - DBUG_EXECUTE("check_querycache",query_cache.check_integrity(1);); - unlock(); DBUG_VOID_RETURN; } --- 2064,2069 ----
  19. 19. Q3, Q4, Q5がクエリキャッシュから返るよう に $ python tgbench_mysql_2.py localhost Q0:0.00024 Q1:27.84138 Q2:20.36092 Q3:20.98092 Q4:81.70963 Q5:75.44204 Total:226.33513 $ python tgbench_mysql_2.py localhost Q0:0.00019 Q1:20.24178 Q2:20.76213 Q3:0.00057 Q4:0.11970 Q5:0.00879 Total:41.13317
  20. 20. はい次。 NOW()関数を何とかしようず。
  21. 21. NOW()関数の回避 • クエリーがクエリーキャッシュにのるべ きか否かを判定するのは Query_cache::is_cacheable 3702 TABLE_COUNTER_TYPE 3703 Query_cache::is_cacheable(THD *thd, size_t query_len, const char *query, 3704 LEX *lex, 3705 TABLE_LIST *tables_used, uint8 *tables_type) 3706 { 3707 TABLE_COUNTER_TYPE table_count; 3708 DBUG_ENTER("Query_cache::is_cacheable"); 3709 3710 if (query_cache_is_cacheable_query(lex) && 3711 (thd->variables.query_cache_type == 1 || 3712 (thd->variables.query_cache_type == 2 && (lex->select_lex.options & 3713 OPTION_TO_QUERY_CACHE)))) 3714 { .. 3720 if (!(table_count= process_and_count_tables(thd, tables_used, 3721 tables_type))) 3722 DBUG_RETURN(0); 3723 3724 if (thd->in_multi_stmt_transaction_mode() && 3725 ((*tables_type)&HA_CACHE_TBL_TRANSACT)) 3726 { 3727 DBUG_PRINT("qcache", ("not in autocommin mode")); 3728 DBUG_RETURN(0); 3729 } 3730 DBUG_PRINT("qcache", ("select is using %d tables", table_count));
  22. 22. NOW()関数の回避 • 本当はNOW()だけ華麗にスルーしたかった けど、手が込みそうなので後ろを振り返 らない勇ましさを発揮。 *************** *** 3707,3716 **** TABLE_COUNTER_TYPE table_count; DBUG_ENTER("Query_cache::is_cacheable"); ! if (query_cache_is_cacheable_query(lex) && ! (thd->variables.query_cache_type == 1 || (thd->variables.query_cache_type == 2 && (lex->select_lex.options & ! OPTION_TO_QUERY_CACHE)))) { DBUG_PRINT("qcache", ("options: %lx %lx type: %u", (long) OPTION_TO_QUERY_CACHE, --- 3691,3699 ---- TABLE_COUNTER_TYPE table_count; DBUG_ENTER("Query_cache::is_cacheable"); ! if (thd->variables.query_cache_type == 1 || (thd->variables.query_cache_type == 2 && (lex->select_lex.options & ! OPTION_TO_QUERY_CACHE))) { DBUG_PRINT("qcache", ("options: %lx %lx type: %u", (long) OPTION_TO_QUERY_CACHE,
  23. 23. Q2もクエリキャッシュから返るように $ python tgbench_mysql_2.py localhost Q0:0.00030 Q1:32.63952 Q2:21.20478 Q3:21.08606 Q4:82.93199 Q5:78.23889 Total:236.10153 $ python tgbench_mysql_2.py localhost Q0:0.00021 Q1:20.41031 Q2:0.00031 Q3:0.00014 Q4:0.11961 Q5:0.00984 Total:20.54041
  24. 24. はい次。 AUTOCOMMITを何とかしようず。
  25. 25. AUTOCOMMITの壁 • Bug #42197の壁 http://bugs.mysql.com/bug.php?id=42197 • 正直色々無理。 • 俺が直せるならとっくに直ってるだろ。 • vioでautocommitフラグを握りつぶそうかと 思ったけど、sql/sql_cache.ccの中で完結した かった。 • トランザクション周りの判定を色々変えてみ るも、そもそもmy_hash_searchで転んでるの でダメぽ。
  26. 26. 結局
  27. 27. 謙虚に初心に返ってみた • ALTER TABLE page Engine = MyISAM; • ALTER TABLE revision Engine = MyISAM; '`,、'`,、( ´∀`)'`,、'`,、
  28. 28. これで全てがクエリキャッシュから返る $ python tgbench_mysql_2.py localhost Q0:0.00031 Q1:3.44232 Q2:2.98533 Q3:2.97978 Q4:29.55061 Q5:25.79326 Total:64.75160 $ python tgbench_mysql_2.py localhost Q0:0.00018 Q1:0.00016 Q2:0.00010 Q3:0.00033 Q4:0.11568 Q5:0.00785 Total:0.12431
  29. 29. 副作用 $ time mysql -e "SELECT rev_id FROM wikipedia.revision ORDER BY RAND() LIMIT 5" +----------+ | rev_id | +----------+ | 43292141 | | 35737287 | | 45015288 | | 39406805 | | 44899598 | +----------+ real 0m4.259s user 0m0.006s sys 0m0.004s $ time mysql -e "SELECT rev_id FROM wikipedia.revision ORDER BY RAND() LIMIT 5" +----------+ | rev_id | +----------+ | 43292141 | | 35737287 | | 45015288 | | 39406805 | | 44899598 | +----------+ real 0m0.027s user 0m0.005s sys 0m0.005s
  30. 30. ORDER BY RAND()でもクエリ キャッシュから返るからDISKに優 しい! orz
  31. 31. 副作用 $ time mysql -e "SELECT rev_id, NOW() FROM wikipedia.revision LIMIT 5" +---------+---------------------+ | rev_id | NOW() | +---------+---------------------+ | 647678 | 2013-07-08 11:50:14 | | 2168855 | 2013-07-08 11:50:14 | | 2168856 | 2013-07-08 11:50:14 | | 2168894 | 2013-07-08 11:50:14 | | 2168972 | 2013-07-08 11:50:14 | +---------+---------------------+ real 0m0.031s user 0m0.007s sys 0m0.003s $ time mysql -e "SELECT rev_id, NOW() FROM wikipedia.revision LIMIT 5" +---------+---------------------+ | rev_id | NOW() | +---------+---------------------+ | 647678 | 2013-07-08 11:50:14 | | 2168855 | 2013-07-08 11:50:14 | | 2168856 | 2013-07-08 11:50:14 | | 2168894 | 2013-07-08 11:50:14 | | 2168972 | 2013-07-08 11:50:14 | +---------+---------------------+ real 0m0.011s user 0m0.005s sys 0m0.004s
  32. 32. まるでREPEATABLE-READ!! orz
  33. 33. 日本よ、これがMySQL 5.6 だッ!! (c) @nippondanji http://nippondanji.blogspot.jp/2012/ 10/mysql-56.html
  34. 34. すいません調子乗りましたorz
  35. 35. 今回の魔改造の副産物 というか、魔改造が副産物だけど
  36. 36. information_schema.QUERY_CACHE_INFO • MariaDB 10.0.2, 5.5.31にもバックポートさ れた、クエリーキャッシュの中身を覗け るinformation_schemaプラグイン • 自力で書こうと頑張っていた頃に見つけ て見事にやる気をなくす • が、折角だからMySQLでも使えるように パッチした • 取り敢えずステージング環境に突っ込ん で使ってる
  37. 37. こんな感じ mysql55> SELECT * FROM information_schema.query_cache_info LIMIT 3G *************************** 1. row *************************** STATEMENT_SCHEMA: tpcc STATEMENT_TEXT: SELECT i_price, i_name, i_data FROM item WHERE i_id = 16360 RESULT_BLOCKS_COUNT: 1 RESULT_BLOCKS_SIZE: 512 RESULT_BLOCKS_SIZE_USED: 298 *************************** 2. row *************************** STATEMENT_SCHEMA: tpcc STATEMENT_TEXT: SELECT i_price, i_name, i_data FROM item WHERE i_id = 39901 RESULT_BLOCKS_COUNT: 1 RESULT_BLOCKS_SIZE: 512 RESULT_BLOCKS_SIZE_USED: 297 *************************** 3. row *************************** STATEMENT_SCHEMA: tpcc STATEMENT_TEXT: SELECT i_price, i_name, i_data FROM item WHERE i_id = 2134 RESULT_BLOCKS_COUNT: 1 RESULT_BLOCKS_SIZE: 512 RESULT_BLOCKS_SIZE_USED: 302 3 rows in set (0.01 sec)
  38. 38. パッチはこちら https://github.com/yoku0825/qc_info
  39. 39. MariaDBのJIRAに インプリメントのパッチがあるので そのうち追加するかも あと5.6で動かないのでそれも
  40. 40. MySQL 5.6ではデフォルトでoffに なりましたが しかも(for performance reasons)って 中の人に書かれてたり。 知ってるけどさ(つд`) http://bugs.mysql.com/bug.php?id=68241
  41. 41. 読んでみると意外と面白かっ たりします よく知られたところだから、 想定する動作が判るってのが大き い
  42. 42. \宣伝/
  43. 43. スパスパMySQLやりたい ( ´∀`)y-~~ ↑このへんがス パスパ
  44. 44. 本家 • 過去のイベントです。 • http://atnd.org/events/33779 • ハッシュタグなんてあったんですね!? #gdgdmysql • 参加されている面子的に、煙草飲みには肩身が狭そうな気配。 • 煙草もやめられないけどMySQLもやめられない。
  45. 45. じゃあ作るしかない
  46. 46. というわけでスパスパMySQL 9月上旬にやるつもりです。 参加しても良いよって方は @yoku0825までメンション下さい。
  47. 47. ご清聴ありがとうございまし た

×