加载SQL Dump时MariaDB生成列报错3105,求解决方案
解决SQL Dump导入时生成列的3105错误
错误原因
concatenated_package_version是生成列(Generated Column),数据库会自动通过定义的表达式计算其值,不允许手动插入或更新该列的数值。你的SQL Dump中包含了对该列的赋值语句,因此触发ERROR 3105。
可行解决方案
方案1:修改SQL Dump文件,移除生成列的引用
如果已经有现成的Dump文件,直接修改文件去掉生成列相关内容:
- 删除CREATE TABLE语句中的生成列定义:
sed -i '/`concatenated_package_version` varchar(255) as (concat("package_name", _utf8mb4':', "version"))/d' /tmp/$filename - 删除INSERT语句中该列的字段名和对应值:
# 移除字段列表中的该列 sed -i 's/`concatenated_package_version`,//g' /tmp/$filename # 移除VALUES中对应的占位符(根据实际字段位置调整) sed -i 's/, ""//g' /tmp/$filename - 重新执行原导入命令即可。
方案2:临时修改目标表结构,导入后恢复
- 先将目标库的
report表中生成列改为普通列:ALTER TABLE report MODIFY COLUMN concatenated_package_version varchar(255); - 执行原导入命令:
zcat /tmp/$filename | mysql --user="${DST_DB_USER}" --password="${DST_DB_PASS}" --host="${DST_DB_HOST}" "${DST_DB_NAME}" - 导入完成后,把该列改回生成列:
ALTER TABLE report MODIFY COLUMN concatenated_package_version varchar(255) AS (concat(`package_name`, _utf8mb4':', `version`)) STORED;注意:用反引号`包裹字段名,避免和字符串引号冲突,原定义中的双引号可能是导出时的语法问题。
方案3:跳过生成列所在表,分步导入
- 导入时跳过
report表:zcat /tmp/$filename | mysql --user="${DST_DB_USER}" --password="${DST_DB_PASS}" --host="${DST_DB_HOST}" --ignore-table="${DST_DB_NAME}".report "${DST_DB_NAME}" - 单独处理
report表:- 从原数据库导出
report表的结构(不含生成列)和数据:mysqldump --user="${SRC_DB_USER}" --password="${SRC_DB_PASS}" --host="${SRC_DB_HOST}" --ignore-columns=concatenated_package_version "${SRC_DB_NAME}" report > /tmp/report_dump.sql - 将该dump导入目标库:
mysql --user="${DST_DB_USER}" --password="${DST_DB_PASS}" --host="${DST_DB_HOST}" "${DST_DB_NAME}" < /tmp/report_dump.sql
- 从原数据库导出
- 在目标库的
report表中添加生成列:ALTER TABLE report ADD COLUMN concatenated_package_version varchar(255) AS (concat(`package_name`, _utf8mb4':', `version`)) STORED;
方案4:导出时排除生成列(预防方案)
如果后续还需要导出数据,直接在导出阶段忽略生成列,避免后续导入出错:
mysqldump --user="${SRC_DB_USER}" --password="${SRC_DB_PASS}" --host="${SRC_DB_HOST}" --ignore-columns=concatenated_package_version "${SRC_DB_NAME}" > /tmp/full_dump.sql
内容的提问来源于stack exchange,提问作者Tal Yitzhak
相关产品推荐
相关产品推荐

