MySQL が盛大にクラッシュしたので myisamchk ユーティリティを使って修復する作業まとめ

また物凄いトラフィックでサーバーが止まっていました。強制終了するとファイルが破損するので、普通に再起動申請をしましたが、数時間経っても再起動されなかったので、強制終了したら案の定 MySQL のファイルが破損しましたので、以前と同じように修復することにしました。

REPAIR TABLE での修復

phpMyAdmin を見てみたらテーブルが使用中のままになっていました。ちょっと気になったけど忙しいので、とりあえず以前と同じ方法で修復を試みることにしました。まず MySQL にコマンドラインで接続。

1
mysql -u root -p

テーブルを選択して REPAIR TABLE コマンドを実行。

1
2
use hoge;
REPAIR TABLE posts;

サーバーに負荷をかけないように Apache など停止してるけど、データも増えてるので、数時間はかかると思ったので今日は寝ることに。

1
2
3
4
5
6
+------+------+-----------+------+---------+-------+----------------------+--------------------------+
| Id   | User | Host      | db   | Command | Time  | State                | Info                     |
+------+------+-----------+------+---------+-------+----------------------+--------------------------+
|    2 | root | localhost | hoge | Query   | 61998 | Repair with keycache | REPAIR TABLE posts       |
| 1040 | root | localhost | NULL | Query   |     0 | NULL                 | SHOW PROCESSLIST         |
+------+------+-----------+------+---------+-------+----------------------+--------------------------+

朝起きたら6万秒経っても解決されていません。仕方ないので kill 2 して、また kill もかなり時間がかかりました。どうやらこれでは解決できないような破損の仕方してるんでしょうかね。修復の仕方が間違ってると思ったのでもうちょっと調べてみることにしました。

myisamchk で修復する

MyISAM を使ってるのですが、myisamchk ユーティリティというのがあるようです。

myisamchk ユーティリティはユーザのデータベース テーブルの情報を収集し、チェック、修復、もしくは最適化します。myisamchk は MyISAM テーブルとともに作動します(データやインデックスを記憶するための .MYD や .MYI テーブル)。

この件に関しては以下のサイトが参考になりました。

破損している原因を調べる

テーブルがどのように破損してるのか以下のコマンドで実行できるらしいです。

1
myisamchk /データベースのパス/*.MYI

まず、テーブルのパスが分かりませんので調べることにしました。とりあえずテーブル名で検索をかけてみることにしました。

1
2
3
4
sudo find / -name '*posts*'
/var/lib/mysql/hoge/posts.frm
/var/lib/mysql/hoge/posts.MYD
/var/lib/mysql/hoge/posts.MYI

すると以上のようにパスが出てきました。ちょうど hoge データベースのフォルダにテーブル名という構造で入っています。MySQL ってこういう風に保存されているんですね。とりあえず、これはこれで今後の参考になりました。

さっそく、テーブルエラーを調べてみます。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
sudo myisamchk /var/lib/mysql/hoge/posts.MYI
Checking MyISAM file: /var/lib/mysql/hoge/posts.MYI
Data records:  111016   Deleted blocks:       0
myisamchk: warning: Table is marked as crashed and last repair failed
myisamchk: warning: 2 clients are using or haven't closed the table properly
- check file-size
myisamchk: warning: Size of datafile is: 13600153700       Should be: 13512913956
- check record delete-chain
- check key delete-chain
- check index reference
- check data record references index: 1
myisamchk: warning: Auto-increment value: 136262 is smaller than max used value: 136263
- check data record references index: 2
- check data record references index: 3
- check data record references index: 4

かなり詳しく解説しながらチェックしてくれます。ただ、これ以降数時間経っても進まないし、速く復旧しないといけないので、一応なんか壊れてるみたいなのは分かったので具体的に修復するコマンドを実行することにします。

データに変更を加えずテーブルを修復する

-p オプションを指定するとデータファイルには触れないでインデックスファイルの修復を試みることができるそうです。できれば被害は少ない方が良いのでこちらを実行してみました。

1
2
3
4
5
6
7
sudo myisamchk -r -q /var/lib/mysql/hoge/posts
- check record delete-chain
- recovering (with sort) MyISAM-table '/var/lib/mysql/hoge/posts'
Data records: 111016
- Fixing index 1
MyISAM-table '/var/lib/mysql/hoge/posts' is not fixed because of errors
Try fixing it by using the --safe-recover (-o), the --force (-f) option or by not using the --quick (-q) flag

エラーによって修復ができないみたいなことが書いてありました。参考サイトには -r オプションのみで実行すると良いとありますのでこれを実行してみます。

1
2
3
4
5
6
7
8
9
10
11
sudo myisamchk -r /var/lib/mysql/hoge/posts
- recovering (with sort) MyISAM-table '/var/lib/mysql/hoge/posts'
Data records: 43547
- Fixing index 1
Found link that points at 4195162663727884602 (outside data file) at 5311977880
- Fixing index 2
- Fixing index 3
- Fixing index 4
myisamchk: error: myisam_sort_buffer_size is too small
MyISAM-table '/var/lib/mysql/hoge/posts' is not fixed because of errors
Try fixing it by using the --safe-recover (-o), the --force (-f) option or by not using the --quick (-q) flag

これでも修復できないので -o オプションで実行してみます。

1
sudo myisamchk -o /var/lib/mysql/hoge/posts

物凄い時間がかかりました。1日程度ですがね。結果 MySQL は修復することができました。時間が掛かりすぎてターミナルの接続が切れてしまい処理結果が見れませんでした。次回からはファイルに処理結果を出力したいと思います。

myisamchk のオプション説明

ちなみに myisamchk コマンドのオプションは以下のコマンドを実行すると見ることができます。

1
myisamchk

ちなみに序盤の修復で使ってた -r オプションは以下のような説明です。

Can fix almost anything except unique keys that aren’t unique.

最終手段の -o オプションはセーフリカバリーです。

Uses old recovery method; Slower than ‘-r’ but can
handle a couple of cases where ‘-r’ reports that it
can’t fix the data file.

コメント

コメントは受け付けていません。