ERROR 1045 是权限认证失败,因密码错误、用户不存在或 host 不匹配;root@localhost 与 root@127.0.0.1 视为不同用户;新建用户需执行 FLUSH PRIVILEGES;Docker 启动需检查 MYSQL_ROOT_PASSWORD;MySQL 8.0 默认插件不兼容旧客户端,可改用 mysql_native_password。

ERROR 1045 (28000):Access denied for user
这是权限认证失败最典型的错误,不是密码错了就是用户不存在,或者 host 不匹配。
-
root@localhost和root@127.0.0.1在 MySQL 里是两个不同用户,注意host字段是否精确匹配 - 新创建用户后必须执行
FLUSH PRIVILEGES;,否则权限不生效 - 如果用 Docker 启动 MySQL,检查是否传入了
MYSQL_ROOT_PASSWORD环境变量,空密码会导致该错误 - MySQL 8.0 默认使用
caching_sha2_password插件,旧客户端(如某些 Python MySQLdb)不支持,可临时改用:ALTER USER 'user'@'host' IDENTIFIED WITH mysql_native_password BY 'password';
ERROR 1062 (23000):Duplicate entry for key
主键或唯一索引冲突,常见于 INSERT 或 REPLACE 场景。
- 不要依赖应用层“先查再插”,并发下仍可能触发;改用
INSERT IGNORE或ON DUPLICATE KEY UPDATE - 注意字符串比较的 collation 影响:比如
utf8mb4_0900_as_cs区分大小写和空格,而utf8mb4_general_ci可能隐式去重 - 复合唯一索引中,
NULL值不参与唯一性校验,多行(1, NULL)不报错 - 自增主键达到上限(如
TINYINT UNSIGNED最大 255)后继续插入也会报此错,但错误信息一样,需检查字段类型
ERROR 1213 (40001):Deadlock found when trying to get lock
死锁不是异常,是 InnoDB 主动检测并回滚其中一个事务的正常行为,关键在如何减少发生频率。
- 事务越短越好,避免在事务里做 HTTP 请求、文件读写等耗时操作
- 所有业务按固定顺序访问表和行(例如总是先更新
orders再更新inventory),能大幅降低死锁概率 - 用
SELECT ... FOR UPDATE时,尽量加 where 条件走索引;全表扫描锁住所有行,极易引发连锁死锁 - 查看最近死锁日志:
SHOW ENGINE INNODB STATUS\G,重点关注LATEST DETECTED DEADLOCK部分
ERROR 2006 (HY000):MySQL server has gone away
连接被服务端主动断开,不是网络问题,而是超时或包过大。
- 最常见原因是
wait_timeout或interactive_timeout超时(默认 8 小时),长连接空闲后被 kill;应用应实现连接健康检查或自动重连 - 执行超大 SQL(如含 50MB JSON 字段的
INSERT)会触发max_allowed_packet限制,服务端直接断连;需同步调大客户端和服务端该参数 - MySQL 重启、OOM killer 杀进程、防火墙中断长连接,都会表现为该错误;建议在应用层捕获该错误并重试事务
- PHP 的
mysql_connect()已废弃,用mysqli或PDO并开启PDO::ATTR_EMULATE_PREPARES = false可减少部分误判
SHOW WARNINGS; 和 SHOW VARIABLES LIKE '%timeout%'; 比盲目搜错误号更有价值。很多“奇怪”的报错,根源都在配置项或事务隔离级别这类隐性设置上。











