MySQLで壊れたテーブルを修正する方法
紹介
時々、MySQLのテーブルが破損することがあります。これはエラーが発生し、その内部のデータが読み取れないことを意味します。破損したテーブルからデータを読み取ろうとすると、通常、サーバーがクラッシュすることになります。
壊れたテーブルの一般的な原因は次の通りです:
- MySQLサーバーが書き込みの途中で停止します。
- 外部プログラムが、サーバーによって同時に変更されているテーブルを変更します。
- 機械が予期せずシャットダウンしました。
- コンピュータのハードウェアが故障します。
- MySQLのコードのどこかにソフトウェアのバグがあります。
テーブルの1つが破損している疑いがある場合は、トラブルシューティングやテーブルの修正を試みる前に、データディレクトリのバックアップを作成するべきです。これにより、データ損失のリスクを最小限に抑えることができます。
まず、MySQLサービスを停止します。
- sudo systemctl stop mysql
注意: Rocky Linuxのような一部のプラットフォームでは、MySQLサービスがmysqldと呼ばれることがあります。
次に、すべてのデータを新しいバックアップディレクトリにコピーします。Ubuntuシステムでは、デフォルトのデータディレクトリは/var/lib/mysql/です。
- cp -r /var/lib/mysql /var/lib/mysql_bkp
バックアップを作成した後、実際にテーブルが破損しているかどうかを調査する準備が整いました。テーブルがMyISAMストレージエンジンを使用している場合、MySQLを再起動し、MySQLプロンプトからCHECK TABLEステートメントを実行することで、破損しているかどうかを確認できます。
- sudo systemctl start mysql
- CHECK TABLE table_name;
このステートメントの出力にメッセージが表示され、データが破損しているかどうかがわかります。MyISAMテーブルが実際に破損している場合は、通常、REPAIR TABLEステートメントを発行することで修復できます:
- REPAIR TABLE table_name;
修理が成功したと仮定すると、出力に次のようなメッセージが表示されます:
+--------------------------+--------+----------+----------+
| Table | Op | Msg_type | Msg_text |
+--------------------------+--------+----------+----------+
| database_name.table_name | repair | status | OK |
+--------------------------+--------+----------+----------+
ただし、テーブルがまだ破損している場合、MySQLのドキュメントでは破損したテーブルを修復するためのいくつかの代替方法が提案されています。
一方、破損したテーブルがInnoDBストレージエンジンを使用している場合、その修復プロセスは異なります。InnoDBはMySQLのバージョン8.0以降のデフォルトのストレージエンジンであり、自動的な破損チェックと修復操作を特徴としています。InnoDBは読み取るすべてのページに対してチェックサムを実行することによって破損したページをチェックし、チェックサムに不一致が見つかった場合はMySQLサーバを自動的に停止します。
InnoDBテーブルの修復が必要になることはほとんどありません。なぜなら、InnoDBにはサーバーが再起動されたときにほとんどの問題を解決できる障害回復メカニズムが備わっているからです。しかし、破損したInnoDBテーブルを再構築する必要がある場合には、MySQLのドキュメントでは「ダンプとリロード」方法を使用することを推奨しています。これは、破損したテーブルへのアクセスを回復し、mysqldumpユーティリティを使用してテーブルの論理バックアップを作成し、テーブルの構造とその中のデータを保持し、その後、テーブルをデータベースに再読み込みすることを含みます。
そのことを考慮して、MySQLサービスを再起動して、そうすることでサーバーへのアクセスが可能になるかどうかを確認してみてください:
- sudo systemctl restart mysql
サーバーがクラッシュし続けるか、その他の理由でアクセスできない場合は、InnoDBのforce_recoveryオプションを有効にするのが役立つかもしれません。これはmysqld.cnfファイルを編集することで行えます。UbuntuやDebianシステムでは、このファイルは通常etc/mysqlにあります。Red HatやRockyシステムでは、このファイルは通常/etc/my.cnf.dにあります。
- sudo nano /etc/mysql/mysql.conf.d/mysqld.cnf
[mysqld] セクションに、次の行を追加します。
. . .
[mysqld]
. . .
innodb_force_recovery=1
ファイルを保存して閉じたら、再度MySQLサービスを再起動してみてください。壊れたテーブルに正常にアクセスできる場合は、mysqldumpユーティリティを使用して、テーブルデータを新しいファイルにダンプします。このファイルに好きな名前を付けることができますが、ここではout.sqlと名付けます:
- mysqldump database_name table_name > out.sql
その後、データベースからテーブルを削除します。MySQLプロンプトを再度開かずに済むように、以下の構文を使用できます。
- mysql -u user -p --execute="DROP TABLE database_name.table_name"
これに続いて、先ほど作成したダンプファイルを使用してテーブルを復元してください。
- mysql -u user -p < out.sql
InnoDBストレージエンジンは、一般的に古いMyISAMエンジンよりも障害耐性が高いことに注意してください。InnoDBを使用しているテーブルは、まだ破損する可能性がありますが、自動復旧機能のおかげで、テーブルの破損やクラッシュのリスクは著しく低くなっています。