はじめに
ローカル環境のDockerでMySQLコンテナを起動させて開発をしていた際に、以下のようなエラーログを吐いてコンテナが終了するようになってしまいました。
InnoDB: We intentionally generate a memory trap.
InnoDB: Submit a detailed bug report to http://bugs.mysql.com.
InnoDB: If you get repeated assertion failures or crashes, even
InnoDB: immediately after the mysqld startup, there may be
InnoDB: corruption in the InnoDB tablespace. Please refer to
InnoDB: http://dev.mysql.com/doc/refman/8.0/en/forcing-innodb-recovery.html
InnoDB: about forcing recovery.
08:46:10 UTC - mysqld got signal 11 ;
Most likely, you have hit a bug, but this error can also be caused by malfunctioning hardware.
Thread pointer: XXX
Attempting backtrace. You can use the following information to find out
where mysqld died. If you see no messages after this, something went
terribly wrong...
うーん、なんかヤバそう……。
というわけで今回は、上記のようなエラーを修正する手順についてお伝えします。
動作環境
私の動作環境は以下の通りです。
動作環境
- PC
- MacBook Pro 2021 (M1 Proチップ)
- OS
- Sonoma 14.5
- Docker Desktopバージョン
- 4.30.0
修正前のcompose.yaml
の記述は以下の通りです。
# ...
db:
image: mysql:8.0.26
platform: 'linux/amd64'
# ...
結論
対応手順は以下の通りです。
- 手順1.
compose.yaml
に追記 - 手順2. Dockerイメージのビルド
- 手順3. コンテナ起動
- 手順4. ダンプ取得
- 手順5. MySQL関連ファイル削除
- 手順6. リカバリレベルを戻して再起動
- 手順7. ダンプをリストアする
以下、手順の詳細です。
手順1. compose.yaml
に追記
--innodb_force_recovery=1
を追記します。
db:
image: mysql:8.0.26
platform: 'linux/amd64'
command:
- --sql-mode=NO_ENGINE_SUBSTITUTION
- --innodb_force_recovery=1 # ← 追記
volumes:
- ./docker/mysql/conf.d:/etc/mysql/conf.d
--innodb_force_recovery=数字
を追記することで、MySQLがリカバリを実行してくれます。
詳細は公式ドキュメントをご参照ください。
手順2. Dockerイメージのビルド
compose.yaml
と同じディレクトリで、以下のコマンドを実行します。
docker compose build --no-cache
ビルドが終了するのを待ちます。
手順3. コンテナ起動
compose.yaml
と同じディレクトリで、以下のコマンドを実行します。
docker compose up
もしコンテナが起動しない場合は、リカバリのレベルを上げてみてください。
リカバリのレベルは1から6まで存在します。
db:
image: mysql:8.0.26
platform: 'linux/amd64'
command:
- --sql-mode=NO_ENGINE_SUBSTITUTION
- --innodb_force_recovery=6 # ← 追記
volumes:
- ./docker/mysql/conf.d:/etc/mysql/conf.d
数字が大きくなればなるほどリカバリできる可能性が高くなりますが、データ破損のリスクが増えます。
まずは1
をお試しいただき、2
, 3
と順番にお試しいただくと良いと思います。
無事にコンテナが起動したら、次へ進みます。
手順4. ダンプ取得
mysqldump
コマンドや、SQLクライアントなどでダンプファイルを取得します。
手順5. MySQL関連ファイル削除
以下のコマンドで、コンテナを終了します。
ctrl + C
続いて、Dockerのボリュームや、./mysql/conf.d
などを削除します。
以下の場合であれば、ローカルの./docker/mysql/conf.d
ファイルを削除します。
volumes:
- ./docker/mysql/conf.d:/etc/mysql/conf.d
(この時点でデータベースのデータは消滅します)
手順6. リカバリレベルを戻して再起動
最初のcompose.yaml
に戻してコンテナを再起動します。
db:
image: mysql:8.0.26
platform: 'linux/amd64'
command:
- --sql-mode=NO_ENGINE_SUBSTITUTION
volumes:
- ./docker/mysql/conf.d:/etc/mysql/conf.d
docker compose up
手順7. ダンプをリストアする
mysql
コマンドやSQLクライアントを利用して、ダンプからデータをリストアします。
対応手順は以上です!
おわりに
今回はMySQLコンテナが起動しなくなった場合の対応についてお伝えしました。
参考になれば幸いです!
以下の記事を参考にさせていただきました。