You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MySQL 8.x并行执行TRUNCATE是否会导致INSERT外键约束报错?

问题判定

该问题不属于配置遗漏,是MySQL 8.0版本存在的并发DDL引发外键元数据损坏的已知Bug。

  • 已在MySQL 8.0.29及多个8.x中间版本稳定复现,相同操作逻辑在MySQL 5.7版本下运行无异常
  • 异常触发特征:被关联的父表中已存在外键要求的合法ID记录,但MySQL持续抛出外键约束校验失败错误,即使新开会话连接数据库执行插入操作仍无法成功,异常状态会持续留存。
复现流程

基础复现步骤:

  1. 创建父表A
  2. 创建子表B,为子表B配置指向表A主键id字段的外键约束
  3. 在会话级别关闭FOREIGN_KEY_CHECKS参数后,并行执行TRUNCATE表A、TRUNCATE表B操作
  4. 向表A插入id为1的记录
  5. 向表B插入关联字段值为1的记录

该报错为概率触发,重复执行上述流程100次左右必然触发异常。

稳定复现脚本

执行以下bash脚本即可触发数据库异常状态:

#!/bin/bash
DB_USER='root';
DB_PASSWD='root';

DB_NAME='mysql_8_bug';
TABLE_A='a';
TABLE_B='b';

set -m

# 初始化环境
mysql --user=$DB_USER --password=$DB_PASSWD << EOF
CREATE DATABASE IF NOT EXISTS $DB_NAME DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
EOF

mysql --user=$DB_USER --password=$DB_PASSWD $DB_NAME << EOF
DROP TABLE IF EXISTS $TABLE_A, $TABLE_B;
EOF


mysql --user=$DB_USER --password=$DB_PASSWD $DB_NAME << EOF
CREATE TABLE $TABLE_A (id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY);
EOF

mysql --user=$DB_USER --password=$DB_PASSWD $DB_NAME << EOF
CREATE TABLE $TABLE_B
(id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
int_a_id BIGINT(20) UNSIGNED DEFAULT NULL,
CONSTRAINT fk_a_id FOREIGN KEY (int_a_id) REFERENCES a (id));
EOF
# 初始化结束


for i in {0..100}
do

# 并行执行TRUNCATE操作
  mysql --user=$DB_USER --password=$DB_PASSWD $DB_NAME --execute="SET @@session.FOREIGN_KEY_CHECKS = 0; TRUNCATE TABLE $TABLE_A; SET @@session.FOREIGN_KEY_CHECKS = 1;" &
  mysql --user=$DB_USER --password=$DB_PASSWD $DB_NAME --execute="SET @@session.FOREIGN_KEY_CHECKS = 0; TRUNCATE TABLE $TABLE_B; SET @@session.FOREIGN_KEY_CHECKS = 1;" &
  wait

  mysql --user=$DB_USER --password=$DB_PASSWD $DB_NAME --execute="INSERT INTO $TABLE_A (id) VALUES (1);"


  mysql --user=$DB_USER --password=$DB_PASSWD $DB_NAME --execute="INSERT INTO $TABLE_B (int_a_id) VALUES (1);"
  if [ $? -gt 0 ]
  then
  echo "触发异常!此时表A中已存在id=1的记录,但表B插入关联数据持续报错,数据库进入异常状态。"
  exit 0
  fi

done
根因与规避方案
  • 根因:MySQL 8.0重构了数据字典与元数据锁(MDL)实现逻辑,关闭会话级外键检查时并行TRUNCATE存在外键关联的表,会触发竞态条件,导致InnoDB存储的外键元数据与实际表结构不一致,外键校验逻辑错误判定父表无对应合法记录。
  • 规避方案:存在外键关联的表执行TRUNCATE操作时,不要关闭外键检查后并行执行,需按照「先清空子表、后清空父表」的顺序串行操作。
  • 异常修复:如果已经触发该问题,执行ALTER TABLE 异常子表名 FORCE;重建表即可修复损坏的外键元数据,恢复正常写入。

内容的提问来源于stack exchange,提问作者Dimitry

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 10:45:49