MySQL トラブル解析入門
@第5回中国地方DB勉強会 
奥野 幹也 
Twitter: @nippondanji 
mikiya (dot) okuno (at) gmail (dot) com
免責事項 
● 本プレゼンテーションにおいて示されている見 
解は、私自身の見解であって、オラクル・コー 
ポレーションの見解を必ずしも反映したもので 
はありません。ご了承ください。
自己紹介 
● MySQL サポートエンジニア 
– 日々のしごと 
● トラブルシューティング全般 
● Q&A回答 
● パフォーマンスチューニング 
など 
● ライフワーク 
– 自由なソフトウェアの普及 
● オープンソースではない 
● ブログ 
今日は個人として 
参加しています。 
– 漢のコンピュータ道 
– http://nippondanji.blogspot.com/
DBAみんなの願い 
枕を高くして眠りたい。
安心を得るためには・・・ 
トラブルシューティングが 
重要!!
アジェンダ 
● MySQL でよくある問題の傾向と対策 
– SQL の結果がおかしい 
– 文字化け 
– レプリケーションの諸問題 
– クラッシュ 
– データ破壊 
– デッドロック 
etc 
● ツールを使いこなす!! 
– SHOW コマンド、INFORMATION_SCHEMA 
– ログ 
etc
SQL の結果がおかしい!!
SQL がエラーになる 
● プログラムのソースコードを見ただけでは分からないことが 
多い。 
– 一般クエリログやlong_query_time=0 にしたスローク 
エリログがクエリの特定に役立つ 
– 理想的には、SQL を実行してエラーになったときアプリ 
ケーションがログを取るようにしておく。 
– 実際にエラーになったSQL を実行してみる。 
● エラーの原因と対処は千差万別
一般クエリログ 
● MySQL サーバーに対して投げられたリクエストを全て記録 
する。 
● 実際に実行されたクエリを見ることができるので、アプリ 
ケーションのデバッグに役立つ。 
– SQL がエラーになろうがなるまいが記録される。 
● 動的に有効・無効を切り替え可能。 
– SET GLOBAL general_log=ON; 
● 出力先はファイルまたはテーブル。
期待通りの結果が返らない 
● MySQL のバグの可能性 
– 別のストレージエンジンを使って試してみる 
– EXPLAIN で実行計画を見る 
● インデックスヒントを使って実行計画を変更してみる 
● 最適化オプションのON/OFF 
– 問題が起きる最小のデータとクエリを突き止める 
● バグ登録 
● そもそもそのSQL は正しいか? 
– 複雑なSQL はシンプルなパーツに分けてみる 
– リレーショナルモデルに沿って考える 
● いつから問題が起きているか? 
– テーブルのメンテナンスやアップグレードはおこなったか 
– アプリケーションの改修をしたか
文字化け
MySQL サーバー内の文字コード変換 
テーブルセッションクライアント 
MySQLサーバー 
①送信する 
SQL文に対する 
文字コード 
③クエリの 
実行結果に対する 
文字コード 
②クエリの実行 
に利用する 
文字コード 
④データを 
蓄える際の 
文字コード 
⑤テーブル名や 
カラム名に対する 
文字コード 
⑥ファイル名を 
解決する際の 
文字コード 
ファイルシステム出展:エキスパートのための MySQL 
[運用+管理]トラブルシューティングガイド
文字コードを確認する 
● SHOW [GLOBAL] STATUS LIKE 'char%'; 
– character_set_client 
– character_set_connection 
– character_set_results 
– character_set_server/character_set_database 
– character_set_system 
– character_set_filesystem 
● アプリケーションから実行してみる 
– ドライバの設定(接続プロパティ)に問題はないか
文字化けの原因と対策 
● 接続用の文字コードは問題ないか? 
– アプリケーションが期待している文字コードとドライバの文 
字コードは同じか? 
● 端末の文字コードは問題ないか? 
– chcp (Windows ) /locale ( UNIX系OS ) 
– MySQL 標準クライアントの場合は—default­character­set 
を指定。ただし­­skip­character­set­client­handshake 
がサーバで設定されていると無効。 
(要注意!) 
– charset utf8 
● テーブル内のデータは問題ないか? 
– latin1 でマルチバイト文字を格納してしまった。 
● 正しい文字コードを指定して取り出すと化ける。 
– いったんbinary としてバックアップ。
テーブルの文字コード 
● カラムごとに文字コードを指定可能 
– SHOW CREATE TABLE で確認 
● INFORMATION_SCHEMA を利用すると一括で調べられ 
る 
– SELECT * FROM COLUMNS 
WHERE CHARACTER_SET_NAME != 'utf8';
Connector/J の留意点 
● 文字コードはcharacterEncoding プロパティで指定 
● 文字コードの指定がない場合には接続先サーバーの 
character_set_server により決定。接続後SET NAMES 
をドライバが実行。 
● ­­skip­character­set­client­handshake 
は効かない 
● characterEncoding が何であれ、Java内部で文字列 
のエンコーディングはucs2 に変換される。
LOAD DATA INFILE 
● LOAD DATA INFILE 
– ファイルの文字コードがcharacter_set_database に 
なっていることを期待している 
– SET character_set_database = cp932; 
– テーブルの文字コードと同じ場合にはbinary を指定する 
と変換が生じないので高速 
– LOAD DATA INFILE ではなくmysqlimport を使う手も 
ある 
● SELECT … INTO OUTFILE 
– デフォルトでは文字コード変換しない 
● LOAD DATA で読むときはbinary を指定すると良い 
– LOAD DATA で読む段階のことまで考えておく 
● SELECT … INTO OUTOFILE 'file_name' 
CHARACTER SET charset_name …
レプリケーション
レプリケーションの仕組み 
クライアント 
同じデータに同じ更新を適用した結果は同じ 
マスタースレーブ 
マスター 
スレッド 
スレーブI/O 
スレッド 
スレーブ 
SQL スレッド 
更新内容 
を記録 
接続スレッド 
更新更新 
読み込み 
転送 
記録 
読み 
込み 
テーブルバイナリログリレーログテーブル
バイナリログ 
● 全ての更新を記録するためのログ 
– 元々はSQL 文を直接記録しておくものだった 
● バイナリ(テキストではない)のヘッダ+ SQL文 
– MySQL 5.1 からSQL を実行した結果(行)を記録するこ 
とが可能に 
● インデックスファイル 
– バイナリログファイル名を記録 
● msyql­bin. 
index 
● バイナリログファイル 
– 連番のついたファイル 
● mysql­bin. 
000001 
– 中身はマジックナンバー+イベント
バイナリログの種類 
ステートメントベース 
● SQL 文を直接記録する 
● データサイズの効率が良い 
● 非決定性のステートメントは含める 
ことができない 
● 従来からある実装 
行ベース 
● データそのものを記録する 
● クエリの種類を問わず対応可能 
● 行ベースしか対応していないスト 
レージエンジンもある 
● 5.1 から利用可能 
MIXED 
● ステートメントベースと行ベースを状況に応じて使い分ける 
● 通常はSBR 、非決定性のステートメントはRBR
SQL スレッドの停止 
● スレーブ上のテーブルを更新してしまった。 
– マスターのデータからリストア 
● スレーブのクラッシュでポジションが巻き戻ってしまった 
– マシンがクラッシュした場合に起こりがち 
– 重複キーエラーに 
– マスターのデータからリストア 
● バイナリログ欠損 
– マスター上で失われた情報はどこにもない!! 
– 全て再セットアップ 
● 一時的なエラーなら 
– mysql> SET GLOBAL SQL_SLAVE_SKIP_COUNTER = N; 
– mysql> START SLAVE;
I/O スレッドの停止 
● ネットワークのエラー。 
● マスターがダウンした。 
● max_allowed_packet が足りない。 
● ユーザがログイン出来ない。 
– ユーザのパスワードを変更してしまった? 
– エラーログを調査。
SHOW SLVAE STATUS 
● Slave_IO_Running: I/O スレッドが動作中かどうか 
● Slave_IO_State: I/O スレッドのステータス 
● Slave_SQL_Running: SQL スレッドが動作中かどうか 
● Master_Log_File: I/O スレッドのバイナリログファイル名 
● Read_Master_Log_Pos: I/O スレッドのポジション 
● Relay_Master_Log_File: SQL スレッドのバイナリログファイル名 
● Exec_Master_Log_Pos: SQL スレッドのポジション 
● Seconds_Behind_Master: 遅延(後述) 
● Last_Error: 最後に発生したエラー 
● Last_Errno: 最後に発生したエラーの番号 
● Skip_Counter: エラーを無視する回数 
● Replicate_*: フィルタ
SHOW MASTER STATUS 
● バイナリログに関する情報を表示する 
– File: 現在更新中のバイナリログファイル名 
● デフォルトでは hostname.000001 から始まる連番の 
ファイル名 
– Position: 現在のバイナリログポジション 
– Binlog_Do/Ignore_DB: フィルタ 
– Executed_Gtid_Set: これまでに実行したGTID 
● マスターとスレーブのバイナリログポジションを見比べる
レプリケーションの遅延 
● Seconds_Behind_Master とは 
– I/O スレッドによる遅延+SQL スレッドによる遅延+ ズレ 
– レプリケーション開始時に時計のズレを検出 
– ネットワークが停止するとI/O スレッドの遅延は分からな 
い 
● 後から急激な時差を検出する場合がある 
● レプリケーションハートビート 
– あくまでも近似値!! 
● I/O スレッドの遅延 
– ネットワークの問題 
– リレーログの書き込みを同期( sync_relay_log ) 
● SQL スレッドの遅延 
– SQL の実行に時間がかかる 
– 更新/削除するデータがキャッシュに存在しない
クラッシュセーフなスレーブ 
● MySQL 5.6 からスレーブがクラッシュしてもレプリケーション 
の再開に支障を来すことがなくなった。 
InnoDB 
クラッシュセーフ 
レプリケーション情報 
= 
relay_log_info ファイル 
クラッシュセーフではない 
InnoDB 
レプリケーション情報 
= 
mysql.slave_relay_log_info 
テーブル 
クラッシュセーフ 
MySQL 5.5以前MySQL 5.6
レプリケーションによるHA 
● 利点 
– 共有ディスク型のHA と違ってリカバリ不要! 
● 超高速フェイルオーバー 
– レプリケーションはデフォルトで使える機能 
● 課題 
– 非同期だから最後に更新したデータを一部失う覚悟が必 
要。 
● 準同期レプリケーション 
– 1:N 構成では昇格に工夫が必要。 
● GTID
準同期レプリケーション 
クライアント 
クライアントへ応答が返った時点で 
スレーブへバイナリログの転送は完了している。 
マスタースレーブ 
マスター 
スレッド 
スレーブI/O 
スレッド 
スレーブ 
SQL スレッド 
9. send_ok 
8. ack 
2.更新内容 
を記録 
4.読み込み 
5.転送 
6.記録 
7-2. 
更新の 
適用 
1. COMMIT 
接続スレッド 
3.更新 
7-1. ack 
テーブルバイナリログリレーログテーブル
Global Transaction ID 
● トランザクションを一意に識別することができるID 
– UUID: トランザクションID の形式で表現される 
● 例) 095E0FF8­18AF­11E2­9E7C­5C260A2AA986: 
123456 
– バイナリログ内に記録 
● スレーブでもバイナリログを有効化 
● log_slave_updates = 1 
● トランザクションID はシーケンス 
– 1:N 環境で、どのスレーブが最も進んでいるか一目瞭然! 
● 昇格の手順は簡単 
– 最も進んでいるスレーブを新しいマスターに 
– CHANGE MASTER TO … MASTER_AUTO_POSITION = 1
msyqlfailover 
● 1:N のレプリケーションで使うツール 
– サーバーの死活監視 
– マスターがFail したときに新たにスレーブを自動で昇格 
● 最も進んだスレーブを検出 
● CHANGE MASTER TO … MASTER_AUTO_POSITION = 1 
● MySQL Utilities に付属 
– Python製
レプリケーション安定化計画 
● ステートメントベースはリスクがある 
– テンポラリテーブルは使わない。 
● テンポラリテーブル作成後にSQL スレッドが停止する 
と、再セットアップが必要になる。 
– Non­deterministic 
なSQL でエラーになる。 
● マスターだけを豪華にし過ぎない 
– マスターとスレーブは同じ量の更新が発生する。 
– ハードウェア、バッファは同じ程度に設定しておく。
レプリケーション安定化計画(つづき) 
● マスタークラッシュ時 
– バイナリログの欠損を防ぐ。 
● MySQL 5.6 + sync_binlog=1 
● 1:N構成では準同期+GTID で昇格を自動化 
– MySQL 5.6 
– mysqlfailover で自動的に昇格 
● クラッシュセーフなスレーブを利用する 
– MySQL 5.6
クラッシュ
クラッシュを誘発するシグナルの種類 
● SIGSEGV 
– プログラムが無効な(セグメント境界を超えた)メモリアド 
レスへアクセスした。 
– バグやデータ破壊の可能性。 
● SIGABRT 
– プログラムがabort(3) を呼び出した。 
– アサーション失敗。バグやデータ破壊の可能性。 
● SIGBUS 
– 無効な物理メモリアドレスへアクセスした。 
– メモリアライメントの問題やハードウェアの故障など。 
● メモリアライメントに問題があるのはバグ 
● メモリアライメントが必要かどうかはCPU次第( SPARC 
など)
エラーログ 
● クラッシュ時にはスタックトレースなどの情報がエラーログ 
に記録される 
– デフォルトではコアファイルが生成されないので、エラーロ 
グが唯一の手がかりに。 
– シグナルの種類が判別可能。 
– クラッシュ後にリカバリが行われているかの判定も重要。 
● エラーログは超重要 
– クラッシュ時以外にも何か問題が起きたらまず見る。 
– 実は標準出力をリダイレクトしたもの。 
– /path/to/datadir/hostname.err 
● /var/log 配下にあることも。 
– サポートへ送るときは編集せずに!!
コア解析 
● GDB などのデバッグツールを使って行う 
● コア解析はいわば検死解剖 
– 直接の死因は分かるがそれがどのように引き起こされた 
かまでは分からないことが多い 
● データ破壊によるクラッシュが起きた場合、なぜデータ 
は壊れたのか?という原因はコア解析では分からないこ 
とが多い。 
● ソースコードの理解が不可欠 
– サポートへ依頼して頂きたい。
データの破損
データ破壊の概要 
● 特にクラッシュ時によく起きる 
– ファイルシステムキャッシュにデータが残っている間にOS 
ごとダウンした場合などは危険 
● データ保護の実装はストレージエンジン次第 
– トランザクション対応のストレージエンジンはクラッシュリカ 
バリあり 
● InnoDB 
● MySQL Cluster 
– トランザクション非対応のストレージエンジンはクラッシュリ 
カバリなし 
● MyISAM 
● ARCHIVE
MyISAM 
● OS やMySQL サーバーのクラッシュ時にデータが壊れるか 
も知れないのは仕様です。 
– トランザクションに対応していないため。 
– OLTP系の処理には不向き。 
● 対策 
– バックアップやレプリケーションなどでデータを複製してお 
く。 
– データロストが発生するのは諦める。 
– REPAIR TABLE コマンドで復旧を試みる。 
● ただし、確実に直るという保証はない。
InnoDB 
● 原因 
– クラッシュなどによって簡単には壊れない 
● ログ(WAL )とダブルライトバッファ 
– ハードウェアのエラーには耐えられない 
● ディスク交換後にリストア 
– バグ 
– オペミス 
● 復旧方法 
– innodb_force_recovery=4 または 6 
– 問題のテーブルまたは全体をmysqldump ( 6 の場合は全体) 
– テーブルをDROP またはデータディレクトリ初期化 
– innodb_fource_recovery オプションを解除して再起動。 
– リストア 
● 対策 
– バックアップやレプリケーションで鉄壁の防御を!
Out of Memory
mysqldがメモリ不足で停止する 
● 32bit バージョンのプログラムはもう使わない!! 
– 論理アドレス枯渇によるOut Of Memory がよく起こる。 
– RSS が1GB程度でも起こる。 
● 割り当て/解放の繰り返しによりフラグメンテーションが 
発生するからVSIZE が大きくなってしまう。 
– Linux では3GB まで、Windows では2GB まで。 
● ulimit 
● バッファの割り当てすぎ。 
– 特にセッションごとのバッファが大きすぎる場合が多 
い。tmp_table_size=64M など。 
● カーネルの設定など 
– FreeBSD … kern.maxdsiz 
– HP­UX 
… maxdsiz_64bit
OOM Killer 
● Linux上でメモリが足りなくなった時にプロセスを終了させ 
る。 
● エラーメッセージがなく突然mysqld が終了している場合 
に疑ってみるべし。 
– OOM Killer が発動したことはsyslog に記録が残る 
– 夜間バッチなどでmysqld またはそれ以外のプロセスが 
大量にメモリを消費していないか? 
● echo ­17 
> /proc/pid/oom_score_adj
デッドロック
デッドロックは障害ではない! 
● トランザクションにはつきもの。理論上回避不能。 
TX1 TX2 
blocked 
blocked
デッドロック対策 
● デッドロックは起きるもの。根絶することはできない。 
– トランザクションが保証しているのは、実行した結果が 
Commit かAbort になるということ。失敗する( Abort ) 
可能性はゼロにできない。 
● InnoDB はデッドロック検出機能あり 
– 片方のトランザクションを強制的にロールバック 
● リトライ処理 
– 発生したら黙ってリトライ。リトライのロジックは必須 
– 他の例外処理とまとめて実装すると良い。 
● 行へアクセスする順序を工夫する 
– 主キーの順でアクセスするなど 
– デッドロックが頻発するケースではテーブルロックも有用
Lock wait timeout 
● ロックを長時間獲得出来なかった時に生じる現象 
– デッドロックではない 
– UPDATE やDELETE に時間がかかり、ロックを待っていた 
他のトランザクションがタイムアウトする 
– InnoDB のデッドロック検出機能は100% ではない 
– NDB にはデッドロック検出機能はないので必ずLock­wait­timeout 
になる。(見極めが難しい) 
● 対策 
– リトライ!! 
– 大量のレコードを一度に更新する処理を改める 
● バッチ系の処理はこまめに分けて更新する 
● テーブルロックをかけてから実行する 
– Lock wait timeout は発生しないが処理が待たされる
パフォーマンス
クエリが遅い 
● 適切なインデックスが使われていない 
– テーブルスキャンが発生している 
– 複合インデックスが必要なのに作成されていない 
● クエリの効率がよくない 
– サブクエリではなくJOIN を 
– クエリが複雑になるのはテーブル設計がよくない兆候かも? 
● 同時実行数が多すぎる 
– >CPU コア数 
● バッファプールが足りない
スロークエリログ 
● 実行に時間がかかったクエリを記録する 
– long_query_time で閾値を指定 
– long_query_time=0 で全てのクエリを記録 
– log_queries_not_using_indexes でインデックスを使っ 
ていないクエリを全て記録 
● 出力先はログまたはテーブル 
– log_output=TABLE 
● ログファイルはmysqldumpslow コマンドで解析
Too many connections 
● ボトルネックが原因でクエリが処理できない 
– 処理の完了待ちの接続が増加 
– max_connections へ到達 
– Too many connections!! 
● ボトルネックの特定が重要 
– テーブルロックの競合(MyISAM ) 
– 行ロックの競合( InnoDB ) 
– 更新が多い場合のログへの書き込み 
– クエリの効率が悪すぎる 
– CPU リソースの枯渇 
– バッファが足りない 
etc
クエリのチューニング 
● EXPLAIN から実行計画を読み取る 
– クエリの構造、インデックス、レコードアクセスタイプ、行数 
● インデックスを付け替える 
● オプティマイザの挙動を理解する 
– アルゴリズム: NLJ 、BNLJ 、BKAJ 、ICP 、ECP など 
– ヒント:使用するインデックスの指定、JOIN の順序固定
ツールを使いこなす。
SHOW コマンド 
● 設定値 
– SHOW GLOBAL VARIABLES 
● 統計情報 
– SHOW GLOBAL STATUS 
● レプリケーション情報 
– SHOW SLAVE STATUS 
– SHOW MASTER STATUS 
● InnoDB の情報 
– SHOW ENGINE INNODB STATUS 
● 
● テーブル定義 
– SHOW CREATE TABLE 
etc...
INFORMATION_SCHEMA 
● SHOW コマンドをも凌駕する情報量 
– バージョンを追うごとに内容が充実 
– SHOW コマンドでは得られない情報多数 
● SELECT でアクセス可能 
– 必要な情報を得るため柔軟に絞り込みが可能 
– JOIN 、サブクエリを利用可能 
– GROUP BY による統計 
– CASE 句による柔軟な出力 
● よく使うSELECT にビューを定義可能 
– 作業の効率化
PERFORMANCE_SCHEMA 
● パフォーマンス統計用のカウンタの集合体 
– かなり細かいデータまで取れる 
– バージョンを追うごとに拡充 
– メモリ消費大なので注意 
● ストレージエンジンとして実装されている 
– 設定用のテーブルもある( UPDATE で設定) 
● ps_helper 
– PERFORMANCE_SCHEMA を活用するためのビュー集 
– http://www.markleith.co.uk/ps_helper/ 
● MySQL Workbench 
– GUI からps_helper を利用
ログ 
● エラーログ 
– 問題が起きたらまず見るべき 
– クライアントへ返されたエラーは記録されない 
● クライアント側でログを持っておくと便利 
● 一般クエリログ 
– MySQL サーバーへ送られたリクエストが記録される 
– アプリケーションのデバッグ用 
● スロークエリログ 
– 時間がかかったクエリが記録される 
● バイナリログ 
– レプリケーションやPIT リカバリに利用される
デバッグ版 
● デバッグ版の入手方法 
– バイナリ版ならmysqld­debug 
● ソースコード 
– — 5.1 configure … ­­with­debug 
– 5.5 — cmake … ­DWITH_ 
DEBUG 
● DBUG パッケージによるトレースが可能 
– my.cnf にてdubug オプションを記述 
– mysqld のコードパスが一目瞭然 
● アサーションが通常版よりも多い
OS の情報を見る 
● 統計情報( UNIX系OS ) 
– mpstat 、vmstat 、iostat 、top 
● 最近話題のdstat 
– /proc ファイルシステム 
● システムの情報を一括で取得 
– Windows 
● アクセサリ>システム>システム情報 
● systeminfo コマンド 
– OSX 
● system_profiler 
– Oracle Solaris 
● Oracle Explorer Data Collector 
– Linux 
● sosreport
MySQL Enterprise Monitor 
● MySQL専用の商用監視ツール 
– 200 を超えるアドバイザルールが総合的にヘルスチェック 
– メール、SNMP による通知 
– システムリソースや使用状況をグラフで表示 
– パフォーマンス解析の強い味方 
● 最強のモニタリング機能 
– レプリケーションモニター 
– クエリアナライザ 
http://www­jp. 
mysql.com/products/enterprise/monitor.html
商用サポート 
● 解析のプロが責任をもってお答えします!! 
– 自ら解析できる場合でも時間の節約に 
● 商用ツールが利用可能( Enterprise Edition ) 
– MySQL Enterprise Monitor 
– MySQL Enterprise Backup 
– ThreadPool プラグイン 
– 認証プラグイン 
● 24時間365 日のサポート 
– ただし日本語は平日9時—5時のみ(緊急時は英語で 
問い合わせ)
トラブルを 
未然に防ぐ!!
運用のベストプラクティス 
一、 バックアップはしっかり計画的に! 
二、 本番投入前に必ずアプリケーションのテストを。 
● 負荷に見合ったハードウェアを選定。 
三、 要件に合致した高可用性構成をチョイス。 
● スタンドアロン? HA ?レプリケーション? MySQL Cluster ? 
● ディザスタリカバリは必要か? 
四、 もしもの時の保険=サポート 
五、 セキュリティは万全に。 
六、 監視は抜かりなく。 
● トラブル、キャパシティ、性能 
● 全部まとめてMySQL Enterprise Monitor はいかが? 
七、 メンテナンスは無理のない計画+周到な準備を。
参考:対策とダウンタイムの目安 
対策要件ダウンタイムの目安 
バックアップからのリストアバックアップの取得データ量次第だが数時間— 
クラッシュリカバリサーバー1台 
InnoDBの利用 
数分—数十分 
HA クラスタのフェイルオーバーサーバー2台 
共有ストレージ 
数分—数十分 
MySQL Cluster のフェイルオーバーサーバー3台以上 
ネットワーク冗長化 
—数秒 
レプリケーションのフェイルオーバーサーバー2台以上数秒程度
メンテナンス計画
メンテナンスの種類 
● テーブルのメンテナンス 
– インデックスやカラムの追加・削除 
– データ型変更 
– 古いデータの破棄 
– テーブルの破損 
● アップグレード 
– バグ修正 
– 新しいバージョンの新機能を使いたい 
● システム構成の変更 
– オプションの変更 
– ディスクやCPU 、メモリの強化
テーブルのメンテナンス 
● テーブル定義変更 
– MySQL 5.6 からInnoDB はオンラインDDL対応 
● インデックスの追加・削除等がオンライン( Inplace ) 
● コピーが必要なケースは従来の動作 
– ALTER TABLE は更新がブロックされる 
– データを古いテーブルから新しい型のテーブルにコピー 
– InnoDB Plugin/MySQL 5.5 のInnoDB ではインデック 
ス部分だけを再構築( Fast Index Creation ) 
– MySQL Cluster はオンラインスキーマ変更に対応 
● 古いデータの破棄 
– RANGE パーティショニング 
– DELETE を使う場合はこまめにCOMMIT 
● OPTIMIZE 、ANALYZE etc
アップグレード 
● 失敗しないためには周到な準備を! 
– アップグレード後の動作確認 
– 作業時間の見積もり 
● 本番環境と同じデータを使って手順を確認 
● レプリケーションの活用でダウンタイム縮小 
– スレーブのバージョン > マスターのバージョン 
– メジャーバージョンの差はひとつまで 
– 手順 
● スレーブをひとつずつアップグレード後、スレーブのひと 
つをマスターに昇格 
● 旧マスターを構成から切り離してアップグレード 
● 必要があれば旧マスターへ切り戻し
まとめ
トラブルシューティングのポイント 
● 何が起きているのかを見極める。 
– 仕様を理解する。 
● 何が正常で何が異常なのか? 
– OS に詳しくなる。 
● 問題がOS からやってくることも多い。 
– 自分でやってみる。 
● 再現が出来ればこちらのもの! 
● 的確に対策をする。 
– 仕組みから何故対策が有効なのかを説明できる。 
● トラブルに備える。 
– トラブルに強い設定。 
– トラブルが起きてもダメージが少ないようにする。
宣伝:もっと詳しくなりたい方へ
宣伝2:新書籍の紹介 
● リレーショナルデータベース実践入門(仮) 
– リレーショナルモデル、SQL 、そしてDB 設計が主なテー 
マの書籍です。 
– どうやってリレーショナルデータベースを使いこなすか! 
● リレーショナルモデル基礎編 
– SQL とリレーショナルモデル 
– 述語論理とリレーショナルモデル 
– 正規化1: 関数従属性 
– 正規化2: 結合従属性 
– 直交性 
– ドメインの設計 
etc 
● アプリケーション開発実践編 
基礎の基礎から 
よくある間違いを 
指摘しつつ 
– 履歴 
– グラフ 
– インデックスの設計 
– ウェブアプリケーションのためのデータ構造 
etc 
応用まで
Q&A!! 
ご静聴ありがとうございました。

MySQLトラブル解析入門

  • 1.
    MySQL トラブル解析入門 @第5回中国地方DB勉強会 奥野幹也 Twitter: @nippondanji mikiya (dot) okuno (at) gmail (dot) com
  • 2.
    免責事項 ● 本プレゼンテーションにおいて示されている見 解は、私自身の見解であって、オラクル・コー ポレーションの見解を必ずしも反映したもので はありません。ご了承ください。
  • 3.
    自己紹介 ● MySQLサポートエンジニア – 日々のしごと ● トラブルシューティング全般 ● Q&A回答 ● パフォーマンスチューニング など ● ライフワーク – 自由なソフトウェアの普及 ● オープンソースではない ● ブログ 今日は個人として 参加しています。 – 漢のコンピュータ道 – http://nippondanji.blogspot.com/
  • 4.
  • 5.
  • 6.
    アジェンダ ● MySQLでよくある問題の傾向と対策 – SQL の結果がおかしい – 文字化け – レプリケーションの諸問題 – クラッシュ – データ破壊 – デッドロック etc ● ツールを使いこなす!! – SHOW コマンド、INFORMATION_SCHEMA – ログ etc
  • 7.
  • 8.
    SQL がエラーになる ●プログラムのソースコードを見ただけでは分からないことが 多い。 – 一般クエリログやlong_query_time=0 にしたスローク エリログがクエリの特定に役立つ – 理想的には、SQL を実行してエラーになったときアプリ ケーションがログを取るようにしておく。 – 実際にエラーになったSQL を実行してみる。 ● エラーの原因と対処は千差万別
  • 9.
    一般クエリログ ● MySQLサーバーに対して投げられたリクエストを全て記録 する。 ● 実際に実行されたクエリを見ることができるので、アプリ ケーションのデバッグに役立つ。 – SQL がエラーになろうがなるまいが記録される。 ● 動的に有効・無効を切り替え可能。 – SET GLOBAL general_log=ON; ● 出力先はファイルまたはテーブル。
  • 10.
    期待通りの結果が返らない ● MySQLのバグの可能性 – 別のストレージエンジンを使って試してみる – EXPLAIN で実行計画を見る ● インデックスヒントを使って実行計画を変更してみる ● 最適化オプションのON/OFF – 問題が起きる最小のデータとクエリを突き止める ● バグ登録 ● そもそもそのSQL は正しいか? – 複雑なSQL はシンプルなパーツに分けてみる – リレーショナルモデルに沿って考える ● いつから問題が起きているか? – テーブルのメンテナンスやアップグレードはおこなったか – アプリケーションの改修をしたか
  • 11.
  • 12.
    MySQL サーバー内の文字コード変換 テーブルセッションクライアント MySQLサーバー ①送信する SQL文に対する 文字コード ③クエリの 実行結果に対する 文字コード ②クエリの実行 に利用する 文字コード ④データを 蓄える際の 文字コード ⑤テーブル名や カラム名に対する 文字コード ⑥ファイル名を 解決する際の 文字コード ファイルシステム出展:エキスパートのための MySQL [運用+管理]トラブルシューティングガイド
  • 13.
    文字コードを確認する ● SHOW[GLOBAL] STATUS LIKE 'char%'; – character_set_client – character_set_connection – character_set_results – character_set_server/character_set_database – character_set_system – character_set_filesystem ● アプリケーションから実行してみる – ドライバの設定(接続プロパティ)に問題はないか
  • 14.
    文字化けの原因と対策 ● 接続用の文字コードは問題ないか? – アプリケーションが期待している文字コードとドライバの文 字コードは同じか? ● 端末の文字コードは問題ないか? – chcp (Windows ) /locale ( UNIX系OS ) – MySQL 標準クライアントの場合は—default­character­set を指定。ただし­­skip­character­set­client­handshake がサーバで設定されていると無効。 (要注意!) – charset utf8 ● テーブル内のデータは問題ないか? – latin1 でマルチバイト文字を格納してしまった。 ● 正しい文字コードを指定して取り出すと化ける。 – いったんbinary としてバックアップ。
  • 15.
    テーブルの文字コード ● カラムごとに文字コードを指定可能 – SHOW CREATE TABLE で確認 ● INFORMATION_SCHEMA を利用すると一括で調べられ る – SELECT * FROM COLUMNS WHERE CHARACTER_SET_NAME != 'utf8';
  • 16.
    Connector/J の留意点 ●文字コードはcharacterEncoding プロパティで指定 ● 文字コードの指定がない場合には接続先サーバーの character_set_server により決定。接続後SET NAMES をドライバが実行。 ● ­­skip­character­set­client­handshake は効かない ● characterEncoding が何であれ、Java内部で文字列 のエンコーディングはucs2 に変換される。
  • 17.
    LOAD DATA INFILE ● LOAD DATA INFILE – ファイルの文字コードがcharacter_set_database に なっていることを期待している – SET character_set_database = cp932; – テーブルの文字コードと同じ場合にはbinary を指定する と変換が生じないので高速 – LOAD DATA INFILE ではなくmysqlimport を使う手も ある ● SELECT … INTO OUTFILE – デフォルトでは文字コード変換しない ● LOAD DATA で読むときはbinary を指定すると良い – LOAD DATA で読む段階のことまで考えておく ● SELECT … INTO OUTOFILE 'file_name' CHARACTER SET charset_name …
  • 18.
  • 19.
    レプリケーションの仕組み クライアント 同じデータに同じ更新を適用した結果は同じ マスタースレーブ マスター スレッド スレーブI/O スレッド スレーブ SQL スレッド 更新内容 を記録 接続スレッド 更新更新 読み込み 転送 記録 読み 込み テーブルバイナリログリレーログテーブル
  • 20.
    バイナリログ ● 全ての更新を記録するためのログ – 元々はSQL 文を直接記録しておくものだった ● バイナリ(テキストではない)のヘッダ+ SQL文 – MySQL 5.1 からSQL を実行した結果(行)を記録するこ とが可能に ● インデックスファイル – バイナリログファイル名を記録 ● msyql­bin. index ● バイナリログファイル – 連番のついたファイル ● mysql­bin. 000001 – 中身はマジックナンバー+イベント
  • 21.
    バイナリログの種類 ステートメントベース ●SQL 文を直接記録する ● データサイズの効率が良い ● 非決定性のステートメントは含める ことができない ● 従来からある実装 行ベース ● データそのものを記録する ● クエリの種類を問わず対応可能 ● 行ベースしか対応していないスト レージエンジンもある ● 5.1 から利用可能 MIXED ● ステートメントベースと行ベースを状況に応じて使い分ける ● 通常はSBR 、非決定性のステートメントはRBR
  • 22.
    SQL スレッドの停止 ●スレーブ上のテーブルを更新してしまった。 – マスターのデータからリストア ● スレーブのクラッシュでポジションが巻き戻ってしまった – マシンがクラッシュした場合に起こりがち – 重複キーエラーに – マスターのデータからリストア ● バイナリログ欠損 – マスター上で失われた情報はどこにもない!! – 全て再セットアップ ● 一時的なエラーなら – mysql> SET GLOBAL SQL_SLAVE_SKIP_COUNTER = N; – mysql> START SLAVE;
  • 23.
    I/O スレッドの停止 ●ネットワークのエラー。 ● マスターがダウンした。 ● max_allowed_packet が足りない。 ● ユーザがログイン出来ない。 – ユーザのパスワードを変更してしまった? – エラーログを調査。
  • 24.
    SHOW SLVAE STATUS ● Slave_IO_Running: I/O スレッドが動作中かどうか ● Slave_IO_State: I/O スレッドのステータス ● Slave_SQL_Running: SQL スレッドが動作中かどうか ● Master_Log_File: I/O スレッドのバイナリログファイル名 ● Read_Master_Log_Pos: I/O スレッドのポジション ● Relay_Master_Log_File: SQL スレッドのバイナリログファイル名 ● Exec_Master_Log_Pos: SQL スレッドのポジション ● Seconds_Behind_Master: 遅延(後述) ● Last_Error: 最後に発生したエラー ● Last_Errno: 最後に発生したエラーの番号 ● Skip_Counter: エラーを無視する回数 ● Replicate_*: フィルタ
  • 25.
    SHOW MASTER STATUS ● バイナリログに関する情報を表示する – File: 現在更新中のバイナリログファイル名 ● デフォルトでは hostname.000001 から始まる連番の ファイル名 – Position: 現在のバイナリログポジション – Binlog_Do/Ignore_DB: フィルタ – Executed_Gtid_Set: これまでに実行したGTID ● マスターとスレーブのバイナリログポジションを見比べる
  • 26.
    レプリケーションの遅延 ● Seconds_Behind_Masterとは – I/O スレッドによる遅延+SQL スレッドによる遅延+ ズレ – レプリケーション開始時に時計のズレを検出 – ネットワークが停止するとI/O スレッドの遅延は分からな い ● 後から急激な時差を検出する場合がある ● レプリケーションハートビート – あくまでも近似値!! ● I/O スレッドの遅延 – ネットワークの問題 – リレーログの書き込みを同期( sync_relay_log ) ● SQL スレッドの遅延 – SQL の実行に時間がかかる – 更新/削除するデータがキャッシュに存在しない
  • 27.
    クラッシュセーフなスレーブ ● MySQL5.6 からスレーブがクラッシュしてもレプリケーション の再開に支障を来すことがなくなった。 InnoDB クラッシュセーフ レプリケーション情報 = relay_log_info ファイル クラッシュセーフではない InnoDB レプリケーション情報 = mysql.slave_relay_log_info テーブル クラッシュセーフ MySQL 5.5以前MySQL 5.6
  • 28.
    レプリケーションによるHA ● 利点 – 共有ディスク型のHA と違ってリカバリ不要! ● 超高速フェイルオーバー – レプリケーションはデフォルトで使える機能 ● 課題 – 非同期だから最後に更新したデータを一部失う覚悟が必 要。 ● 準同期レプリケーション – 1:N 構成では昇格に工夫が必要。 ● GTID
  • 29.
    準同期レプリケーション クライアント クライアントへ応答が返った時点で スレーブへバイナリログの転送は完了している。 マスタースレーブ マスター スレッド スレーブI/O スレッド スレーブ SQL スレッド 9. send_ok 8. ack 2.更新内容 を記録 4.読み込み 5.転送 6.記録 7-2. 更新の 適用 1. COMMIT 接続スレッド 3.更新 7-1. ack テーブルバイナリログリレーログテーブル
  • 30.
    Global Transaction ID ● トランザクションを一意に識別することができるID – UUID: トランザクションID の形式で表現される ● 例) 095E0FF8­18AF­11E2­9E7C­5C260A2AA986: 123456 – バイナリログ内に記録 ● スレーブでもバイナリログを有効化 ● log_slave_updates = 1 ● トランザクションID はシーケンス – 1:N 環境で、どのスレーブが最も進んでいるか一目瞭然! ● 昇格の手順は簡単 – 最も進んでいるスレーブを新しいマスターに – CHANGE MASTER TO … MASTER_AUTO_POSITION = 1
  • 31.
    msyqlfailover ● 1:Nのレプリケーションで使うツール – サーバーの死活監視 – マスターがFail したときに新たにスレーブを自動で昇格 ● 最も進んだスレーブを検出 ● CHANGE MASTER TO … MASTER_AUTO_POSITION = 1 ● MySQL Utilities に付属 – Python製
  • 32.
    レプリケーション安定化計画 ● ステートメントベースはリスクがある – テンポラリテーブルは使わない。 ● テンポラリテーブル作成後にSQL スレッドが停止する と、再セットアップが必要になる。 – Non­deterministic なSQL でエラーになる。 ● マスターだけを豪華にし過ぎない – マスターとスレーブは同じ量の更新が発生する。 – ハードウェア、バッファは同じ程度に設定しておく。
  • 33.
    レプリケーション安定化計画(つづき) ● マスタークラッシュ時 – バイナリログの欠損を防ぐ。 ● MySQL 5.6 + sync_binlog=1 ● 1:N構成では準同期+GTID で昇格を自動化 – MySQL 5.6 – mysqlfailover で自動的に昇格 ● クラッシュセーフなスレーブを利用する – MySQL 5.6
  • 34.
  • 35.
    クラッシュを誘発するシグナルの種類 ● SIGSEGV – プログラムが無効な(セグメント境界を超えた)メモリアド レスへアクセスした。 – バグやデータ破壊の可能性。 ● SIGABRT – プログラムがabort(3) を呼び出した。 – アサーション失敗。バグやデータ破壊の可能性。 ● SIGBUS – 無効な物理メモリアドレスへアクセスした。 – メモリアライメントの問題やハードウェアの故障など。 ● メモリアライメントに問題があるのはバグ ● メモリアライメントが必要かどうかはCPU次第( SPARC など)
  • 36.
    エラーログ ● クラッシュ時にはスタックトレースなどの情報がエラーログ に記録される – デフォルトではコアファイルが生成されないので、エラーロ グが唯一の手がかりに。 – シグナルの種類が判別可能。 – クラッシュ後にリカバリが行われているかの判定も重要。 ● エラーログは超重要 – クラッシュ時以外にも何か問題が起きたらまず見る。 – 実は標準出力をリダイレクトしたもの。 – /path/to/datadir/hostname.err ● /var/log 配下にあることも。 – サポートへ送るときは編集せずに!!
  • 37.
    コア解析 ● GDBなどのデバッグツールを使って行う ● コア解析はいわば検死解剖 – 直接の死因は分かるがそれがどのように引き起こされた かまでは分からないことが多い ● データ破壊によるクラッシュが起きた場合、なぜデータ は壊れたのか?という原因はコア解析では分からないこ とが多い。 ● ソースコードの理解が不可欠 – サポートへ依頼して頂きたい。
  • 38.
  • 39.
    データ破壊の概要 ● 特にクラッシュ時によく起きる – ファイルシステムキャッシュにデータが残っている間にOS ごとダウンした場合などは危険 ● データ保護の実装はストレージエンジン次第 – トランザクション対応のストレージエンジンはクラッシュリカ バリあり ● InnoDB ● MySQL Cluster – トランザクション非対応のストレージエンジンはクラッシュリ カバリなし ● MyISAM ● ARCHIVE
  • 40.
    MyISAM ● OSやMySQL サーバーのクラッシュ時にデータが壊れるか も知れないのは仕様です。 – トランザクションに対応していないため。 – OLTP系の処理には不向き。 ● 対策 – バックアップやレプリケーションなどでデータを複製してお く。 – データロストが発生するのは諦める。 – REPAIR TABLE コマンドで復旧を試みる。 ● ただし、確実に直るという保証はない。
  • 41.
    InnoDB ● 原因 – クラッシュなどによって簡単には壊れない ● ログ(WAL )とダブルライトバッファ – ハードウェアのエラーには耐えられない ● ディスク交換後にリストア – バグ – オペミス ● 復旧方法 – innodb_force_recovery=4 または 6 – 問題のテーブルまたは全体をmysqldump ( 6 の場合は全体) – テーブルをDROP またはデータディレクトリ初期化 – innodb_fource_recovery オプションを解除して再起動。 – リストア ● 対策 – バックアップやレプリケーションで鉄壁の防御を!
  • 42.
  • 43.
    mysqldがメモリ不足で停止する ● 32bitバージョンのプログラムはもう使わない!! – 論理アドレス枯渇によるOut Of Memory がよく起こる。 – RSS が1GB程度でも起こる。 ● 割り当て/解放の繰り返しによりフラグメンテーションが 発生するからVSIZE が大きくなってしまう。 – Linux では3GB まで、Windows では2GB まで。 ● ulimit ● バッファの割り当てすぎ。 – 特にセッションごとのバッファが大きすぎる場合が多 い。tmp_table_size=64M など。 ● カーネルの設定など – FreeBSD … kern.maxdsiz – HP­UX … maxdsiz_64bit
  • 44.
    OOM Killer ●Linux上でメモリが足りなくなった時にプロセスを終了させ る。 ● エラーメッセージがなく突然mysqld が終了している場合 に疑ってみるべし。 – OOM Killer が発動したことはsyslog に記録が残る – 夜間バッチなどでmysqld またはそれ以外のプロセスが 大量にメモリを消費していないか? ● echo ­17 > /proc/pid/oom_score_adj
  • 45.
  • 46.
  • 47.
    デッドロック対策 ● デッドロックは起きるもの。根絶することはできない。 – トランザクションが保証しているのは、実行した結果が Commit かAbort になるということ。失敗する( Abort ) 可能性はゼロにできない。 ● InnoDB はデッドロック検出機能あり – 片方のトランザクションを強制的にロールバック ● リトライ処理 – 発生したら黙ってリトライ。リトライのロジックは必須 – 他の例外処理とまとめて実装すると良い。 ● 行へアクセスする順序を工夫する – 主キーの順でアクセスするなど – デッドロックが頻発するケースではテーブルロックも有用
  • 48.
    Lock wait timeout ● ロックを長時間獲得出来なかった時に生じる現象 – デッドロックではない – UPDATE やDELETE に時間がかかり、ロックを待っていた 他のトランザクションがタイムアウトする – InnoDB のデッドロック検出機能は100% ではない – NDB にはデッドロック検出機能はないので必ずLock­wait­timeout になる。(見極めが難しい) ● 対策 – リトライ!! – 大量のレコードを一度に更新する処理を改める ● バッチ系の処理はこまめに分けて更新する ● テーブルロックをかけてから実行する – Lock wait timeout は発生しないが処理が待たされる
  • 49.
  • 50.
    クエリが遅い ● 適切なインデックスが使われていない – テーブルスキャンが発生している – 複合インデックスが必要なのに作成されていない ● クエリの効率がよくない – サブクエリではなくJOIN を – クエリが複雑になるのはテーブル設計がよくない兆候かも? ● 同時実行数が多すぎる – >CPU コア数 ● バッファプールが足りない
  • 51.
    スロークエリログ ● 実行に時間がかかったクエリを記録する – long_query_time で閾値を指定 – long_query_time=0 で全てのクエリを記録 – log_queries_not_using_indexes でインデックスを使っ ていないクエリを全て記録 ● 出力先はログまたはテーブル – log_output=TABLE ● ログファイルはmysqldumpslow コマンドで解析
  • 52.
    Too many connections ● ボトルネックが原因でクエリが処理できない – 処理の完了待ちの接続が増加 – max_connections へ到達 – Too many connections!! ● ボトルネックの特定が重要 – テーブルロックの競合(MyISAM ) – 行ロックの競合( InnoDB ) – 更新が多い場合のログへの書き込み – クエリの効率が悪すぎる – CPU リソースの枯渇 – バッファが足りない etc
  • 53.
    クエリのチューニング ● EXPLAINから実行計画を読み取る – クエリの構造、インデックス、レコードアクセスタイプ、行数 ● インデックスを付け替える ● オプティマイザの挙動を理解する – アルゴリズム: NLJ 、BNLJ 、BKAJ 、ICP 、ECP など – ヒント:使用するインデックスの指定、JOIN の順序固定
  • 54.
  • 55.
    SHOW コマンド ●設定値 – SHOW GLOBAL VARIABLES ● 統計情報 – SHOW GLOBAL STATUS ● レプリケーション情報 – SHOW SLAVE STATUS – SHOW MASTER STATUS ● InnoDB の情報 – SHOW ENGINE INNODB STATUS ● ● テーブル定義 – SHOW CREATE TABLE etc...
  • 56.
    INFORMATION_SCHEMA ● SHOWコマンドをも凌駕する情報量 – バージョンを追うごとに内容が充実 – SHOW コマンドでは得られない情報多数 ● SELECT でアクセス可能 – 必要な情報を得るため柔軟に絞り込みが可能 – JOIN 、サブクエリを利用可能 – GROUP BY による統計 – CASE 句による柔軟な出力 ● よく使うSELECT にビューを定義可能 – 作業の効率化
  • 57.
    PERFORMANCE_SCHEMA ● パフォーマンス統計用のカウンタの集合体 – かなり細かいデータまで取れる – バージョンを追うごとに拡充 – メモリ消費大なので注意 ● ストレージエンジンとして実装されている – 設定用のテーブルもある( UPDATE で設定) ● ps_helper – PERFORMANCE_SCHEMA を活用するためのビュー集 – http://www.markleith.co.uk/ps_helper/ ● MySQL Workbench – GUI からps_helper を利用
  • 58.
    ログ ● エラーログ – 問題が起きたらまず見るべき – クライアントへ返されたエラーは記録されない ● クライアント側でログを持っておくと便利 ● 一般クエリログ – MySQL サーバーへ送られたリクエストが記録される – アプリケーションのデバッグ用 ● スロークエリログ – 時間がかかったクエリが記録される ● バイナリログ – レプリケーションやPIT リカバリに利用される
  • 59.
    デバッグ版 ● デバッグ版の入手方法 – バイナリ版ならmysqld­debug ● ソースコード – — 5.1 configure … ­­with­debug – 5.5 — cmake … ­DWITH_ DEBUG ● DBUG パッケージによるトレースが可能 – my.cnf にてdubug オプションを記述 – mysqld のコードパスが一目瞭然 ● アサーションが通常版よりも多い
  • 60.
    OS の情報を見る ●統計情報( UNIX系OS ) – mpstat 、vmstat 、iostat 、top ● 最近話題のdstat – /proc ファイルシステム ● システムの情報を一括で取得 – Windows ● アクセサリ>システム>システム情報 ● systeminfo コマンド – OSX ● system_profiler – Oracle Solaris ● Oracle Explorer Data Collector – Linux ● sosreport
  • 61.
    MySQL Enterprise Monitor ● MySQL専用の商用監視ツール – 200 を超えるアドバイザルールが総合的にヘルスチェック – メール、SNMP による通知 – システムリソースや使用状況をグラフで表示 – パフォーマンス解析の強い味方 ● 最強のモニタリング機能 – レプリケーションモニター – クエリアナライザ http://www­jp. mysql.com/products/enterprise/monitor.html
  • 62.
    商用サポート ● 解析のプロが責任をもってお答えします!! – 自ら解析できる場合でも時間の節約に ● 商用ツールが利用可能( Enterprise Edition ) – MySQL Enterprise Monitor – MySQL Enterprise Backup – ThreadPool プラグイン – 認証プラグイン ● 24時間365 日のサポート – ただし日本語は平日9時—5時のみ(緊急時は英語で 問い合わせ)
  • 63.
  • 64.
    運用のベストプラクティス 一、 バックアップはしっかり計画的に! 二、 本番投入前に必ずアプリケーションのテストを。 ● 負荷に見合ったハードウェアを選定。 三、 要件に合致した高可用性構成をチョイス。 ● スタンドアロン? HA ?レプリケーション? MySQL Cluster ? ● ディザスタリカバリは必要か? 四、 もしもの時の保険=サポート 五、 セキュリティは万全に。 六、 監視は抜かりなく。 ● トラブル、キャパシティ、性能 ● 全部まとめてMySQL Enterprise Monitor はいかが? 七、 メンテナンスは無理のない計画+周到な準備を。
  • 65.
    参考:対策とダウンタイムの目安 対策要件ダウンタイムの目安 バックアップからのリストアバックアップの取得データ量次第だが数時間— クラッシュリカバリサーバー1台 InnoDBの利用 数分—数十分 HA クラスタのフェイルオーバーサーバー2台 共有ストレージ 数分—数十分 MySQL Cluster のフェイルオーバーサーバー3台以上 ネットワーク冗長化 —数秒 レプリケーションのフェイルオーバーサーバー2台以上数秒程度
  • 66.
  • 67.
    メンテナンスの種類 ● テーブルのメンテナンス – インデックスやカラムの追加・削除 – データ型変更 – 古いデータの破棄 – テーブルの破損 ● アップグレード – バグ修正 – 新しいバージョンの新機能を使いたい ● システム構成の変更 – オプションの変更 – ディスクやCPU 、メモリの強化
  • 68.
    テーブルのメンテナンス ● テーブル定義変更 – MySQL 5.6 からInnoDB はオンラインDDL対応 ● インデックスの追加・削除等がオンライン( Inplace ) ● コピーが必要なケースは従来の動作 – ALTER TABLE は更新がブロックされる – データを古いテーブルから新しい型のテーブルにコピー – InnoDB Plugin/MySQL 5.5 のInnoDB ではインデック ス部分だけを再構築( Fast Index Creation ) – MySQL Cluster はオンラインスキーマ変更に対応 ● 古いデータの破棄 – RANGE パーティショニング – DELETE を使う場合はこまめにCOMMIT ● OPTIMIZE 、ANALYZE etc
  • 69.
    アップグレード ● 失敗しないためには周到な準備を! – アップグレード後の動作確認 – 作業時間の見積もり ● 本番環境と同じデータを使って手順を確認 ● レプリケーションの活用でダウンタイム縮小 – スレーブのバージョン > マスターのバージョン – メジャーバージョンの差はひとつまで – 手順 ● スレーブをひとつずつアップグレード後、スレーブのひと つをマスターに昇格 ● 旧マスターを構成から切り離してアップグレード ● 必要があれば旧マスターへ切り戻し
  • 70.
  • 71.
    トラブルシューティングのポイント ● 何が起きているのかを見極める。 – 仕様を理解する。 ● 何が正常で何が異常なのか? – OS に詳しくなる。 ● 問題がOS からやってくることも多い。 – 自分でやってみる。 ● 再現が出来ればこちらのもの! ● 的確に対策をする。 – 仕組みから何故対策が有効なのかを説明できる。 ● トラブルに備える。 – トラブルに強い設定。 – トラブルが起きてもダメージが少ないようにする。
  • 72.
  • 73.
    宣伝2:新書籍の紹介 ● リレーショナルデータベース実践入門(仮) – リレーショナルモデル、SQL 、そしてDB 設計が主なテー マの書籍です。 – どうやってリレーショナルデータベースを使いこなすか! ● リレーショナルモデル基礎編 – SQL とリレーショナルモデル – 述語論理とリレーショナルモデル – 正規化1: 関数従属性 – 正規化2: 結合従属性 – 直交性 – ドメインの設計 etc ● アプリケーション開発実践編 基礎の基礎から よくある間違いを 指摘しつつ – 履歴 – グラフ – インデックスの設計 – ウェブアプリケーションのためのデータ構造 etc 応用まで
  • 74.