添加生成列导致Docker环境下MariaDB 10崩溃、表损坏问题求助
问题根因
该问题属于MariaDB 10.x早期分支的已知BUG:多次连续添加使用NOW()这类非确定性函数的VIRTUAL(非存储)生成列时,会触发InnoDB元数据写入冲突,导致实例崩溃、表空间被标记为损坏。你使用的mariadb:10是大版本浮动标签,实际拉取的大概率是存在该BUG的10.2/10.3旧版本。
损坏表修复方案
所有操作前必须先完整备份数据目录,避免数据丢失
- 第一步:停止运行的MariaDB容器,完整备份本地挂载的整个数据库数据目录。
- 第二步:启动容器时追加启动参数
--innodb-force-recovery=3,该参数会跳过InnoDB后台崩溃恢复流程,允许以只读模式访问表数据。 - 第三步:进入容器执行
mysqldump导出program表的全量数据:
mysqldump -u [你的数据库用户名] -p [你的库名] program > program_backup.sql
- 第四步:关闭容器,移除原有损坏的表空间文件(
.ibd、.rfm文件),正常启动无恢复参数的MariaDB实例,重新建表后导入备份的SQL文件即可恢复数据。
后续规避方案
- 不要使用
mariadb:10这类大版本浮动标签,固定使用经过验证的稳定次级版本镜像,例如mariadb:10.11,该版本已完全修复生成列相关的崩溃BUG。 - 单次ALTER语句内完成所有生成列的添加操作,不要拆分多次执行,示例如下:
ALTER TABLE program ADD is_current tinyint AS ( IF ( status IN ('active', 'suspended') AND start_date >= NOW(), 1, 0 ) ), ADD is_covered tinyint AS ( IF ( status IN ('active', 'suspended') AND start_date <= NOW(), 1, 0 ) );
- 若确实需要分批次添加生成列,每次执行ALTER之后先运行
OPTIMIZE TABLE program;刷新表元数据,再执行下一次变更操作。
内容的提问来源于stack exchange,提问作者qotsa42
相关产品推荐
相关产品推荐

