Docker 中 MySQL 无法启动:`Encryption algorithm support missing` 与 `innodb_force_recovery` 抢救实录

张开发
2026/4/14 16:29:23 15 分钟阅读

分享文章

Docker 中 MySQL 无法启动:`Encryption algorithm support missing` 与 `innodb_force_recovery` 抢救实录
背景生产环境 MySQL 运行在 Docker 中数据目录通过卷挂载到宿主机例如/moli/data/mysql_prod_data。在异常关机或磁盘异常后容器反复重启失败。错误日志中可能出现-[MY-012671][InnoDB]Encryption algorithm support missing: N-[MY-013183]InnoDB Assertion failure: log0recv.cc:3388: errDB_SUCCESS- 调用栈位于recv_recovery_from_checkpoint_startredo 恢复阶段 -/usr/sbin/mysqld(ut_dbg_assertion_failed(char const*, char const*, unsigned long)0x2cc)[0x57dfa60de03c]/usr/sbin/mysqld(0x1dfb778)[0x57dfa5f96778]/usr/sbin/mysqld(dd::bootstrap::DDSE_dict_init(THD*, dict_init_mode_t, unsigned int)0x88)[0x57dfa5dcd088]/usr/sbin/mysqld(dd::upgrade_57::do_pre_checks_and_initialize_dd(THD*)0x2cf)[0x57dfa5dc399f]/usr/sbin/mysqld(0xf5a5e1)[0x57dfa50f55e1]/usr/sbin/mysqld(0x216a83f)[0x57dfa630583f]/lib/x86_64-linux-gnu/libpthread.so.0(0x74a4)[0x75de520a64a4]/lib/x86_64-linux-gnu/libc.so.6(clone0x3f)[0x75de503f5d0f]Trying to get some variables. Some pointers may be invalid and cause the dump to abort. Query(0): Connection ID(thread ID):1Status: NOT_KILLED The manual page at http://dev.mysql.com/doc/mysql/en/crashing.html contains information that shouldhelpyoufindout what is causing the crash.本文梳理原因判断、备份、强制恢复、导出、更换数据目录、导入的完整流程便于复现与内网 Runbook 化。现象与日志含义崩溃位置在 InnoDB从 redo 做恢复阶段而非普通连接或查询。Encryption algorithm support missing常见关联包括数据目录中存在表空间加密 / keyring相关元数据但当前实例未正确加载密钥或插件或使用过的MySQL 构建/镜像与当前不一致若从未启用加密redo 或页损坏也可能被误解析表现类似。若栈中出现upgrade_57等字样说明启动路径涉及5.7 → 8.0升级检查抢救阶段应尽量保持与原小版本一致避免随意换大版本「试运气」。卷挂载本身通常不是根因卷只是把同一套数据文件交给mysqld问题在于数据与进程/配置是否匹配以及文件是否损坏。宿主机侧数据目录属主若文件管理器中数据目录下文件属主为dnsmasq等与容器内MySQL 运行用户不一致的账号可能导致读写异常。官方mysql镜像内mysql用户常见为UID/GID 999以实际镜像为准dockerrun--rmmysql:8.0.15idmysql在已完成整目录备份的前提下sudochown-R999:999 /moli/data/mysql_prod_data修正后再次启动。此操作不能保证解决加密/redo 断言但成本低应优先执行。第一步备份任何操作之前整目录物理备份实例无法启动时尤为重要停止容器避免拷贝过程中文件仍在变化。使用保留权限的拷贝dockercompose stop mysqlsudocp-a/moli/data/mysql_prod_data /moli/backup/mysql_prod_data_$(date%Y%m%d_%H%M%S)备份应存放在与数据盘不同的磁盘或机器。逻辑备份mysqldump输出位置dockerexec容器名mysqldump...备份.sql重定向由宿主机 shell 处理因此.sql文件位于执行命令时终端的当前工作目录或所指定的绝对路径不在容器内部。第二步innodb_force_recovery尝试启动在[mysqld]或 Dockercommand中配置从 1 开始逐级增大直至 6innodb_force_recovery 1示例Composecommand中---innodb_force_recovery6说明数值越大越可能丢失数据越接近只读抢救场景。不可长期在生产环境以高档位运行目标是能够连接并导出数据。若低档位无法启动而高档位可以说明 redo/字典路径上存在严重不一致或损坏更需在导出后换新数据目录重建实例。第三步逻辑导出按需库表示例仅导出业务库moli_client_prod密码含特殊字符时用单引号包裹dockerexecmoli-mysql-prod mysqldump-uroot-p你的密码\--databasesmoli_client_prod\--single-transaction\--routines--events--triggers\moli_client_prod_$(date%Y%m%d_%H%M%S).sql--databases会在 dump 中包含CREATE DATABASE/USE便于导入到全新空实例。mysqldump: [Warning] Using a password on the command line can be insecure为预期安全提示不表示导出失败。根据导出文件体积如数 GB可粗判是否为空文件或严重不完整。数值越大越可能丢失数据越接近只读抢救场景。不可长期在生产环境以高档位运行目标是能够连接并导出数据。若低档位无法启动而高档位可以说明 redo/字典路径上存在严重不一致或损坏更需在导出后换新数据目录重建实例。innodb_force_recovery各档位含义160为默认值表示不启用强制恢复。16为 MySQL 官方定义的抢救模式语义与 MySQL 手册 · InnoDB 强制恢复 一致数字越大对正常一致性假设破坏越大数据越不可信。档位含义概要1SRV_FORCE_IGNORE_CORRUPT遇到损坏页时尽量不因此让服务器崩溃mysqldump导出时可能跳过损坏的二级索引记录。仍可能在某些 DML 上因损坏页失败。2SRV_FORCE_NO_BACKGROUND不启动主线程中的后台任务如purge等避免后台操作触碰坏页或加剧不一致。3SRV_FORCE_NO_TRX_UNDO崩溃恢复完成后不执行事务回滚不做 undo 驱动的回滚。未提交事务可能被当成已生效逻辑上更危险。4SRV_FORCE_NO_IBUF_MERGE不执行 change buffer插入缓冲合并。避免因合并读写坏页导致启动失败二级索引可能与主键索引暂时不一致。5SRV_FORCE_NO_UNDO_LOG_SCAN启动时不扫描 undo 日志InnoDB 将未结束的事务视为已提交。极易造成脏读进库表仅作最后抢救。6SRV_FORCE_NO_LOG_REDO不做 redo 日志的前滚roll-forward即跳过基于 redo 的恢复阶段。能绕过部分 redo/恢复路径上的断言或损坏但可能丢失崩溃前已提交却未反映到数据文件中的修改且数据文件与日志可能严重不一致。操作上的共识与手册一致任意innodb_force_recovery 0时应视为应急模式除导出数据、DROP表等必要操作外不要对 InnoDB 表做正常业务写入。手册指出≥ 4时 InnoDB 对数据采取更保守策略实践中常将实例当作只读抢救使用。成功启动后应尽快mysqldump或等价逻辑备份并在新的空数据目录上初始化实例、导入备份禁止长期带着强制恢复参数跑生产。第四步更换数据目录并正常启动移除强制恢复停止容器。重命名旧数据目录作为归档新建空目录并将属主设为容器内mysql的 UID:GID。从 Compose 与conf.d中删除所有innodb_force_recovery相关配置。启动容器使 MySQL 在空目录上完成初始化。sudomv/moli/data/mysql_prod_data /moli/data/mysql_prod_data_bad_$(date%Y%m%d)sudomkdir-p/moli/data/mysql_prod_datasudochown-R999:999 /moli/data/mysql_prod_datadockercompose up-dmysql999:999请按id mysql实际输出调整。第五步导入 dumpdockerexec-imoli-mysql-prod mysql-uroot-p你的密码\/path/to/moli_client_prod_时间戳.sql大文件导入耗时较长属正常现象。导入后执行SHOW TABLES、关键表COUNT(*)应用连接数据库端口做冒烟测试Compose 与配置方面的长期建议项建议privileged: true对 InnoDB 恢复无必要稳定后建议关闭以降低风险面。MYSQL_USER默认为root易与官方镜像初始化语义冲突更稳妥为仅设置MYSQL_ROOT_PASSWORD业务用户使用独立账号创建。expire_logs_daysMySQL 8.0 已弃用可改为binlog_expire_logs_seconds。镜像版本数据健康后可在充分验证的前提下将8.0.15等旧补丁升级到较新8.0.x。复盘与预防项说明抢救数据完整性使用innodb_force_recovery6导出的数据不保证 100% 一致需业务侧抽查若存在更早全量备份 binlog可对比或做时间点恢复补数据。持久化参数innodb_flush_log_at_trx_commit2与较大的sync_binlog在崩溃时可能丢失最近少量已提交事务需在性能与可靠性间权衡。innodb_flush_methodO_DIRECT部分网络存储或特殊挂载下可能出现兼容问题若遇疑难 I/O 现象可在测试环境对比fsync等行为。例行备份定期全备逻辑或物理 保留 binlog比依赖强制恢复可靠得多。小结推荐处理顺序为整目录备份 → 修正数据目录属主如需要→ 逐级尝试innodb_force_recovery→ 导出所需库 → 空目录初始化新实例并移除强制恢复 → 导入 SQL → 验证。原则对数据目录的删改与 redo 相关操作必须建立在完整备份之上强制恢复仅为临时过桥生产应以干净实例 逻辑恢复为最终形态。

更多文章