首页
关于我们
友链链接
壁纸下载
更多
统计中心
热点搜索
图床上传
推荐
剩余价值
磁链清理
IP定位
Search
1
[Win DD包] wes7-x86-cn-精简,安装后仅占用1.55G存储空间
25,929 阅读
2
v2rayN基础使用教程、配置说明、添加订阅、路由选择
18,239 阅读
3
鸿蒙Next也能科学上网?Clash Meta for harmorny next os
11,623 阅读
4
纯血鸿蒙系统如何安装电报、推特、Tiktok和油管APP
8,948 阅读
5
保姆级教程!甲骨文ARM DD成Debian10并升级内核成5.10
6,494 阅读
Linux学堂
网站建设
网络资源
主题插件
固件工具
主机评测
MV频道
登录
Search
标签搜索
vps
typecho
linux
bench
mysql
cloudflare
nginx
lnmp
empirecms
ssl
openwrt
google
centos
docker
qbittorrent
telegram
n1
301
free
serverstat
V+变量
累计撰写
304
篇文章
累计收到
256
条评论
首页
栏目
Linux学堂
网站建设
网络资源
主题插件
固件工具
主机评测
MV频道
页面
关于我们
友链链接
壁纸下载
统计中心
热点搜索
图床上传
推荐
剩余价值
磁链清理
IP定位
搜索到
1
篇与
的结果
2026-06-03
Discuz X3.5升级到Discuz X5及数据库迁移后出现的约束CONSTRAINT失败 + 主键重复Duplicate entry for key问题的解决
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,在大表上非常慢,且导入后还需重新添加,远不如临时禁用检查高效。不要手动编辑第 6868 行:SQL 备份文件通常有数百 MB 甚至 GB 级别,用普通编辑器打开极易卡死或损坏文件。即使定位到该行,后续可能还有成千上万条同样违规的数据。此操作仅影响当前导入会话:check_constraint_checks=0 是会话级变量,不会影响数据库中已有的约束定义,也不会影响其他连接或后续的正常使用。3.3 主键重复Duplicate entry for key博主在导入mysql数据库过程中还出现了主键重复问题:ERROR 1062 (23000) at line 19: Duplicate entry 'XXXXX' for key 'PRIMARY'这个错误 ERROR 1062 (23000): Duplicate entry 'XXXXX' for key 'PRIMARY' 表示在导入 SQL 备份时,目标数据库表中已经存在主键为 XXXXX 的记录,导致插入冲突。这通常发生在以下两种情况:非空库恢复:目标数据库不是全新的,里面已有旧数据或之前导入失败残留的数据。SQL 文件问题:备份文件中包含了 CREATE TABLE 但没有 DROP TABLE IF EXISTS,或者您正在重复导入同一个备份文件。Qwen3.7-Max这个错误 ERROR 1062 (23000): Duplicate entry '38472' for key 'PRIMARY' 表示在导入 SQL 备份时,目标数据库表中已经存在主键为 38472 的记录,导致插入冲突。这通常发生在以下两种情况:非空库恢复:目标数据库不是全新的,里面已有旧数据或之前导入失败残留的数据。SQL 文件问题:备份文件中包含了 CREATE TABLE 但没有 DROP TABLE IF EXISTS,或者您正在重复导入同一个备份文件。🛠️ 解决方案(按场景选择)方案1:全新恢复 / 覆盖现有数据(最常见)如果您确认目标数据库可以被完全覆盖,请在导入命令中添加 --force 参数,让 MySQL 忽略重复键错误并继续执行后续语句:mysql -u root -p database_name --force < database_name.sql⚠️ 注意:--force 会跳过所有报错行(包括重复键、约束失败等),但不会回滚已成功的部分。结合您之前的 #4025 错误,建议组合使用:mysql -u root -p database_name --force --init-command="SET SESSION check_constraint_checks=0;" < database_name.sql方案二:确保干净恢复(推荐用于生产环境)如果希望避免任何数据混淆,最稳妥的做法是先清空再导入:# 1. 删除并重建数据库(彻底清除旧数据) mysql -u root -p -e "DROP DATABASE IF EXISTS \`database_name\`; CREATE DATABASE \`database_name\` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;" # 2. 重新授权(如需要) mysql -u root -p -e "GRANT ALL PRIVILEGES ON \`bbs-gvars-com\`.* TO 'your_user'@'localhost'; FLUSH PRIVILEGES;" # 3. 导入备份 mysql -u root -p database_name --init-command="SET SESSION check_constraint_checks=0;" < database_name.sql3.4 🛠️ 一键解决命令结合所有问题(约束失败 + 主键重复),使用以下组合命令一次性解决:mysql -u root -p database_name \ --force \ --init-command="SET SESSION check_constraint_checks=0; SET FOREIGN_KEY_CHECKS=0; SET UNIQUE_CHECKS=0; SET sql_mode='';" \ < database_name.sql参数说明:--force:跳过 Duplicate entry 等所有非致命错误,继续执行后续 SQLcheck_constraint_checks=0:解决当前 #4025 CONSTRAINT failed 及之前的 fields 约束错误FOREIGN_KEY_CHECKS=0:避免外键顺序导致的导入失败sql_mode='':解决 MODIFY COLUMN 语法兼容性问题所有设置均为 SESSION 级别,仅影响本次导入连接,不会污染数据库全局配置3.5🔍 为什么帖子内容也会触发约束?原因具体表现MySQL → MariaDB 迁移MySQL 5.7/8.0 对 CHECK 约束“只解析不执行”,旧帖内容可能含 \0、截断的 UTF-8 字符等;MariaDB 10.3+ 会严格校验Discuz! 版本升级X3.5 为 content 添加了长度/格式约束,但备份来自 X3.4 或更早版本,存在历史脏数据编辑器/插件残留第三方编辑器或采集插件写入的内容不符合原生 Discuz! 格式规范3.6⚠️ 导入后必须执行的验证与修复约束检查被临时禁用意味着脏数据会被原样写入。导入完成后,请务必执行以下检查和修复:-- 1. 检查 content 为空的异常帖子 SELECT pid, tid FROM pre_forum_post WHERE content = '' OR content IS NULL; -- 2. 检查包含非法字符或截断内容的帖子(可选) SELECT pid, tid FROM pre_forum_post WHERE content NOT REGEXP '^[\x09\x0A\x0D\x20-\x7E\x{4E00}-\x{9FFF}]*$'; -- 3. 统一修复空内容为 Discuz! 默认占位符 UPDATE pre_forum_post SET content = '[内容已丢失]' WHERE content = '' OR content IS NULL;3.7💡 关键提醒不要逐行定位 line 16:SQL 备份文件中可能有成千上万条违规帖子内容,逐条修复不现实。不要删除约束定义:ALTER TABLE ... DROP CONSTRAINT 在大表上极慢,且导入后还需重建,远不如临时禁用高效。--force 的副作用:它会跳过所有错误(包括真正的语法错误)。导入完成后务必通过行数对比验证数据完整性:SELECT COUNT(*) FROM pre_forum_post;-- 与备份源或导出时的记录数对比如果仍报其他 CONSTRAINT 错误:说明还有其他表存在同样问题,上述 --init-command 已经覆盖了所有常见约束类型,理论上不应再出现同类报错。
2026年06月03日
1 阅读
0 评论
0 点赞