V变量—建站日记 - discuz
type: channel
link: http://vvars.com/tag/discuz/
items: Discuz X3.5升级到Discuz X5及数据库迁移后出现的约束CONSTRAINT失败 + 主键重复Duplicate entry for key问题的解决

Discuz X3.5升级到Discuz X5及数据库迁移后出现的约束CONSTRAINT失败 + 主键重复Duplicate entry for key问题的解决
type: item
date: 2026-06-03T00:02:00+08:00
description: 1 背景博主最近把手头上唯一的论坛从DISCUZX3.5升级到Discuz X5，另外把建站VPS提供商从netcup转到Hostdizre，原因是Netcup的月租价格从5.75O提到6.81O，本来网站就没什么流量，索性就以80元的价格忍痛出掉了VPS1000 G11翻倍款（2024年黑五），迁移过程中无论是mysql导入，还是phpmyadmin,都出现了约束CONSTRAINT失败 + 主键重复Duplicate entry for key问题，借助AI找到了解决办法，这里记录一下，方面以后自己查阅。2 升级教程升级比较简单，直接按官方教程就行了：从 X5.0 开始安装程序内置升级程序，升级前请关闭站点、关闭所有插件。请详细阅读下面的内容：1、确保您的旧版本 Discuz! 必须为 X3.5 版本，如不满足版本要求请先升级到此版本； 2、确保 UCenter 和 Discuz! 部署在一个数据库中； 3、确保您已备份了数据库和程序文件，将旧版本程序文件移动到其他目录下； 4、将旧版本的配置文件 config/config_global.php、config/config_ucenter.php 复制到当前新版本的 config/ 目录中； 5、点击“下一步”开始升级； 6、升级完成后可以将旧版本中 source/plugin/ 目录下的插件文件挑选后复制到新版本的对应目录下、将 template/ 目录下的模板文件挑选后复制到新版本的对应目录下（不要复制 template/default/ 目录）； 7、升级完成后 data/attachment/ 目录以及 data/ 目录下其他目录请酌情复制；如旧版本应用涉及其他目录中的文件，请自行咨询相关开发者复制；3 数据迁移3.1 直接用mysql命令迁移在源服务器终端导出数据mysqldump -u root -p --databases database_name> database_name.sql在新服务器终端导入数据mysql -u root -p database_name --force < database_name.sql3.2 CONSTRAINT约束失败问题博主在导入数据时，出现如下错误：ERROR 4025 (23000) at line XXXX: CONSTRAINT `pre_common_member_profile.fields` failed for `database_name`.`pre_common_member_profile通过AI找到了解决办法：这个错误明确指出了在导入 SQL 文件的第 XXXX 行时，pre_common_member_profile 表的 fields 字段数据违反了 MariaDB 的 CHECK 约束。由于是在恢复数据库，最安全、最高效的做法是临时关闭约束检查，而不是去逐条修改备份文件中的数据（这既耗时又容易破坏备份完整性）。出现这个问题的原因：原因说明MySQL → MariaDB 迁移MySQL 8.0 之前对 CHECK 约束是“只解析不执行”的，旧数据可能包含空字符串或非法序列化值；MariaDB 会严格校验Discuz! 版本差异新版 Discuz! 建表脚本为 fields 添加了格式约束（如必须为合法 PHP 序列化数组），但您的备份来自旧版，存在 '' 等不合规值备份导出环境宽松原服务器可能禁用了约束检查或使用了更宽松的 sql_mode，导致脏数据被成功备份方法一：命令行导入时直接注入参数（最推荐）如果您使用命令行恢复，无需修改 SQL 文件，直接在命令中追加参数即可跳过该约束：mysql -u root -p database_name --init-command="SET SESSION check_constraint_checks=0;" < database_name.sql原理：--init-command 会在每次连接建立时自动执行，确保整个导入过程都在禁用约束检查的状态下进行。方法二：修改 SQL 备份文件头部如果您使用宝塔面板、Navicat 或其他工具导入，无法传递命令行参数，请用文本编辑器（如 Notepad++ / VSCode）打开 .sql 文件，在最顶部添加：SET SESSION check_constraint_checks = 0; SET FOREIGN_KEY_CHECKS = 0; SET UNIQUE_CHECKS = 0; SET sql_mode = '';保存后重新导入。导入完成后，这些设置会随会话结束自动失效，无需手动恢复。🛠️重要提醒不要尝试删除约束后再导入：删除/重建约束需要 ALTER TABLE，在大表上非常慢，且导入后还需…