Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
SlideShare a Scribd company logo
MySQL Admin が見た
Devs の常識、 DBA は非常識
2013/09/14
yoku0825@MyNA
PHP Conference 2013
\こんにちは!/
● yoku0825
● とある企業の DBA
● MySQL 歴 5 年くらい
● オラクれない
● ポスグれない
● 嫁の夫
● せがれの父
● 日本 MySQL ユーザ会 (MyNA) のスベり担当
\しゃべること!/
● 日常的に MySQL のソースコードに触れる変態
DBA がフツーの Devs に投げた愛のマサカリ集
( のつもり )
● ウチの開発言語は PHP > Java >> Ruby らしいです
● ウチでは DBA がサーバーの構築、 Devs が設計・
テーブル構築・運営、 DBA はトラブルシュートや改
善提案 ( 運用 ) 、というサイクルで回しています。
それでは Devs からのお便りを
紹介していきます
  yoku0825 さんこんにちは。
 現在 MySQL 4.0 を使用しているサービスがあるの
ですが、このたびサーバーのリプレースに伴い
MySQL 5.6 を導入したいと思っています。
 最新版なので特に問題なく移行できると考えていま
すが、注意するポイントなどがあれば教えて下さい。
( 30 代・東京都・ Perl Monger )
( ゚ д ゚ ) えっ
●
レプリケーションを使ったバージョンアップ
●
旧バージョンのスレーブがある場合、マスターのバージョンアップ
をかける前に 1 台ずつ切り離してバージョンアップしておく。
● スレーブを全部バージョンアップできたら、新バージョンのスレー
ブ 1 台を使ってカスケードレプリケーション構成にしておく。
●
どこかのタイミングで新バージョンのスレーブをマスターとして参
照するように切り替える。
● 旧マスターをバージョンアップして新マスターのスレーブにしてし
まう。
●
停止時間は切り替え時間だけで済む。
●
オフラインバージョンアップ
● データファイルに互換性があれば、 mysqld 停止 ⇒ バイナリー入
れ替え ⇒ 起動 ⇒ mysql_upgrade で OK 。
● データファイルの互換性がなければ mysqldump でダンプして新しい
mysqld にリストアする(最後の手段)
● ダンプの SQL 自体互換性がなくてちょっといじらないといけない
場合も。
● 基本的にレプリケーション , オフラインバージョン
アップできるのは 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 でど
れだけ速く上げられるか。
  Perl Monger さん、お便りありがとうございます。
 バージョンアップの決意が 5 年ほど遅かったようで
す。バージョンアップそのものもそれなりに大変です
が、アプリケーションがそのまま動くかどうかのテストや
改修の方が余程大変だと思います。
 わたしも頑張るので Perl Monger さんも頑張ってくだ
さい。
はい次のお便り
  yoku0825 さんこんにちは。
 私のサービスで使っている MySQL は既にレコード
が 3000 万件になり、パーティショニングしても
SELECT が重くなってきました。 InnoDB バッファプー
ルも Free buffers が 0 です。
 そろそろスケールアウトを考えているのですが、どの
ような構成が良いでしょうか?
( 30 代・東京都・じゃばー)
( ゚ д ゚ ) えっ
●
スケールアウトのしどき
●
物理的にメモリー、ストレージが足りない時。
– アプリケーションで水平シャーディングしてやるのが多い。
– 参照局所性が高い場合はメモリーが尽きてるように見えても意
外と大丈夫なこともある。
● SHOW ENGINE INNODB STATUS のバッファプールヒッ
ト率とかを参考に。
● INSERT, DELETE が重い時はパーティショニングが有効。
– PRIMARY KEY 直打ちのケースしか SELECT は速くならな
い。
● SELECT, UPDATE が重い時は大概そこじゃない。
– イケてないクエリー、イケてないインデックス、イケてないパラ
メータ。
– SHOW FULL PROCESSLIST の State を見てみると、 copying
to tmp table とか書いてあったりしないかい?
– スケールアウトさせてもまたへたれるパターン。
●
スケールアップのしどき
●
物理的にメモリー、ストレージが足りない時。
● IOPS を上げるようなスケールアップよりは余るまでメモリーを積む
方がコストパフォーマンスが良い。
– RDS や EC2 だとこういう悩みはありそう。
– メモリーを積んでもパフォーマンスが伸びなくなってから、更に
パフォーマンスが欲しいなら IOPS 。
– とはいえクエリーが適度にチューニングされているのが前提な
のはスケールアウトといっしょ。
– 高 IOPS な感じにするのであれば innodb_{read|write}_thread
とか上げるんだけどあんまり情報無い。。前にベンチマークし
た時は {12|12} でデフォルトの {4|4} の 2 倍くらいスコア出た。
● 残念ながら CPU や NIC がネックになるほど綺麗にスキーマ作っ
てあってクエリーが綺麗な DB は今のところ見たことがない
(´ ・ ω ・` )
 じゃばーさん、お便りありがとうございます。
  Free buffers のもうちょっと下にある、 Buffer pool hit
rate も見てあげてください。これが 1000/1000 のうちは
取り敢えず大丈夫です。
 というか、 SELECT が重いのはまずクエリーを
チューニングしましょう。。
はい次のお便り
  yoku0825 さんこんにちは。
 私のサービスでは新規のテーブルを作る時には必
ず開発担当同士でスキーマと SQL のレビューをして
いますが、先日 DBA が「そのレビューは何をレビュー
しているんだ」とケチをつけてきました。
 勿論、結果が正しく返ってくるか、インデックスが使
われているかをどうかを確認しているのですが、どうす
れば彼に伝わるでしょうか?
( 20 代・東京都・ぺちぱー)
( ゚ д ゚ ) えっ
● SQL レビュー?
● 文化な話もあるけれど。
● 「今」「想定通りのインデックスで」「想定通りの結果が返ってくる」
のは、ある意味当たり前というかなんと言うか。。
●
今よりレコード件数が増えても、「想定通りのインデックスで」「想定
している範囲のレスポンスで」結果が返ってくることも勘案してくだ
さい。
● EXPLAIN の select_type が DEPENDENT SUBQUERY 、 type
が ALL 、 Extra が Using temporary table や Using filesort の場合
は大体件数が伸びると重くなってきます。
– イケてないクエリーはデータの件数が増えれば増えるほど加
速度的に重くなっていくパターンが多いので、テストデータの
件数や分布も大事。
 ぺちぱーさん、お便りありがとうございます。
 うるさい場合、「 mysqladmin に
innodb_buffer_pool_dump_now インプリメントできな
い?」とでも振っておくと勝手にパッチ書き始めて黙る
と思います。
 ただ、 SQL レビューはもう少しデータが増えた時の
ことも考えてやっていただけるとお互い幸せになりま
す。よくわからなければ DBA に聞いてください。
はい次のお便り
  yoku0825 さんこんにちは。
 最近、親テーブルと子テーブルの間でデータ不整
合が頻発し対応に追われています。
 簡単に自動化する方法はあるのでしょうか?
( 30 代・東京都・じゃばー)
( ゚ д ゚ ) えっ
●
外部キー制約
●
これ嫌いな人多いですよね。
● 嫌いな理由ベスト (?)3 は、
– テスト目的などのテキトーなデータを突っ込もうとするとエラー
が出る。
●
その操作が不整合の原因になるからやめろってエラーな
んですけどね。
– そもそも外部キー制約を追加する ALTER TABLE が転ける。
●
それってつまり既に不整合g
– 重くなりそう。
● tpcc_mysql で試した時には重くなかった。
– 外部キー > セカンダリキー > キーなし
– 誤差レベルしか違わなかったけど。
●
これだけじゃなく、適切なトランザクションのコミット単位も大事。
 じゃばーさん、たびたびのお便りありがとうございま
す。
 不整合を自動で解消するよりも、そもそも不整合を
起こしにくい仕組みを導入しましょう。
 というかまず不整合徹底的に直さないと ALTER
TABLE できませんので何というか一緒に頑張りましょ
う orz
はい次のお便り
いつまで続くんだこれ
  yoku0825 さんこんにちは。
 このクエリー、速くならない?
( 30 代・東京都・ 831 )
( ゚ д ゚ ) えっ
●
相関サブクエリー使ってる
● サブクエリーの内側の WHERE 句で外側クエリーのテーブルのカ
ラム参照してるやつ。
– SELECT .., (SELECT .. FROM t2 WHERE t1.xx> t2.yy)
FROM t1 .. WHERE .. みたいな。
●
相関サブクエリーは外側クエリーからフェッチした行数だけサブク
エリーを実行するので、外側クエリーのテーブルが大きくなれば
なるほど一気に重くなる。
● CPU 使用率を跳ね上げることが多い。というか CPU 使用率が跳
ね上がったら大量アクセスかこれを疑う。
● パズルだと思って JOIN に書き換えるか、中間テーブルやアプリ
側に一度値を保持させてクエリーを分割する。
● EXPLAIN すら返ってこなくなるパターンはほぼこれ。
● PostgreSQL はこのへんもそつなくこなすイメージ。
●
インデックスが足りない
● 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 は全てインデックスで解決できないと非常に重い。
●
パラメータがイケてない
●
体感ではこのパターン少ない。
● 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 はこのパターンに入るんだろうか。
  831 さん、お便りありがとうございます。
  MySQL はアホの子なので、難しいクエリーを投げ
るとなかなか返してくれません。 MySQL でも判るよう
な簡単なクエリーに書き換えたり、インデックスでヒント
をあげて下さい。
 大事なことなのでもう一度言います。 MySQL はア
ホの子です。ナントカとハサミは使いようだと思って頑
張ってください。
はい次のお便り
  yoku0825 さんこんにちは。
 イケてないクエリーが特定できない時やイケてない
箇所が判らない時ってどーすんべ?
( 30 代・東京都・ 831 )
( ゚ д ゚ ) えっ
●
そのままではスローログに載らないクエリー
● 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 に「今やってる処理」が表示されるので、ざっくりあたりを
つけられる。
●
どこがイケてないんだかいまいち判らないクエリー
● まずは 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 に。
  831 さん、お便りありがとうございます。
 色々テクニックはあるのですが、深掘りしていくとそ
れなりに MySQL そのものの知識が必要になってきた
りはします。
 いつでも MySQL 専門の DBA に振ってあげてくだ
さい。決して説明するのが面倒な訳じゃないです。
はい次のお便り
もう 1 つくらいいけるかな
  yoku0825 さんこんにちは。
 私はある企業で DBA を勤めていますが、となりの
ひとが MySQL をいじってばかりで Oracle や
PostgreSQL に触ろうとしません。
 どうしたら良いでしょうか?
( 30 代・神奈川県・となりのひと)
( ゚ д ゚ ) えっ
             (  ゚ д ゚ )
          _ (__ つ /  ̄ ̄ ̄ / _
              \ /      /
             ( ゚ д ゚ ; )
          _ (__ つ /  ̄ ̄ ̄ / _
              \ /      /
ちょうど良い時間になりましたので、
今日はこのへんで。。
` となりのひと ' は俺の上長 (DBA チームのリーダー ) 。。
この番組は弊社 Devs のみなさんの ( 質問の ) 提供で
DBA の yoku0825 がお送りいたしました。
See you next time!
ご清聴ありがとうございました
身近に DBA がいない方はぜひ、
日本 MySQL ユーザ会に遊びにきてください!

More Related Content

Devsの常識、DBAは非常識