memo.xight.org

日々のメモ

テーブルの修復方法

Summary

  MySQL でテーブルが破損した場合の発生エラー
  ・`tbl_name.frm' is locked against change
  ・Can't find file `tbl_name.MYI' (Errcode: ###)
  ・Unexpected end of file
  ・Record file is crashed
  ・Got error ### from table handler
  perror ### を実行することでエラーの詳細情報を取得できる.

shell> perror 126 127 132 134 135 136 141 144 145
126 = Index file is crashed / Wrong file format
127 = Record-file is crashed
132 = Old database file
134 = Record was already deleted (or record file crashed)
135 = No more room in record file
136 = No more room in index file
141 = Duplicate unique key or constraint on write or update
144 = Table is crashed and last repair failed
145 = Table was marked as crashed and should be repaired

注意

  エラー135 (no more room in record file) の場合は以下を実行する必要がある.

mysql> ALTER TABLE table MAX_ROWS=xxx AVG_ROW_LENGTH=yyy;


段階1 : テーブルのチェック

  時間に余裕があれば,2列目のコマンドを実行.

myisamchk *.MYI
myisamchk -e *.MYI


  mysqld が終了している場合,--update オプションを使用して
  myisamchk がテーブルに 'checked' のマークを付けるようにする.

  myisamchk がエラーを返したテーブルのみ修復が必要.
  エラーを返したテーブルについては段階2へ.
  チェック時に `out of memory' などの複雑なエラーが発生,又は myisamchk がクラッシュした場合は段階3へ.

段階2 : 簡単で安全な修復

myisamchk -r -q tbl_name

  失敗したら以下の手順
  1. データファイルのバックアップ
  2. 以下を実行してインデックスファイルを再構築

myisamchk -r tbl_name

  3. 2に失敗したら,以下を実行

myisamchk --safe-recover tbl_name


  チェック時に `out of memory' などの複雑なエラーが発生,又は myisamchk がクラッシュした場合は段階3へ.

段階3 : 困難な修復

1. データファイルを安全な場所に移動
2. テーブル記述ファイルを利用して,新しい空白のデータとインデックスファイルを作成する.
   使用している SQL バージョンに TRUNCATE TABLE がない場合は,代わりに DELETE FROM table_name を使用

shell> mysql db_name
mysql> SET AUTOCOMMIT=1;
mysql> TRUNCATE TABLE table_name;
mysql> quit

3. 古いデータファイルを新しく作成したデータファイルにコピーする
4. 段階2に戻る.

段階4 : 非常に困難な修復

1. バックアップから記述ファイルをリストアし,段階3へ.
   又は,インデックスファイルをリストアして,myisamchk -r を実行し,段階2へ.
2. 別のデータベースにテーブルのコピーを作成する.
   テーブルのコピーを作成したデータベースから,新しいデータファイルを削除する.
   記述ファイルとインデックスファイルを,クラッシュしたデータベースに移動する.
   これで新しい記述ファイルとインデックスファイルができ,データファイルは前のものがそのまま残る.
   段階 2 に戻り,インデックスファイルを再構築する.
   (テーブルがどのように作成されたか正確にわかっていれば)

Reference

  MySQL Manual - テーブルの修復方法
  http://dev.mysql.com/doc/mysql/ja/Repair.html