【完全版】MySQL「ERROR 1146: Table doesn’t exist」の原因と対処法|テーブル不存在エラー全パターン徹底解説
MySQL/MariaDBにクエリを実行した時、以下のエラーで弾かれた経験はありませんか?
ERROR 1146 (42S02): Table 'mydb.users' doesn't exist
ERROR 1146 (42S02): Table 'mydb.Users' doesn't exist
PHP Fatal error: SQLSTATE[42S02]: Base table or view not found: 1146
java.sql.SQLSyntaxErrorException: Table 'mydb.users' doesn't exist
「テーブルが存在しません」というシンプルなメッセージですが、実際の原因は10種類以上あり、「テーブルは確かに存在するのにエラーが出る」ケースが頻発します。
- SHOW TABLESで一覧表示されるのにアクセスできない
- 開発環境では動くが本番では失敗する
- MySQLサーバーを移行した後から発生する
- Dockerコンテナを再起動したらテーブルが消えた
- 大文字小文字を変えただけで動く時がある
- レプリケーション環境で時々起きる
- InnoDB復旧後にいくつかのテーブルだけ消失
本記事では、MySQL ERROR 1146 のすべての原因と対処法を、現場で即使えるトラブルシューティング手順として整理します。テーブル名のスペル問題から、データベース選択ミス、lower_case_table_names設定、InnoDB ファイル消失、Docker・AWS RDS対応、復旧手順、プログラム言語別対処、FAQまで完全網羅。この1本でMySQLのテーブル不存在エラーが全て解決します。
- 1. 結論:今すぐ試すべき3ステップ
- 2. まず押さえる:エラーメッセージの読み解き方
- 3. ERROR 1146の原因カテゴリ
- 4. 【原因①】テーブル名・データベース名の指定ミス(最頻出)
- 5. 【原因②】大文字小文字問題(最大の落とし穴)
- 6. 【原因③】テーブルが削除されている
- 7. 【原因④】InnoDB の .ibd ファイル消失・破損
- 8. 【原因⑤】データディレクトリ移行・コピー失敗
- 9. 【原因⑥】ビュー(VIEW)が壊れている
- 10. 【原因⑦】パーティション関連
- 11. 【原因⑧】Docker 環境での 1146
- 12. 【原因⑨】レプリケーション環境での同期遅延
- 13. 【原因⑩】権限不足が ERROR 1146 として返される
- 14. AWS RDS / クラウドDB での 1146
- 15. プログラム言語別 ERROR 1146 対処
- 16. 関連エラーと違い
- 17. 予防策・ベストプラクティス
- 18. トラブルシューティング・チェックリスト
- 19. よくある質問(FAQ)
- 19.1. Q1. SHOW TABLES で表示されているのに SELECT で 1146 が出ます
- 19.2. Q2. 大文字小文字を意識せず使いたいです
- 19.3. Q3. テーブルを誤って DROP しました。復旧できますか?
- 19.4. Q4. Dockerでテーブルが消えました
- 19.5. Q5. MySQL を Linux→Windows に移行したら 1146 が大量発生します
- 19.6. Q6. INFORMATION_SCHEMA でテーブルは見えるのにクエリで 1146
- 19.7. Q7. .frm ファイルがあって .ibd がない場合は?
- 19.8. Q8. テストデータベースでテーブル名が大文字になります
- 19.9. Q9. CREATE TABLE 成功後すぐ SELECT で 1146
- 19.10. Q10. Oracle ORA-00942 との違いは?
- 19.11. Q11. AWS RDS でテーブルが見えなくなりました
- 19.12. Q12. Webアプリで時々 1146 が発生します
- 20. 参考リンク・関連資料
- 21. まとめ
結論:今すぐ試すべき3ステップ
時間がない方向けに、まず試すべき手順を示します。
ステップ1:テーブルが本当に存在するか確認
-- 接続中のDBで全テーブル確認
SHOW TABLES;
-- 該当テーブルの存在確認(INFORMATION_SCHEMA経由)
SELECT TABLE_SCHEMA, TABLE_NAME
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME = 'users';
ステップ2:データベース指定を確認
-- 現在選択中のDB
SELECT DATABASE();
-- 別DBに切り替えてみる
USE mydb;
SELECT * FROM users LIMIT 1;
ステップ3:大文字小文字を確認
-- テーブル名の大文字小文字を表示
SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
WHERE LOWER(TABLE_NAME) = LOWER('users');
それでも解決しない場合は、以下の詳細な原因分析へ進んでください。
まず押さえる:エラーメッセージの読み解き方
ERROR 1146 (42S02): Table 'mydb.users' doesn't exist
↑ ↑
DB名 テーブル名
エラーから読み取れる情報:
- DB名:
mydb - テーブル名:
users - SQLSTATE:
42S02(テーブル/ビュー未発見の標準コード)
このエラーは「指定されたDB名.テーブル名の組み合わせが見つからない」ことを意味します。
「見つからない」が意味する可能性
| 状況 | 実態 |
|---|---|
| テーブルが本当に存在しない | 削除済み、未作成 |
| DB名が違う | 別のDBに作成済み |
| テーブル名のスペルミス | タイポ |
| 大文字小文字の不一致 | OS設定依存 |
| ファイルレベルで壊れている | InnoDB .ibd 不整合 |
| 権限がない | ※MySQLは権限がない場合も1146を返すことがある |
ERROR 1146の原因カテゴリ
| カテゴリ | 例 | 頻度 |
|---|---|---|
| スペル・参照ミス | テーブル名タイプミス、DB指定漏れ | 最多 |
| 大文字小文字系 | lower_case_table_names設定、OS依存 | 多 |
| DB選択系 | USE文の漏れ、デフォルトDB違い | 多 |
| 削除・移行系 | DROP実行済み、移行不備 | 多 |
| InnoDB ファイル系 | .ibd消失、innodb_file_per_table関連 | 中 |
| ビュー・パーティション系 | ビュー定義壊れ、パーティション欠損 | 中 |
| 権限系 | テーブルの権限がないため1146扱い | 中 |
| 環境固有 | Docker volume、レプリケーション | 中 |
これらを順番にチェックします。
【原因①】テーブル名・データベース名の指定ミス(最頻出)
最も多いケースです。
スペルミス・タイポ
-- ❌ 間違ったテーブル名
SELECT * FROM userss;
SELECT * FROM Users; -- 環境によっては失敗
-- ✅ 正しいテーブル名(実際の名前と完全一致)
SELECT * FROM users;
データベース指定漏れ
接続中のDBが異なる場合に発生:
-- 現在のDB
SELECT DATABASE();
-- 結果: testdb(なのに users は mydb にある)
-- ❌ 失敗
SELECT * FROM users;
-- ✅ DB名で修飾
SELECT * FROM mydb.users;
-- ✅ USE で切り替え
USE mydb;
SELECT * FROM users;
接続後のデフォルトDB確認
SELECT DATABASE(); -- 現在のDB
SHOW DATABASES; -- 全DB一覧
全DBからテーブルを検索
SELECT TABLE_SCHEMA, TABLE_NAME
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME LIKE '%users%';
これでどのDBにあるか一目で分かります。
【原因②】大文字小文字問題(最大の落とし穴)
MySQLはOSによってテーブル名の扱いが異なるため、開発・本番で挙動が変わります。
lower_case_table_names 設定
SHOW VARIABLES LIKE 'lower_case_table_names';
| 値 | 動作 |
|---|---|
0 | テーブル名は作成時のまま保存・大文字小文字を区別 |
1 | テーブル名は全て小文字で保存・大文字小文字を区別しない |
2 | 作成時のまま保存・比較時は小文字化(macOS等) |
OSごとのデフォルト値
| OS | デフォルト値 |
|---|---|
| Linux | 0(区別する) |
| Windows | 1(区別しない) |
| macOS | 2(保存はそのまま、比較時は無視) |
問題発生パターン
開発(Mac、値=2): CREATE TABLE Users → 大小文字無視で動作
本番(Linux、値=0): SELECT * FROM users → ERROR 1146("Users" として作られているため)
確認方法
-- 実際のテーブル名(大文字小文字含む)
SELECT TABLE_NAME
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'mydb'
ORDER BY TABLE_NAME;
対処法1:適切なテーブル名でアクセス
-- 実際に保存されている名前で指定
SELECT * FROM `Users`; -- バッククォートで囲むと確実
対処法2:lower_case_table_names を統一
⚠️ この設定は MySQL初期化時にのみ変更可能 で、運用中の変更は推奨されません。
# /etc/mysql/my.cnf
[mysqld]
lower_case_table_names = 1
設定変更にはデータベースを完全クリーンインストールするか、慎重なデータ移行手順が必要です。
対処法3:開発時から統一規約を採用
業務開発では「全テーブル名を小文字」「スネークケース」のような命名規約を設けて、OS依存の問題を回避するのがベストプラクティスです。
-- 推奨
CREATE TABLE users (...);
CREATE TABLE user_profiles (...);
-- 非推奨
CREATE TABLE Users (...);
CREATE TABLE UserProfiles (...);
【原因③】テーブルが削除されている
DROPされたか、データファイルが消失している可能性です。
削除履歴の確認
MySQLは標準では削除履歴を残しません。Binary Log(バイナリログ)が有効なら確認できます:
-- バイナリログの状態
SHOW VARIABLES LIKE 'log_bin';
-- 有効な場合、ログを確認
SHOW BINARY LOGS;
-- 特定ログからDROP文を検索
SHOW BINLOG EVENTS IN 'mysql-bin.000123';
# binログをテキストで読む
mysqlbinlog /var/log/mysql/mysql-bin.000123 | grep -i "DROP TABLE"
一般ログの確認
-- 一般ログ有効化(事前設定が必要)
SHOW VARIABLES LIKE 'general_log%';
-- ログ確認
SELECT * FROM mysql.general_log
WHERE argument LIKE '%DROP TABLE%users%'
ORDER BY event_time DESC;
復旧手段
バックアップから復元
# mysqldump からの復元
mysql -u root -p mydb < backup_mydb.sql
# 特定テーブルだけ取り出す
grep -E "DROP TABLE.*users|CREATE TABLE.*users|INSERT INTO.*users" backup.sql > users.sql
Point-in-Time Recovery(PITR)
# バックアップ復元 + バイナリログ適用
mysql < backup.sql
mysqlbinlog --stop-datetime="2026-06-17 10:00:00" mysql-bin.000123 | mysql
バックアップがない場合の最終手段
InnoDB の ibdata や ibd ファイルから直接復旧する特殊技法もありますが、専門ツール(Percona Data Recovery Tool 等)の使用や有償サービスが必要です。
【原因④】InnoDB の .ibd ファイル消失・破損
InnoDB エンジンでは、innodb_file_per_table 設定時に各テーブルが個別の .ibd ファイルで管理されます。
設定確認
SHOW VARIABLES LIKE 'innodb_file_per_table';
-- ON: 個別ファイル / OFF: 共有 ibdata1
データファイルの場所確認
SHOW VARIABLES LIKE 'datadir';
-- 例: /var/lib/mysql/
# データディレクトリ内のファイル
ls -la /var/lib/mysql/mydb/
# 各テーブルの .ibd ファイルがあるはず
# users.ibd, products.ibd, ...
.frm ファイルだけ残っているケース
MySQL 5.7以前では、テーブル定義.frmとデータ.ibdが別ファイル。なんらかの理由で .ibd のみ消えると ERROR 1146 が出ます。
ls /var/lib/mysql/mydb/users.*
# users.frm(定義ファイル)はあるが
# users.ibd(データファイル)がない
.ibd ファイル再リンク(IMPORT TABLESPACE)
別の同じ構造のサーバーから .ibd を持ってきて復旧:
-- 1. テーブルを再作成
USE mydb;
CREATE TABLE users (
id INT PRIMARY KEY,
name VARCHAR(100)
);
-- 2. テーブルスペースを切り離す
ALTER TABLE users DISCARD TABLESPACE;
-- 3. 別環境からコピーした .ibd と .cfg を配置
-- /var/lib/mysql/mydb/ に コピー
-- 4. テーブルスペースをインポート
ALTER TABLE users IMPORT TABLESPACE;
⚠️ MySQL 8.0以降は .frm ファイルがなくなり、メタデータは mysql.ibd に統合されています。挙動が異なるので公式ドキュメント参照。
InnoDB 強制復旧モード
データファイルが破損している場合、強制復旧モードで起動して救出:
# /etc/mysql/my.cnf
[mysqld]
innodb_force_recovery = 1 # 1〜6、徐々に強い復旧
sudo systemctl restart mysql
復旧モードでmysqldump → 通常モードで再構築 が王道。値が大きいほどリスクが高まるので、必ず1から試してください。
【原因⑤】データディレクトリ移行・コピー失敗
サーバー移行時にデータディレクトリのコピー方法が不適切な場合に発生します。
安全な移行手順
# 1. MySQL停止
sudo systemctl stop mysql
# 2. データディレクトリを完全コピー(権限ごと)
sudo rsync -av /var/lib/mysql/ user@newhost:/var/lib/mysql/
# 3. 権限調整(新サーバー側で)
sudo chown -R mysql:mysql /var/lib/mysql
# 4. 起動
sudo systemctl start mysql
よくある失敗
# ❌ MySQL停止せずにコピー → データ整合性破損
cp -r /var/lib/mysql /backup/
# ❌ 一部ファイルだけコピー → InnoDB不整合
cp /var/lib/mysql/mydb/users.* /new/
# ❌ 権限を引き継いでいない → MySQLが読めない
不完全な移行後の症状
SHOW TABLESには表示される- でも
SELECT * FROM tableで 1146 エラー - MySQLログに「Tablespace open failed」などの警告
復旧
データディレクトリ移行に失敗した場合、最も確実なのは論理バックアップ(mysqldump)からの再構築です:
# 旧サーバーで論理バックアップ
mysqldump -u root -p --all-databases --routines --triggers --events > backup.sql
# 新サーバーで復元
mysql -u root -p < backup.sql
【原因⑥】ビュー(VIEW)が壊れている
ビューも INFORMATION_SCHEMA.TABLES に出ますが、参照先テーブルがなくなると 1146 を返します。
ビューの確認
-- ビュー一覧
SELECT TABLE_NAME, VIEW_DEFINITION
FROM INFORMATION_SCHEMA.VIEWS
WHERE TABLE_SCHEMA = 'mydb';
-- ビューの定義確認
SHOW CREATE VIEW user_summary;
ビューの再作成
参照先テーブルを復旧した後、ビューを再作成:
DROP VIEW IF EXISTS user_summary;
CREATE VIEW user_summary AS
SELECT id, name, email FROM users;
ビューの依存テーブル確認
SELECT TABLE_NAME, VIEW_DEFINITION
FROM INFORMATION_SCHEMA.VIEWS
WHERE VIEW_DEFINITION LIKE '%users%';
【原因⑦】パーティション関連
パーティション化されたテーブルで一部パーティションが消失したケースです。
パーティション確認
SELECT
PARTITION_NAME,
PARTITION_DESCRIPTION,
TABLE_ROWS
FROM INFORMATION_SCHEMA.PARTITIONS
WHERE TABLE_SCHEMA = 'mydb'
AND TABLE_NAME = 'orders';
パーティション分離されたファイル
ls /var/lib/mysql/mydb/orders*
# orders#P#p202601.ibd
# orders#P#p202602.ibd
# ...
一部の .ibd が消失すると、該当パーティションへのクエリで 1146 が出ます。
対処
パーティション単位での復旧は難易度が高いため、論理バックアップから再構築が基本対処です。
【原因⑧】Docker 環境での 1146
Docker MySQL コンテナ特有のシナリオがあります。
よくあるシナリオ
# 初回コンテナ作成
docker run -d --name mysql -e MYSQL_ROOT_PASSWORD=pass mysql:8.0
# CREATE TABLE を実行
mysql -h 127.0.0.1 -u root -p
# コンテナ削除(ボリュームなし)
docker rm -f mysql
# 再作成 → テーブルが消失
docker run -d --name mysql -e MYSQL_ROOT_PASSWORD=pass mysql:8.0
mysql> SELECT * FROM users;
-- ERROR 1146
原因
Dockerコンテナの /var/lib/mysql をホストにマウントしていない場合、コンテナ削除でデータも消失します。
対処:永続ボリュームの利用
# Named volume を使う
docker run -d \
--name mysql \
-e MYSQL_ROOT_PASSWORD=pass \
-v mysql_data:/var/lib/mysql \
mysql:8.0
docker-compose の場合
services:
mysql:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: pass
MYSQL_DATABASE: mydb
volumes:
- mysql_data:/var/lib/mysql # ← 必須
volumes:
mysql_data:
初期化スクリプトでテーブル作成
services:
mysql:
image: mysql:8.0
volumes:
- mysql_data:/var/lib/mysql
- ./init.sql:/docker-entrypoint-initdb.d/init.sql # 初期化SQL
init.sql:
CREATE DATABASE IF NOT EXISTS mydb;
USE mydb;
CREATE TABLE IF NOT EXISTS users (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100)
);
これでコンテナ初回作成時にテーブルが自動構築されます。
⚠️ 初期化スクリプトは既存ボリュームには適用されません。新規ボリュームのみ。
既存ボリュームを使い続けたい場合
# ボリュームから直接接続して状態確認
docker run -it --rm \
-v mysql_data:/var/lib/mysql \
mysql:8.0 ls /var/lib/mysql/mydb/
データが残っていれば、新コンテナでマウントすればOK。
【原因⑨】レプリケーション環境での同期遅延
レプリカ(スレーブ)側で 1146 エラーが出るケースがあります。
状況例
- マスター側で
CREATE TABLE実行 - アプリがレプリカに
SELECTクエリ送信 - レプリカへの同期が遅れていて、テーブルがまだない → ERROR 1146
確認
-- レプリカ側で
SHOW REPLICA STATUS\G
-- または旧構文
SHOW SLAVE STATUS\G
Seconds_Behind_Source: 5 -- 5秒遅延中
Last_Error: ...
対処
- レプリケーション遅延の改善(ハードウェア・ネットワーク)
- アプリ側でリトライロジック実装
- 重要な直後の読み取りはマスター(プライマリ)に向ける
- 読み書き分離フレームワークで遅延考慮
マスター/レプリカでテーブル定義不一致
-- 各サーバーでテーブル定義確認
SHOW CREATE TABLE users\G
不一致がある場合、DDLが片側だけ実行された可能性。マスター側で再実行が必要。
【原因⑩】権限不足が ERROR 1146 として返される
MySQL は仕様上、権限のないテーブルに対しても 1146 を返すことがあります。
確認
-- 自分の権限確認
SHOW GRANTS;
-- 特定テーブルへの権限
SHOW GRANTS FOR CURRENT_USER();
対処
-- 必要な権限を付与(root等で実行)
GRANT SELECT, INSERT, UPDATE, DELETE ON mydb.users TO 'app_user'@'%';
FLUSH PRIVILEGES;
権限関連の詳細はMySQL ERROR 1045 access denied の記事を参照してください。
AWS RDS / クラウドDB での 1146
AWS RDS for MySQL
よくある原因
- スナップショットから復元時の不整合
- パラメーターグループの
lower_case_table_names変更 - マルチAZ切り替え時の一時的な不整合
- リードレプリカでの遅延
対処
# RDSログ確認
aws rds describe-db-log-files --db-instance-identifier mydb
aws rds download-db-log-file-portion --db-instance-identifier mydb --log-file-name error/mysql-error.log
RDSは/var/lib/mysqlに直接アクセスできないため、SQLレベルでの確認と対処に限られます。
Google Cloud SQL
- Cloud Logging で
mysql-generalログ確認 - スナップショットからの新規インスタンス起動でリストア
Azure Database for MySQL
- Azure Portal → 該当MySQL → 監視 → メトリック
- バックアップ復元機能で過去時点を復旧
プログラム言語別 ERROR 1146 対処
PHP(PDO)
try {
$stmt = $pdo->query("SELECT * FROM users");
} catch (PDOException $e) {
if ($e->getCode() === '42S02') {
// ERROR 1146 - Table doesn't exist
error_log("Table not found: " . $e->getMessage());
// テーブル自動作成 or エラー応答
}
}
Python(PyMySQL)
import pymysql
try:
with conn.cursor() as cursor:
cursor.execute("SELECT * FROM users")
except pymysql.err.ProgrammingError as e:
if e.args[0] == 1146:
print("テーブルが存在しません:", e)
Java(JDBC)
try (Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * FROM users")) {
// ...
} catch (SQLException e) {
if (e.getErrorCode() == 1146) {
System.err.println("テーブル不存在: " + e.getMessage());
}
}
Node.js(mysql2)
try {
const [rows] = await conn.query('SELECT * FROM users');
} catch (err) {
if (err.errno === 1146) {
console.error('Table not found:', err.message);
}
}
ORMでの自動マイグレーション
多くのORMは自動でテーブルを作成・更新できます:
# Django
python manage.py migrate
# SQLAlchemy
Base.metadata.create_all(engine)
# Sequelize
sequelize.sync()
ローカル開発で頻繁にスキーマ変更する場合、ORMのマイグレーション機能で自動化するのが安全です。
関連エラーと違い
ERROR 1049 (42000): Unknown database
DBそのものが存在しない場合:
USE nonexistent;
-- ERROR 1049 (42000): Unknown database 'nonexistent'
対処:
CREATE DATABASE nonexistent;
ERROR 1051 (42S02): Unknown table
DROP TABLE 等で存在しないテーブルを指定した場合:
DROP TABLE users;
-- 既にない場合: ERROR 1051
-- IF EXISTS で回避
DROP TABLE IF EXISTS users;
ERROR 1054 (42S22): Unknown column
列が存在しない場合。テーブルはあるが列名がミスっている:
SELECT username FROM users;
-- 実際の列名は user_name の場合: ERROR 1054
ERROR 1064: SQL syntax error
SQL構文エラー。テーブル名と関係ない場合も多いですが、テーブル名にスペースや予約語を含むと出ることがあります:
-- ❌
SELECT * FROM order;
-- ✅
SELECT * FROM `order`;
予防策・ベストプラクティス
ERROR 1146 を起こさない設計と運用のポイント。
1. 命名規約の統一
- 全テーブル名を小文字
- 単語区切りはアンダースコア
- 予約語の回避
-- 推奨
CREATE TABLE user_profiles (...);
-- 避ける
CREATE TABLE UserProfiles (...); -- 大文字小文字でOS依存
CREATE TABLE order (...); -- 予約語
2. 永続化の確認
Docker・仮想環境では、必ずボリュームマウントを設定:
volumes:
- mysql_data:/var/lib/mysql
3. 定期バックアップ
# 毎日バックアップ
0 3 * * * mysqldump -u root --all-databases | gzip > /backup/mysql-$(date +\%Y\%m\%d).sql.gz
cron運用はcrontab記事参照。
4. データ移行は論理バックアップ経由
物理コピーは整合性リスクが高い:
# 推奨
mysqldump --all-databases > backup.sql
mysql < backup.sql
# 避けるべき(リスクあり)
rsync /var/lib/mysql/ newhost:/var/lib/mysql/
5. 監視
-- テーブル一覧を定期取得して比較
SELECT TABLE_SCHEMA, TABLE_NAME, TABLE_ROWS, DATA_LENGTH
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA NOT IN ('information_schema', 'mysql', 'performance_schema', 'sys');
定期的に実行し、行数の急激な変動や消失を検知。
6. lower_case_table_names を統一
各環境の MySQL 設定をインストール時から統一:
[mysqld]
lower_case_table_names = 1
開発・本番ともに同じ値で構築。
7. CI/CDでスキーマチェック
# CI で実行
mysqldump -d -u root mydb > schema_actual.sql
diff schema_expected.sql schema_actual.sql || exit 1
スキーマの意図しない変更を検知できます。
トラブルシューティング・チェックリスト
- エラーメッセージから DB.テーブル を確認
SHOW TABLESでテーブル存在確認SELECT DATABASE()で接続DBを確認INFORMATION_SCHEMA.TABLESで全DB横断検索- 大文字小文字を変えてみる、バッククォートで囲む
lower_case_table_names設定確認/var/lib/mysql/DB名/のファイル存在確認(要root)- 権限確認:
SHOW GRANTS - Docker環境なら volume 設定確認
- レプリケーション環境なら同期遅延確認
- バックアップから復元検討
- 最終手段:InnoDB 強制復旧モード
よくある質問(FAQ)
Q1. SHOW TABLES で表示されているのに SELECT で 1146 が出ます
考えられる原因:
- バッククォートが必要な特殊名(大小文字混在、予約語、ハイフン等)
- 権限がない(MySQLは権限なしでも 1146 を返すことがある)
- 物理ファイル(.ibd)の破損
-- バッククォートで明示
SELECT * FROM `Users`;
SELECT * FROM mydb.`Users`;
Q2. 大文字小文字を意識せず使いたいです
lower_case_table_names = 1 を MySQL 初期化時 に設定。既存環境では:
- 命名規約として全テーブルを小文字にする
- アプリ側でバッククォート + 明示的なケース指定
Q3. テーブルを誤って DROP しました。復旧できますか?
- バックアップがある → mysqldump から復元
- Binary Log有効 → Point-in-Time Recovery
- どちらもない → Percona Data Recovery Tool 等の専門手段
- クラウドDB → スナップショット復元
普段から自動バックアップを設定しておくことが最重要です。
Q4. Dockerでテーブルが消えました
ボリュームマウントなしのコンテナを docker rm した可能性大。次回からは:
volumes:
- mysql_data:/var/lib/mysql
を必ず設定してください。
Q5. MySQL を Linux→Windows に移行したら 1146 が大量発生します
lower_case_table_names のデフォルト値が異なるためです。移行先で 1 に設定してから論理バックアップ復元してください。
[mysqld]
lower_case_table_names = 1
⚠️ 既存データありでこの値を変更するのは危険。新規DBで設定してインポート。
Q6. INFORMATION_SCHEMA でテーブルは見えるのにクエリで 1146
メタデータ(INFORMATION_SCHEMA)と実データ(テーブルスペース)の不整合の可能性。InnoDB の .ibd ファイルが消失している場合があります:
ls /var/lib/mysql/mydb/
# users.ibd が存在しない、サイズが0など
復旧手段は限定的。バックアップからの再インポートが基本対処です。
Q7. .frm ファイルがあって .ibd がない場合は?
MySQL 5.7以前で発生するパターン。同じ構造のテーブルを別環境で作って .ibd をインポート:
CREATE TABLE users (...); -- 同じ定義で作成
ALTER TABLE users DISCARD TABLESPACE;
-- .ibd ファイルをコピー
ALTER TABLE users IMPORT TABLESPACE;
Q8. テストデータベースでテーブル名が大文字になります
MySQL を Mac で動かしている場合、lower_case_table_names = 2 が原因の可能性。本番(Linux)と挙動が変わるので、開発・本番で命名規約を統一推奨。
Q9. CREATE TABLE 成功後すぐ SELECT で 1146
考えられる原因:
- 異なる接続セッション、異なる DB に作成された
- レプリカ側を見ている
- トランザクション分離レベルの影響(実際は稀)
-- 作成直後に確認
SHOW TABLES LIKE 'users';
SELECT DATABASE();
Q10. Oracle ORA-00942 との違いは?
両者とも「テーブル/ビューが存在しない」エラーですが:
| 項目 | MySQL 1146 | Oracle ORA-00942 |
|---|---|---|
| 権限不足の挙動 | 1146を返す可能性 | 必ず ORA-00942 |
| スキーマ参照 | DBで明示分離 | スキーマがユーザーと結合 |
| 大文字小文字 | OS依存 | 引用符付きのみ区別 |
詳細はOracle ORA-00942の記事をご参照ください。
Q11. AWS RDS でテーブルが見えなくなりました
考えられる原因:
- マスターからリードレプリカへ接続している(遅延)
- スナップショット復元で前時点に戻った
- パラメーターグループの設定変更
RDSコンソールから状態確認とログ取得。
Q12. Webアプリで時々 1146 が発生します
可能性:
- 複数の DB を切り替える処理でミス
- セッション間の DB 状態管理ミス
- マスター/スレーブ振り分けでスレーブの遅延
アプリログとMySQLログ両方で発生時刻を突き合わせて原因特定。
参考リンク・関連資料
MySQL公式ドキュメント
- MySQL 8.0 Reference – Identifier Case Sensitivity – 大文字小文字
- MySQL 8.0 Reference – InnoDB File-Per-Table – .ibd ファイル
- MySQL 8.0 Reference – InnoDB Recovery Forcing – 強制復旧
- MySQL 8.0 Reference – Backup and Recovery – バックアップ・復旧
- INFORMATION_SCHEMA.TABLES – メタデータビュー
MariaDB
- MariaDB – ERROR 1146 – エラーコード一覧
復旧ツール
- Percona Data Recovery Tool – 商用復旧サービス
- mysqldump – 論理バックアップ
Docker
- Docker Hub – MySQL – 公式イメージ
- docker-entrypoint-initdb.d – 初期化スクリプト
クラウドDB
関連エラー記事(本サイト)
- MySQL 1045 access denied エラーの対処 – 認証エラー
- ORA-00942: 表またはビューが存在しません – Oracle類似エラー
- Docker「no space left on device」エラーの対処 – Docker関連
- Address already in use エラーの対処 – 開発トラブル
まとめ
MySQL ERROR 1146 は単純なエラーに見えて、10種類以上の原因があります。要点を再整理します。
- エラーから情報を読む:
Table 'DB.テーブル' doesn't existの構造を把握 - 最頻出原因: スペル・大文字小文字(OS依存)、DB選択ミス
- lower_case_table_names: Linux/Win/Mac でデフォルト値が違うので注意
- InnoDB ファイル消失:
.ibdファイル確認、必要なら強制復旧モード - Docker環境: ボリュームマウント忘れで頻発
- AWS RDS: スナップショット復元 / マスターレプリカ確認
- 予防: 命名規約・永続化・バックアップ・移行手順の標準化
これらの知識は、Webアプリ開発・DB管理・本番運用・移行作業・障害復旧など、MySQL を扱うあらゆる場面で必須です。本記事をブックマークしておけば、ERROR 1146 に遭遇した時の対応が大幅に効率化されます。
本記事は2026年6月時点の情報をもとに、MySQL 5.7 / 8.0 / 8.4 および MariaDB 10.x / 11.x での動作確認・公式ドキュメントに基づき作成しています。バージョンによって挙動が異なる場合があるため、最新の情報はMySQL公式ドキュメントもあわせてご確認ください。
-
前の記事
【完全版】Linux「No such file or directory」エラーの原因と確認方法まとめ 2026.06.19
-
次の記事
PostgreSQL「current transaction is aborted, commands ignored until end of transaction block」エラー原因と解決方法 2026.06.20
コメントを書く