LATEST FOREIGN KEY ERROR - xiaoboluo768/qianjinliangfang GitHub Wiki

  • 第四段信息,这一段外键错误的信息一般不会出现,除非你服务器上发生了外键错误,有时问题在于事务在插入,更新或删除一条记录时要寻找父表或子表,还有时候是当innodb尝试增加或删除一个外键或者修改一个已经存在的外键时,发现表之间类型不匹配,这部分输出对于调试与innodb不明确的外键错误发生的准确原因非常有帮助,下面搞一个示例来看看:
# 创建父表:
mysql> create table parent(parent_id int not null,primary key(parent_id)) engine=innodb;

# 创建子表:
mysql> create table child(child_id int not null,key child_id(child_id),constraint i_child foreign key(child_id) references parent(parent_id)) engine=innodb;

# 插入数据:
mysql> insert into parent(parent_id) values(1);
mysql> insert into child(child_id) values(1);
  • 有两种基本的外键错误: 第一种:以某种可能违反外键约束关系的方法增加,更新,删除数据,将导致第一类错误,如,在父表中删除行时发生如下错误:
mysql> delete from parent;
ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails (`xiaoboluo`.`child`, \
CONSTRAINT `i_child` FOREIGN KEY (`child_id`) REFERENCES `parent` (`parent_id`)) # 错误信息相当明了,对所有由增加,\
删除,更新不匹配的行导致的错误都会看到相似的信息,下面是show engine innodb status的输出:
  • 在show engine innodb status输出中可以看到类似如下信息
------------------------
LATEST FOREIGN KEY ERROR
------------------------
160128  1:17:06 Transaction:  #这行显示了最近一次外键错误的日期和时间
TRANSACTION D203D6, ACTIVE 0 sec updating or deleting
mysql tables in use 1, locked 1
4 lock struct(s), heap size 1248, 2 row lock(s), undo log entries 1
MySQL thread id 20027, OS thread handle 0x7f0a4c0f8700, query id 1813996 localhost root updating
delete from parent
Foreign key constraint fails for table `xiaoboluo`.`child`:

, #上面部分显示了关于破坏外键约束的事务详情。后边部分显示了发现错误时innodb正尝试修改的准确数据,输出中有许多是转换成可打印格式的行数据。

CONSTRAINT `i_child` FOREIGN KEY (`child_id`) REFERENCES `parent` (`parent_id`)
Trying to delete or update in parent table, in index `PRIMARY` tuple:
DATA TUPLE: 3 fields;
0: len 4; hex 80000001; asc     ;;
1: len 6; hex 000000d203d6; asc       ;;
2: len 7; hex 1e000001ca0110; asc        ;;


But in child table `xiaoboluo`.`child`, in index `child_id`, there is a record:
PHYSICAL RECORD: n_fields 2; compact format; info bits 0
0: len 4; hex 80000001; asc     ;;
1: len 6; hex 000013a99b3e; asc      >;;
  • 第二种:尝试修改父表的表结构时发生的错误,这种错误就没有那么清楚了,这可能会让调试更困难:
mysql> alter table parent modify parent_id int unsigned not null;
ERROR 1025 (HY000): Error on rename of './xiaoboluo/#sql-b695_4e3b' to './xiaoboluo/parent' (errno: 150)
  • 查看show engine innodb status输出信息:
------------------------
LATEST FOREIGN KEY ERROR
------------------------
160128  1:32:33 Error in foreign key constraint of table xiaoboluo/child:
there is no index in referenced table which would contain
the columns as the first columns, or the data types in the
referenced table do not match the ones in table. Constraint:
,
CONSTRAINT "i_child" FOREIGN KEY ("child_id") REFERENCES "parent" ("parent_id")
The index in the foreign key in table is "child_id"
See http://dev.mysql.com/doc/refman/5.5/en/innodb-foreign-key-constraints.html
for correct foreign key definition.
InnoDB: Renaming table `xiaoboluo`.<result 2 when explaining filename '#sql-b695_4e3b'> to `xiaoboluo`.`parent` failed!

# 上面的错误是数据类型不匹配,外键列必须有完全相同的数据类型,包括任何的修饰符(如这里父表多加了一个unsigned,这也是问题所在),\
当看到1025错误并不理解为什么时,最好查看下innodb status。在每次看到有新错误时,外键错误信息都会被重写,\
percona toolkit中的pt-fk-error-logger工具可以用表保存这些信息以供后续分析。

上一篇:SEMAPHORES | 下一篇:LATEST DETECTED DEADLOCK