Docker

ActiveRecord::StatementInvalid: Mysql2::Error: Table ‘myapp_development.schema_migrations’ doesn’t existの解決方法

Docker

 

今回はDocker環境下で吐かれるエラー「ActiveRecord::StatementInvalid: Mysql2::Error: Table ‘myapp_development.schema_migrations’ doesn’t exist」の解消方法について解説したいと思います。

同様のエラーで困っている方の参考になれば幸いです。

突如発生したエラーに僕自身2時間以上ハマってしまったので、個人的な備忘録としても残しておきます。

エラー内容

突然、以下のコマンド全てを実行することができず、エラーが吐かれてしまいます。

  • docker-compose up
  • docker-compose run app rails db:migrate
  • docker-compose run app rails db:migrate:reset
  • docker-compose run app rails db:drop
  • docker-compose run app rails db:reset

 

エラー内容を確認すると以下の2つが記載されています。

ActiveRecord::StatementInvalid: Mysql2::Error: Table 'myapp_development.schema_migrations' doesn't exist
InnoDB: Cannot open table myapp_development/schema_migrations from the internal data dictionary of InnoDB though the .frm file for the table exists.
schema_migrationsテーブルには、どのマイグレーションファイルが実行済みかがvarchar(255)型として格納されています。これはrails db:migrateの度に更新されます。

どうやら、myapp_developmentにschema_migrationsテーブルが存在していないことが原因のようです。

解決手順

解決に向けて試したことは以下の5つです。

  1. とりあえずビルド
  2. 開発環境をクリーンにし、rails db:drop
  3. エラー原因のschema_migrationsを削除
  4. データベースを直接削除
  5. データディレクトリの場所を特定して削除

 

今回のケースでは結果的に5つ目の方法で解決できましたが、同様のエラーで詰まっている方は1~4の手順も試すこともお勧めします。

では順番に見ていきましょう。

①とりあえずビルド

Dockerで何かしらのエラーが出た際は、とりあえずビルドし直すとうまく行くパターンが多いので、とりあえず試してみます。

% docker-compose build --no-cache
キャッシュでbuildしてしまうことを避けるため、念のため「–no-cache」オプションを付与しています。

②開発環境をクリーンにし、rails db:drop

「docker-compose down」コマンドで開発環境をクリーンにし、その後データベースをdropしてみます。

% docker-compose down
% docker-compose run app rails db:drop
色々調べてみるとこれで解決できる場合が多いらしいです。

③エラー原因のschema_migrationsを削除

MySQLにrootユーザーでログインし、直接エラー原因として言われているshema_migrationsテーブルを削除してみます。

% docker ps

% docker exec -it MySQLのコンテナ名 bash

root@000000000:/# mysql -u root -p

mysql>show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| myapp_development  |
| myapp_test         |
| myapp_test-0       |
| myapp_test-1       |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
8 rows in set (0.04 sec)

mysql> use myapp_development;

mysql>show tables;
+-----------------------------+
| Tables_in_myapp_development |
+-----------------------------+
| active_storage_attachments  |
| active_storage_blobs        |
| ar_internal_metadata        |
| record_items                |
| records                     |
| schema_migrations           |
| users                       |
+-----------------------------+
7 rows in set (0.00 sec)

mysql> drop table schema_migrations;
ERROR 1051 (42S02): Unknown table 'myapp_development.schema_migrations'
Docker
【Docker×MySQL】Docker環境下でMySQLコンテナに接続する方法(テーブル情報を確認)Docker環境下でMySQLコンテナに接続し、テーブル情報を確認する方法について解説しています。Docker環境下でもテーブルデータを確認したい機会は必ず出てくるため、ぜひこの手順を覚えておきましょう。...
shema_migrationsテーブルがあるにも関わらず、dropしようとするとそんなものはないと言われてしまっていますね。

④データベースを直接削除

テーブル削除が無理であれば、データベースごと削除を試みます。

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| myapp_development  |
| myapp_test         |
| myapp_test-0       |
| myapp_test-1       |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
8 rows in set (0.04 sec)

mysql> drop database myapp_development;
ERROR 1010 (HY000): Error dropping database (can't rmdir './myapp_development', errno: 39)

⑤データディレクトリの場所を特定して削除

データベースの削除ができなかったので、データディレクトリごと削除を試みます。

まずは以下のコマンドでデータディレクトリの場所を確認しましょう。

mysql> show variables like 'datadir';
+---------------+-----------------+
| Variable_name | Value           |
+---------------+-----------------+
| datadir       | /var/lib/mysql/ |
+---------------+-----------------+
1 row in set (0.01 sec)

 

その後、以下のコマンドでディレクトリごと削除します。

% docker exec アプリ名_db_1 rm -rf /var/lib/mysql/myapp_development

 

再度MySQLコンテナにアクセスすると、myapp_developmentが消えています。

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| myapp_test         |
| myapp_test-0       |
| myapp_test-1       |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
7 rows in set (0.01 sec)

 

後は再度データベースを作成し、migrateを実行すれば完了です。

% docker-compose run app rails db:create                               
% docker-compose run app rails db:migrate

エラー原因

結論不明です。

以下の記事によると、何かしらの操作でスキーマ情報の不整合が起きてしまうらしいです。

参考:MySQLでスキーマ情報に不整合が起こったら

どなたか分かる方教えてください。

まとめ

ActiveRecord::StatementInvalid: Mysql2::Error: Table 'myapp_development.schema_migrations' doesn't exist
InnoDB: Cannot open table myapp_development/schema_migrations from the internal data dictionary of InnoDB though the .frm file for the table exists.

 

上記エラーの解決手段をまとめると、以下のようになります。

  • とりあえずビルド
  • 開発環境をクリーンにし、rails db:drop
  • エラー原因のschema_migrationsを削除
  • データベースを直接削除
  • データディレクトリの場所を特定して削除

参考

 

 

今回はDocker環境下で吐かれるエラー「ActiveRecord::StatementInvalid: Mysql2::Error: Table ‘myapp_development.schema_migrations’ doesn’t exist」の解消方法について解説しました。同様のエラーで詰まっている方の参考になればと思います。