直接查容器日志是定位MySQL升级失败的首要步骤,重点搜索[ERROR]、unknown variable等关键词;需检查my.cnf废弃参数、init.sql不兼容语法、数据卷版本兼容性及日志配置变更。

直接看容器日志,别猜
MySQL容器升级后启动失败,第一反应不是重试或删镜像,而是立刻查日志。Docker不会主动告诉你哪条SQL错了、哪个参数废弃了,但日志里全有。运行 docker logs <container_name>,重点搜 [ERROR] 和 mysqld: unknown variable 这类关键词。如果输出太长,加 grep -i "error\|unknown\|fail" 过滤。典型线索包括:unknown variable 'innodb_log_files_in_group'(该参数在 MySQL 8.0.30+ 已移除)、Collation 'utf8mb4_0900_ai_ci' is not supported(旧版本客户端不兼容新默认排序规则)。
检查 my.cnf 是否含已废弃参数
升级后最常踩的坑是配置文件里留着老版本才认的参数。比如 MySQL 8.4+ 彻底移除了 query_cache_type、expire_logs_days,而 default_authentication_plugin 在 8.0.27 后已不推荐设为 caching_sha2_password(默认就是)。用 mysqld --defaults-file=/path/to/my.cnf --validate-config 验证语法——注意:这个命令必须在对应版本的 MySQL 二进制下执行,否则校验无效。常见陷阱:lower_case_table_names=2 在 macOS 容器中不被支持;skip-host-cache 在 8.0.33+ 被静默忽略但不报错,可能掩盖真实问题。
init.sql 脚本里有没有用到被删的语法?
升级后 init 脚本失败往往不是 SQL 写错了,而是用了已被删除的功能。例如:CREATE USER ... IDENTIFIED BY PASSWORD 'xxx' 在 8.0.25+ 报错(改用 IDENTIFIED WITH caching_sha2_password AS 'hash');GRANT ALL PRIVILEGES ON *.* 在 strict mode 下若没指定 WITH GRANT OPTION 会失败;还有 SET GLOBAL sql_mode='' 在 8.0.31+ 不再允许空值。用 mysql -u root -p -e"your problematic statement" 在本地同版本 MySQL 上单行验证,比反复启停容器快得多。特别注意:脚本里如果有 source /xxx.sql,它不会报错但也不会执行——MySQL 容器里的 mysql 客户端默认禁用 source 命令。
确认数据卷是否兼容新版本
挂载了旧版 /var/lib/mysql 数据卷的容器,升级镜像后大概率启动失败。InnoDB 表空间格式、系统表结构、甚至 ibdata1 文件头都可能不兼容。错误日志里出现 InnoDB: Unsupported redo log format 或 Table 'mysql.user' doesn't exist 就是典型信号。此时不能强行跳过校验——innodb_force_recovery=1 可能让你连上,但写入会损坏数据。稳妥做法是:先用旧镜像备份 mysqldump --all-databases,再用新镜像初始化空数据目录,最后导入。别信“升级文档说自动迁移”,实际中 schema 升级脚本(mysql_upgrade)在容器启动流程里默认不触发,除非你手动加 command: ["mysqld", "--upgrade"]。
log_error_verbosity=3 在 8.0.30+ 改名成 log_error_services,旧值被忽略,导致后续错误日志变短,反而更难定位问题。


















