INSERT失败主因有四:1.主键/唯一索引冲突报ERROR 1062;2.字段类型或长度不匹配在严格模式下报ERROR 1406/1366;3.外键引用不存在父记录报ERROR 1452;4.权限不足或MyISAM引擎限制导致中断。
最常见的失败原因是试图插入重复的 PRIMARY KEY 或 UNIQUE 字段值。MySQL 会直接报错 ERROR 1062 (23000): Duplicate entry 'xxx' for key 'yyy'。
SHOW CREATE TABLE table_name; 确认哪些字段有 UNIQUE 或 PRIMARY KEY 约束SELECT * FROM table_name WHERE column_name = 'value';
INSERT IGNORE(静默跳过)、REPLACE INTO(删旧插新)或 INSERT ... ON DUPLICATE KEY UPDATE(冲突时更新)INSERT IGNORE 会吞掉其他错误(如字段超长),不推荐在调试阶段使用比如向 VARCHAR(10) 插入 15 个字符,或向 INT 插入字符串 'abc',MySQL 在严格模式下会拒绝写入并报错 ERROR 1406 (22001): Data too long 或 ERROR 1366 (HY000): Incorrect integer value。
SELECT @@sql_mode;,若含 STRICT_TRANS_TABLES 或 STRICT_ALL_TABLES,则类型校验严格DESCRIBE table_name;,重点核对 Type 和 Null 列NULL 字符串)当插入记录引用了不存在的父表主键时,MySQL 报错 ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails。
SELECT CONSTRAINT_NAME, COLUMN_NAME, REFERENCED_TABLE_NAME, REFERENCED_COLUMN_NAME FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE WHERE TABLE_NAME = 'child_table' AND CONSTRAINT_SCHEMA = DATABASE();
SELECT id FROM parent_table WHERE id = 123;
SET FOREIGN_KEY_CHECKS = 0;,完事后记得设回 1
用户没有 INSE 权限时,报错
RTERROR 1142 (42000): INSERT command denied to user;而使用 MyISAM 引擎时,如果磁盘满或达到 max_allowed_packet 限制,也会静默失败或报错 ERROR 2006 (HY000): MySQL server has gone away。
SHOW GRANTS FOR CURRENT_USER;,确保包含 GRANT INSERT ON db.table TO 'user'@'%';
SHOW TABLE STATUS LIKE 'table_name';,优先用 InnoDB(支持事务、行锁、外键)df -h(Linux)或看 MySQL 错误日志中是否有 disk full 提示SET GLOBAL max_allowed_packet = 64*1024*1024;,但要同步修改配置文件中的 max_allowed_packet
SELECT t.TABLE_NAME, t.ENGINE, t.TABLE_ROWS, ROUND(((t.DATA_LENGTH + t.INDEX_LENGTH) / 1024 / 1024), 2) AS size_mb FROM information_schema.TABLES t WHERE t.TABLE_SCHEMA = DATABASE() AND t.TABLE_NAME = 'your_table';
实际排障时,别只盯着 SQL 语句本身——先看 MySQL 错误日志(通常是 /var/log/mysql/error.log 或由 log_error 配置项指定),里面常有比客户端提示更具体的上下文,比如死锁链路、磁盘 I/O 超时、连接被 kill 的原因。很多“插入失败”根本不是语法问题,而是资源卡住了。