Devsの常識、DBAは非常識

23,593
-1

Published on

2013/09/14 at PHP Conference 2013

Published in: Technology
1 Comment
161 Likes
Statistics
Notes
No Downloads
Views
Total Views
23,593
On Slideshare
0
From Embeds
0
Number of Embeds
17
Actions
Shares
0
Downloads
111
Comments
1
Likes
161
Embeds 0
No embeds

No notes for slide

Devsの常識、DBAは非常識

  1. 1. MySQL Admin が見た Devs の常識、 DBA は非常識 2013/09/14 yoku0825@MyNA PHP Conference 2013
  2. 2. \こんにちは!/ ● yoku0825 ● とある企業の DBA ● MySQL 歴 5 年くらい ● オラクれない ● ポスグれない ● 嫁の夫 ● せがれの父 ● 日本 MySQL ユーザ会 (MyNA) のスベり担当
  3. 3. \しゃべること!/ ● 日常的に MySQL のソースコードに触れる変態 DBA がフツーの Devs に投げた愛のマサカリ集 ( のつもり ) ● ウチの開発言語は PHP > Java >> Ruby らしいです ● ウチでは DBA がサーバーの構築、 Devs が設計・ テーブル構築・運営、 DBA はトラブルシュートや改 善提案 ( 運用 ) 、というサイクルで回しています。
  4. 4. それでは Devs からのお便りを 紹介していきます
  5. 5.   yoku0825 さんこんにちは。  現在 MySQL 4.0 を使用しているサービスがあるの ですが、このたびサーバーのリプレースに伴い MySQL 5.6 を導入したいと思っています。  最新版なので特に問題なく移行できると考えていま すが、注意するポイントなどがあれば教えて下さい。 ( 30 代・東京都・ Perl Monger )
  6. 6. ( ゚ д ゚ ) えっ
  7. 7. ● レプリケーションを使ったバージョンアップ ● 旧バージョンのスレーブがある場合、マスターのバージョンアップ をかける前に 1 台ずつ切り離してバージョンアップしておく。 ● スレーブを全部バージョンアップできたら、新バージョンのスレー ブ 1 台を使ってカスケードレプリケーション構成にしておく。 ● どこかのタイミングで新バージョンのスレーブをマスターとして参 照するように切り替える。 ● 旧マスターをバージョンアップして新マスターのスレーブにしてし まう。 ● 停止時間は切り替え時間だけで済む。 ● オフラインバージョンアップ ● データファイルに互換性があれば、 mysqld 停止 ⇒ バイナリー入 れ替え ⇒ 起動 ⇒ mysql_upgrade で OK 。 ● データファイルの互換性がなければ mysqldump でダンプして新しい mysqld にリストアする(最後の手段) ● ダンプの SQL 自体互換性がなくてちょっといじらないといけない 場合も。
  8. 8. ● 基本的にレプリケーション , オフラインバージョン アップできるのは 1 つ上のメジャーバージョンまで。 ● MySQL 3.23.31(2001/01) ~ 3.23.58(2003/9) ● MySQL 4.0.12(2003/03) ~ 4.0.30(2007/02) ● MySQL 4.1.7(2004/10) ~ 4.1.25(2008/12) ● MySQL 5.0.15(2005/10) ~ 5.0.96(2012/03) ● MySQL 5.1.30(2008/11) ~ 5.1.71 ● MySQL 5.5.8(2010/12) ~ 5.5.33 ● MySQL 5.6.10(2013/02) ~ 5.6.13 ● 4.0 -> 4.1 -> 5.0 -> 5.1 -> 5.5 -> 5.6 と上げるといっ ても難しいので、サービスを止めて mysqldump でど れだけ速く上げられるか。
  9. 9.   Perl Monger さん、お便りありがとうございます。  バージョンアップの決意が 5 年ほど遅かったようで す。バージョンアップそのものもそれなりに大変です が、アプリケーションがそのまま動くかどうかのテストや 改修の方が余程大変だと思います。  わたしも頑張るので Perl Monger さんも頑張ってくだ さい。
  10. 10. はい次のお便り
  11. 11.   yoku0825 さんこんにちは。  私のサービスで使っている MySQL は既にレコード が 3000 万件になり、パーティショニングしても SELECT が重くなってきました。 InnoDB バッファプー ルも Free buffers が 0 です。  そろそろスケールアウトを考えているのですが、どの ような構成が良いでしょうか? ( 30 代・東京都・じゃばー)
  12. 12. ( ゚ д ゚ ) えっ
  13. 13. ● スケールアウトのしどき ● 物理的にメモリー、ストレージが足りない時。 – アプリケーションで水平シャーディングしてやるのが多い。 – 参照局所性が高い場合はメモリーが尽きてるように見えても意 外と大丈夫なこともある。 ● SHOW ENGINE INNODB STATUS のバッファプールヒッ ト率とかを参考に。 ● INSERT, DELETE が重い時はパーティショニングが有効。 – PRIMARY KEY 直打ちのケースしか SELECT は速くならな い。 ● SELECT, UPDATE が重い時は大概そこじゃない。 – イケてないクエリー、イケてないインデックス、イケてないパラ メータ。 – SHOW FULL PROCESSLIST の State を見てみると、 copying to tmp table とか書いてあったりしないかい? – スケールアウトさせてもまたへたれるパターン。
  14. 14. ● スケールアップのしどき ● 物理的にメモリー、ストレージが足りない時。 ● IOPS を上げるようなスケールアップよりは余るまでメモリーを積む 方がコストパフォーマンスが良い。 – RDS や EC2 だとこういう悩みはありそう。 – メモリーを積んでもパフォーマンスが伸びなくなってから、更に パフォーマンスが欲しいなら IOPS 。 – とはいえクエリーが適度にチューニングされているのが前提な のはスケールアウトといっしょ。 – 高 IOPS な感じにするのであれば innodb_{read|write}_thread とか上げるんだけどあんまり情報無い。。前にベンチマークし た時は {12|12} でデフォルトの {4|4} の 2 倍くらいスコア出た。 ● 残念ながら CPU や NIC がネックになるほど綺麗にスキーマ作っ てあってクエリーが綺麗な DB は今のところ見たことがない (´ ・ ω ・` )
  15. 15.  じゃばーさん、お便りありがとうございます。   Free buffers のもうちょっと下にある、 Buffer pool hit rate も見てあげてください。これが 1000/1000 のうちは 取り敢えず大丈夫です。  というか、 SELECT が重いのはまずクエリーを チューニングしましょう。。
  16. 16. はい次のお便り
  17. 17.   yoku0825 さんこんにちは。  私のサービスでは新規のテーブルを作る時には必 ず開発担当同士でスキーマと SQL のレビューをして いますが、先日 DBA が「そのレビューは何をレビュー しているんだ」とケチをつけてきました。  勿論、結果が正しく返ってくるか、インデックスが使 われているかをどうかを確認しているのですが、どうす れば彼に伝わるでしょうか? ( 20 代・東京都・ぺちぱー)
  18. 18. ( ゚ д ゚ ) えっ
  19. 19. ● SQL レビュー? ● 文化な話もあるけれど。 ● 「今」「想定通りのインデックスで」「想定通りの結果が返ってくる」 のは、ある意味当たり前というかなんと言うか。。 ● 今よりレコード件数が増えても、「想定通りのインデックスで」「想定 している範囲のレスポンスで」結果が返ってくることも勘案してくだ さい。 ● EXPLAIN の select_type が DEPENDENT SUBQUERY 、 type が ALL 、 Extra が Using temporary table や Using filesort の場合 は大体件数が伸びると重くなってきます。 – イケてないクエリーはデータの件数が増えれば増えるほど加 速度的に重くなっていくパターンが多いので、テストデータの 件数や分布も大事。
  20. 20.  ぺちぱーさん、お便りありがとうございます。  うるさい場合、「 mysqladmin に innodb_buffer_pool_dump_now インプリメントできな い?」とでも振っておくと勝手にパッチ書き始めて黙る と思います。  ただ、 SQL レビューはもう少しデータが増えた時の ことも考えてやっていただけるとお互い幸せになりま す。よくわからなければ DBA に聞いてください。
  21. 21. はい次のお便り
  22. 22.   yoku0825 さんこんにちは。  最近、親テーブルと子テーブルの間でデータ不整 合が頻発し対応に追われています。  簡単に自動化する方法はあるのでしょうか? ( 30 代・東京都・じゃばー)
  23. 23. ( ゚ д ゚ ) えっ
  24. 24. ● 外部キー制約 ● これ嫌いな人多いですよね。 ● 嫌いな理由ベスト (?)3 は、 – テスト目的などのテキトーなデータを突っ込もうとするとエラー が出る。 ● その操作が不整合の原因になるからやめろってエラーな んですけどね。 – そもそも外部キー制約を追加する ALTER TABLE が転ける。 ● それってつまり既に不整合g – 重くなりそう。 ● tpcc_mysql で試した時には重くなかった。 – 外部キー > セカンダリキー > キーなし – 誤差レベルしか違わなかったけど。 ● これだけじゃなく、適切なトランザクションのコミット単位も大事。
  25. 25.  じゃばーさん、たびたびのお便りありがとうございま す。  不整合を自動で解消するよりも、そもそも不整合を 起こしにくい仕組みを導入しましょう。  というかまず不整合徹底的に直さないと ALTER TABLE できませんので何というか一緒に頑張りましょ う orz
  26. 26. はい次のお便り いつまで続くんだこれ
  27. 27.   yoku0825 さんこんにちは。  このクエリー、速くならない? ( 30 代・東京都・ 831 )
  28. 28. ( ゚ д ゚ ) えっ
  29. 29. ● 相関サブクエリー使ってる ● サブクエリーの内側の WHERE 句で外側クエリーのテーブルのカ ラム参照してるやつ。 – SELECT .., (SELECT .. FROM t2 WHERE t1.xx> t2.yy) FROM t1 .. WHERE .. みたいな。 ● 相関サブクエリーは外側クエリーからフェッチした行数だけサブク エリーを実行するので、外側クエリーのテーブルが大きくなれば なるほど一気に重くなる。 ● CPU 使用率を跳ね上げることが多い。というか CPU 使用率が跳 ね上がったら大量アクセスかこれを疑う。 ● パズルだと思って JOIN に書き換えるか、中間テーブルやアプリ 側に一度値を保持させてクエリーを分割する。 ● EXPLAIN すら返ってこなくなるパターンはほぼこれ。 ● PostgreSQL はこのへんもそつなくこなすイメージ。
  30. 30. ● インデックスが足りない ● MyISAM はテーブルスキャンでも割と速いけれど、そのノリで InnoDB に向かうと地獄が見える。 ● MySQL が 1 つのリレーションで使えるインデックスは基本的に 1 つだけなので、重いクエリーには複合インデックスを作る。 – 基本その 1 、 WHERE 句の AND 条件でつながれているもの を順番に並べる。 – 基本その 2 、それに ORDER BY で使われているカラムを足 す。 – SELECT .. FROM .. WHERE c4= xx AND c2= yy ORDER BY c3 なら、 (c4, c2, c3) – 不等号とか OR 演算子使ったりすると ORDER BY まで波及し ないとか、 LIMIT 使ってるなら WHERE よりも ORDER BY を 狙ってインデックス作ると速いとかこれ以外にもコツはある。 ● 特に COUNT は全てインデックスで解決できないと非常に重い。
  31. 31. ● パラメータがイケてない ● 体感ではこのパターン少ない。 ● innodb_buffer_pool_size は データ格納量 か搭載メモリー全体の 75% くらい突っ込む。 – 仮想マシンで構築する時は、データ格納予想量の 1.35 倍を 割当メモリーにしてる。 ● MyISAM テーブルは key_buffer_size や OS のページキャッシュ を使うので、その分 innodb_buffer_pool_size を下げないといけな い。 – なるべくどちらか片方にした方がメモリーの奪い合いがなくて 良し。 ● SSD などの高速ストレージの場合は innodb_flush_method や innodb_io_capacity でかなり変わる。 ● マウントオプションに noatime 足すのも結構効く。 ● query_cache_type= 1 はこのパターンに入るんだろうか。
  32. 32.   831 さん、お便りありがとうございます。   MySQL はアホの子なので、難しいクエリーを投げ るとなかなか返してくれません。 MySQL でも判るよう な簡単なクエリーに書き換えたり、インデックスでヒント をあげて下さい。  大事なことなのでもう一度言います。 MySQL はア ホの子です。ナントカとハサミは使いようだと思って頑 張ってください。
  33. 33. はい次のお便り
  34. 34.   yoku0825 さんこんにちは。  イケてないクエリーが特定できない時やイケてない 箇所が判らない時ってどーすんべ? ( 30 代・東京都・ 831 )
  35. 35. ( ゚ д ゚ ) えっ
  36. 36. ● そのままではスローログに載らないクエリー ● SET GLOBAL long_query_time= 0.3; SET GLOBAL log_queries_not_using_indexes= 1; とかして 10 分くらいサンプリ ングする。 – 大概死ぬほどスローログ吐くので、 pt-query-digest や mysqldumpslow と併用。 – 予めログをローテートさせておかないと混じって見にくい。 ● pager egrep -v "Sleep|handlersocket|Binlog Dump" からの SHOW FULL PROCESSLIST を連打。 – 個人的にはこれお気に入り。 – TeraTerm 使ってると Recurring Command って設定があるの で、これで 0.5 ~ 1 秒間隔くらいで連続実行させる。 – State に「今やってる処理」が表示されるので、ざっくりあたりを つけられる。
  37. 37. ● どこがイケてないんだかいまいち判らないクエリー ● まずは EXPLAIN – Key で想定しているキーが使われているかどうか、 Key length が想定している長さで使われているか。 ● (int, datetime, varchar(32)) のキーなのに Key length が 4 だと、左端の int にしかキーが効いてない。 – Using filesort は意外と重い。 covering index か ORDER BY 狙いのキーを作る。 ● オプティマイザーは ORDER BY 狙いのキーよりも WHERE 狙いのキーの方を選びたがるので、 USE INDEX でキーを狙い撃ちしてやる。 ● SET profiling= 1; からのクエリー実行からの SHOW PROFILE; – たまに遅い、というようなケースには不向き。 – 内部のステージごとに所要時間が表示されるので、再現性が あるなら最強。 – 5.6 で deprecated に。
  38. 38.   831 さん、お便りありがとうございます。  色々テクニックはあるのですが、深掘りしていくとそ れなりに MySQL そのものの知識が必要になってきた りはします。  いつでも MySQL 専門の DBA に振ってあげてくだ さい。決して説明するのが面倒な訳じゃないです。
  39. 39. はい次のお便り もう 1 つくらいいけるかな
  40. 40.   yoku0825 さんこんにちは。  私はある企業で DBA を勤めていますが、となりの ひとが MySQL をいじってばかりで Oracle や PostgreSQL に触ろうとしません。  どうしたら良いでしょうか? ( 30 代・神奈川県・となりのひと)
  41. 41. ( ゚ д ゚ ) えっ
  42. 42.              (  ゚ д ゚ )           _ (__ つ /  ̄ ̄ ̄ / _               \ /      /
  43. 43.              ( ゚ д ゚ ; )           _ (__ つ /  ̄ ̄ ̄ / _               \ /      /
  44. 44. ちょうど良い時間になりましたので、 今日はこのへんで。。 ` となりのひと ' は俺の上長 (DBA チームのリーダー ) 。。
  45. 45. この番組は弊社 Devs のみなさんの ( 質問の ) 提供で DBA の yoku0825 がお送りいたしました。 See you next time!
  46. 46. ご清聴ありがとうございました 身近に DBA がいない方はぜひ、 日本 MySQL ユーザ会に遊びにきてください!

×