◀ 11.

MySQLエラー一覧|番号・SQLSTATE別の原因と安全な確認手順

▶

MySQLのエラーは番号だけで解決操作を選ばず、接続・認証・SQL実行・通信切断の段階を分けます。この一覧から症状を探し、詳しい手順は下の子ページから選んでください。

MySQLエラーの段階を分け、読取確認から変更計画へ進む図

まず安全に切り分ける順番

  1. 時刻、サーバー/ドライバ版、SQLSTATEと固有番号、失敗段階を記録する。生SQLや接続文字列、パスワードは公開しない。
  2. 許可された既存接続で、接続先・列定義・制約・セッション設定を読み取り確認する。認証に失敗した接続ではSQLを実行できないため、権限を勝手に広げない。
  3. 同じメッセージを開発用の小さなデータで再現し、変更前後の結果を比較する。エラーが消えてもデータが正しいとは限らない。
  4. 再起動/アカウント変更/スキーマ変更/制約停止/ログ設定変更は別の変更作業として影響・承認・戻し方を確認する。

2006/2013等で書き込み中に切断した場合、クライアントから結果が見えなくても確定済みの可能性があります。無条件に再送せず、処理IDやトランザクションの結果を照合して二重登録を防ぎます。

個別の子ページから選ぶ

一覧の下にも元のコードを保持していますが、変更操作や誤ったコメントには直前で注意を付けています。コピーして順番に実行する診断スクリプトではありません。MySQLとMariaDB、MySQLの各版では構文や制限が異なります。

一次資料: MySQL 8.0のアカウント照合、権限変更の反映、外部キーと再検査の制限、UPSERTの更新動作、mysql_configの既定ソケット、PDOのエラー情報。

この記事の要点
  • MySQL の代表的なエラー番号と対処を一覧化(1045 / 1062 / 1064 / 1146 / 1452 / 2002 / 1366 / 1093 / 1170 / 1318 ほか)
  • ERROR 1045 (28000) Access denied は認証拒否。接続先・選択されるアカウント・認証方式を確認し、安易にパスワードを変えない
  • ERROR 1062 Duplicate entry はユニーク制約違反。衝突したキーと意図を確認し、無条件に上書きしない
  • ERROR 2002 Can't connect to local MySQL server はソケット or サービス停止 → systemctl status mysqld
  • ERROR 1452 Cannot add or update a child row は外部キー違反。親子の値と投入順を確認し、制約無効化を通常の対処にしない

MySQL エラー番号一覧(よく出会うもの)

エラー番号SQLSTATE意味主な原因
104528000Access denied for userパスワード / ホスト / ユーザー不一致
104942000Unknown databaseDB 未作成 / typo
106223000Duplicate entryPRIMARY / UNIQUE 重複
106442000SQL syntax error構文エラー / 予約語
1093HY000You can't specify target table for update in FROM clauseUPDATE 対象を直接サブクエリで参照
114642S02Table doesn't existテーブル未作成 / DB 違い / 大小文字
117042000BLOB/TEXT used in key without prefix lengthTEXT列の通常INDEXではprefixが必要。FULLTEXTとは別
131842000Incorrect number of arguments for PROCEDURE引数の数違い
1366HY000Incorrect integer value / Incorrect string value等数値変換失敗や文字コード不一致。メッセージと対象列を照合
145123000Cannot delete or update a parent row子レコードが残っていて FK 違反
145223000Cannot add or update a child rowFK 先の親が存在しない
2002HY000Can't connect to local MySQL serverサービス停止 / ソケットパス違い
2003HY000Can't connect to MySQL server on hostFW / port / bind-address
2006HY000MySQL server has gone awaywait_timeout / max_allowed_packet 超過
2013HY000Lost connection during query長時間クエリ / ネットワーク切断

ERROR 1045: Access denied for user

ERROR 1045 (28000): Access denied for user 'app'@'192.168.1.5' (using password: YES)

次の旧例は読み取り専用ではありません。 ALTER USERはパスワードを変更します。NewPass!は例示値で使用せず、%へ公開範囲を広げないでください。旧コメントの「具体的なホストが無ければ%が優先されない」は誤りで、接続時は一致したアカウント行の具体性等で選択されます。mysql.userの参照には権限が必要です。通常のALTER USER後にFLUSH PRIVILEGESを追加する必要はありません。

-- ユーザー / ホスト一覧
SELECT user, host FROM mysql.user;

-- 'app'@'%' があり 'app'@'192.168.1.5' が無い場合は % が優先されないことに注意
-- パスワード再設定
ALTER USER 'app'@'%' IDENTIFIED BY 'NewPass!';
FLUSH PRIVILEGES;

-- 権限確認
SHOW GRANTS FOR 'app'@'%';

ERROR 1062: Duplicate entry

下の旧UPSERT例は既存行を更新する操作です。重複を拒否したい処理の代替にはなりません。別のUNIQUEキーの衝突も確認します。VALUES(name)形式はMySQL 8.0.20から非推奨で、対象版の公式構文を確認してください。既存データを削除してエラーを消す手順にも進みません。

ERROR 1062 (23000): Duplicate entry 'taro@example.com' for key 'users.users_email_unique'
-- どのインデックスで衝突したか確認
SHOW INDEX FROM users WHERE Key_name = 'users_email_unique';

-- UPSERT で回避
INSERT INTO users (email, name) VALUES ('taro@example.com', 'Taro')
ON DUPLICATE KEY UPDATE name = VALUES(name), updated_at = NOW();

-- 既存重複データを集計
SELECT email, COUNT(*) FROM users GROUP BY email HAVING COUNT(*) > 1;

ERROR 1064: SQL syntax

予約語・カンマ・クォート等を、エラー位置と対象サーバーの構文で確認します。下には失敗する例とCREATE TABLEによる変更例が含まれます:

-- ❌ order は予約語
CREATE TABLE order (id INT);

-- ✅ バッククォートで囲む
CREATE TABLE `order` (id INT);

-- ❌ クォートが閉じていない
SELECT * FROM users WHERE name = 'taro;

-- ✅
SELECT * FROM users WHERE name = 'taro';

ERROR 2002: Can't connect to local MySQL server

下のsystemctl startはサービスを起動する変更操作で、診断の初手ではありません。コンテナ/マネージドDBではsystemctlを使わない場合もあります。mysql_config --socketはビルド時の既定ソケットで、稼働サーバーの実パスの証明ではありません。TCPへ変えると接続先や適用アカウント/認証方式が変わり得るため、rootへの安易な切替はしません。

# サービス確認
systemctl status mysqld          # rpm 系
systemctl status mysql           # deb 系
systemctl status mariadb         # MariaDB

# ソケットパス確認
mysql_config --socket
# /var/lib/mysql/mysql.sock

# 起動
sudo systemctl start mysqld

# tcp 経由に切替(ローカルソケットが見つからない場合)
mysql -h 127.0.0.1 -P 3306 -u root -p

ERROR 1452 / 1451: 外部キー違反

次の旧例にあるFOREIGN_KEY_CHECKS=0は通常の解決策にしません。 1へ戻しても、その間に入れた不整合データは再検査されません。親子の列/値・投入順・更新/削除要件を確認します。ON DELETE CASCADEは子データも削除する設計変更で、単なるエラー回避ではありません。既存制約に同じALTERを追加しないでください。

-- 1452: 子に親未存在
-- 1451: 親に紐づく子が残っている

-- 一時的に FK チェックを無効化(一括 import 等)
SET FOREIGN_KEY_CHECKS = 0;
-- ... 大量 INSERT ...
SET FOREIGN_KEY_CHECKS = 1;

-- 親レコードを先に投入
INSERT INTO categories (id, name) VALUES (1, 'IT');
INSERT INTO articles (id, category_id, title) VALUES (1, 1, 'MySQL Guide');

-- 削除時は ON DELETE CASCADE / SET NULL を検討
ALTER TABLE articles
ADD CONSTRAINT fk_cat FOREIGN KEY (category_id) REFERENCES categories(id)
ON DELETE CASCADE;

ERROR 1366: Incorrect integer value

この見出しは数値変換の場合です。1366にはIncorrect string value等もあるため、番号だけで原因を固定しません。下の旧例のsql_mode解除は推奨しません。「空→NULLが正しい」はnullableで業務上も未指定を許す列に限ります。NOT NULL列ではNULLも拒否され、整数以外の入力を一律に欠損へ変えると情報を失います。

-- strict mode 確認
SHOW VARIABLES LIKE 'sql_mode';

-- 一時的に外す(推奨しない)
SET SESSION sql_mode = REPLACE(@@sql_mode, 'STRICT_TRANS_TABLES', '');

-- 正しい修正: アプリ側で空→NULL 変換
INSERT INTO users (age) VALUES (NULL);  -- ✅
INSERT INTO users (age) VALUES ('');     -- ❌ 1366

ERROR 1093: target table for update in FROM clause

下の2つのDELETEを重複整理として実行しないでください。 MIN(id)を全emailグループから選ぶため、重複していない行も削除対象です。旧例のチェック印はデータ保全や削除対象の正しさを保証しません。派生表の扱いも対象版・最適化条件次第です。まずSELECTで対象集合を確認し、何を残すか決めます。DELETE/UPDATEは別途バックアップと影響確認を伴う変更作業です。

-- ❌
DELETE FROM users WHERE id IN (SELECT MIN(id) FROM users GROUP BY email);

-- ✅ サブクエリを別名でラップ
DELETE FROM users WHERE id IN (
    SELECT id FROM (
        SELECT MIN(id) AS id FROM users GROUP BY email
    ) AS t
);

ERROR 1170: BLOB/TEXT used in key without prefix length

下は別々のテーブル作成例で、まとめて実行しません。通常のB-treeとFULLTEXTは検索目的が異なり、FULLTEXTは一律の代用品ではありません。prefix長255も万能ではなく、文字コード/行形式/バージョンのキーバイト上限と検索条件で検証します。個別の子ページから該当条件を選んでください。

-- ❌ TEXT 列をそのまま INDEX
CREATE TABLE posts (body TEXT, INDEX (body));

-- ✅ prefix length 指定
CREATE TABLE posts (body TEXT, INDEX (body(255)));

-- 全文検索したいなら FULLTEXT
CREATE TABLE posts (body TEXT, FULLTEXT (body));

ERROR 2006 / 2013: gone away / Lost connection

原因確認 / 対処
wait_timeout 経過で切断SHOW VARIABLES LIKE 'wait_timeout'; / アプリで再接続
max_allowed_packet 超過SHOW VARIABLES LIKE 'max_allowed_packet';で実効値と送受信サイズを比較。無測定のGLOBAL変更はしない
OOM Killer に殺された権限のある範囲でOS/コンテナの終了理由とメモリ上限を照合。単純な増設/設定増量で原因確定としない
ロードバランサのアイドルタイムアウトTCP keepalive / コネクションプール調整

調査用スニペット

次の旧ブロック全体は読み取り専用ではありません。 末尾のSET GLOBALは本番のログ設定を変えるため、許可と容量/保持/復旧の計画なしに実行しません。SHOW FULL PROCESSLISTやInnoDB状態等にSQL・個人情報が含まれ得るので、そのまま公開しないでください。SHOW WARNINGS/ERRORSはそのセッションの直近の対象文の診断で、全接続の障害履歴ではありません。

-- 直近のエラー / 警告
SHOW WARNINGS;
SHOW ERRORS;

-- ステータス
SHOW GLOBAL STATUS LIKE 'Aborted%';
SHOW GLOBAL STATUS LIKE 'Connections';

-- 実行中スレッド
SHOW FULL PROCESSLIST;

-- ロック状況
SELECT * FROM performance_schema.data_locks\G
SHOW ENGINE INNODB STATUS\G

-- スロークエリ ON
SET GLOBAL slow_query_log = 'ON';
SET GLOBAL long_query_time = 1;

FAQ

Q: アプリのエラーログにはエラー番号が無い
A: SQLSTATEとMySQL固有の番号を分けます。PDOのerrorInfo[0]はSQLSTATE、errorInfo[1]はドライバ固有の番号です。PDOException::getCode()を常にMySQL番号と扱いません。LaravelのQueryExceptionもerrorInfoの有無を確認し、SQL・bindings・例外全文を公開ログへ出さないでください。mysqli_errno()も対象接続の診断です。

Q: ステージングでは出ないのに本番でだけ 1366 が出る
A: sql_modeだけと決めつけず、実際のメッセージ・列型/null許可・接続と列の文字コード・入力値の型/差分を照合します。エラーを隠すために本番のstrictを解除したり、設定ファイルを丸ごと上書きしたりしません。

子ページ
  1. 1071 Specified key was too long; max key length is 767 bytes
  2. ERROR 1063 (42000): Incorrect column specifier for column '~'
  3. mysqld: Can't change dir to '...\MySQL\MySQL Server X.X\data\' (OS errno 2 - No such file or directory)
  4. Install/Remove of the Service Denied!
  5. Datetime 型が NULL に見える
  6. Warning: World-writable config file '/etc/mysql/my.cnf' is ignored
  7. ERROR 1698 (28000): Access denied for user 'root'@'localhost'
  8. Exception: Wrong MySQL configuration
  9. [Warning] TIMESTAMP with implicit DEFAULT value is deprecated.
  10. ERROR 1820 (HY000): You must reset your password using ALTER USER statement before executing this statement.
  11. ERROR 1819 (HY000): Your password does not satisfy the current policy requirements
  12. Incorrect column specifier for column 'カラム名'
  13. BLOB/TEXT column 'description' used in key specification without a key length
  14. ERROR: /bin/sh: mysql_config: コマンドが見つかりません
  15. Host '...' is blocked because of many connection errors; unblock with 'mysqladmin flush-hosts'
  16. CSVエクスポート時に「ERROR 1045 (28000): Access denied for user 'username'@'localhost'」エラーが表示される
  17. Cannot execute statement: impossible to write to binary log since BINLOG_FORMAT = STATEMENT
  18. SQLSTATE[22007]: Invalid datetime format: 1366 Incorrect string value: ~
同階層のページ
  1. ダウンロード&インストール方法(Windows)
  2. インストール方法(Linux)
  3. コマンド一覧
  4. SQL
  5. データ型
  6. 関数
  7. 管理ツール
  8. 設定
  9. パフォーマンスチューニング関連
  10. エクスポートおよびインポート
  11. エラー&トラブル
  12. 文字コードの確認
  13. 実行中の SQL の状態確認およびプロセスキルの方法
  14. パスワードの無効化設定
  15. root ユーザーの初期パスワード確認方法
  16. rootユーザーのパスワード変更方法
  17. LIMIT, OFFSET の始まりと挙動
  18. mysqlのバージョン確認方法
  19. MySQLで実行計画を表示する方法
  20. レプリケーションのステータス確認方法
  21. 中央値の導き方(バージョン8未満)
  22. 階層SQL(バージョン8未満)
  23. パーセンタイルの導き方
  24. 特定スキーマの全テーブルの全カラム情報を取得する方法

最近更新/作成されたページ