编程 MySQL 8.0 升 8.4 LTS 复盘:停机不到 2 分钟,踩了认证插件、废弃参数、GPG 密钥三个坑

2026-09-12 21:01:27

MySQL 8.0 升 8.4 LTS 复盘:停机不到 2 分钟,踩了认证插件、废弃参数、GPG 密钥三个坑

MySQL 8.0 已 EOL,把生产库从 8.0 升到 8.4 LTS,整个过程约 1 小时,实际停机不到 2 分钟。中途踩了 3 个坑,每个都足以让服务起不来或者网站直接宕机,记录如下。

升级前检查

三件事必须在动刀前做完:

  1. 认证插件。查一遍所有用户的插件类型:
    SELECT user, host, plugin FROM mysql.user;
    
  2. 配置里的废弃参数。逐项对照 8.4 已移除的参数列表,尤其是 my.cnf 里历史遗留的项。
  3. sql_mode。确认升级前后行为差异不会影响现有 SQL。

另外可以用 8.4 的 mysqld 直接校验配置文件,提前发现非法参数:

mysqld --validate-config --defaults-file=/etc/my.cnf

三个坑

坑 1:mysql_native_password 被默认禁用

库里的用户此前全部使用 mysql_native_password。MySQL 8.4 默认禁用该插件,改用 caching_sha2_password。直接升级的后果是所有 PHP 数据库连接失败,网站宕机。

升级前先改完:

ALTER USER 'DBuser'@'localhost' IDENTIFIED WITH caching_sha2_password BY '用户密码';

一个附带问题:密码里含 ! 时 Bash 会做历史命令扩展,报 event not found。两种解法:set +H 关闭 history expansion,或者用 heredoc 输入 SQL。

坑 2:my.cnf 中已被移除的参数

配置里用了 expire_logs_days = 10,这个参数在 8.4 已移除,替代品是 binlog_expire_logs_seconds。旧参数留在配置里会导致 MySQL 直接启动失败。

sudo sed -i 's/^expire_logs_days\s*=\s*10/binlog_expire_logs_seconds = 864000/' /etc/mysql/mysql.conf.d/mysqld.cnf

坑 3:仓库 GPG 密钥过期

apt update 报 MySQL 仓库包签名密钥过期。即使下载了 RPM-GPG-KEY-mysql-2023 仍然无效,属于密钥轮换滞后。

临时跳过签名完成升级:

sudo apt-get update --allow-insecure-repositories -o Acquire::AllowInsecureRepositories=yes
sudo apt-get upgrade mysql-server mysql-client -y --allow-unauthenticated

下载来源仍是 repo.mysql.com 官方地址,升级后新仓库密钥会自动生效。

其他行为变更

  • AUTO_INCREMENT 用在 FLOAT/DOUBLE 列上,从弃用警告改为直接报错。
  • 外键要求父表被引用列必须有唯一索引(restrict_fk_on_non_standard_key 默认 ON)。
  • 移除 mysqlpumpFLUSH HOSTS(改用 TRUNCATE TABLE performance_schema.host_cache)、旧 Keyring 插件。
  • 变量 default_authentication_pluginauthentication_policy 取代。
  • SET_USER_ID 拆分为 SET_ANY_DEFINERALLOW_NONEXISTENT_DEFINER
  • 新增 tls-certificates-enforced-validation
  • 复制相关默认值变化:replica_parallel_workers 默认从 0 变为 4

回滚与备份

8.0 → 8.4 会升级系统表,无法直接降级,升级前务必做完整备份,这是唯一的回滚路径。

兼容性方面,WordPress 7.0.2 + PHP 8.4.22 与 MySQL 8.4 的测试已通过。

复制全文 生成海报 MySQL 数据库升级 运维

推荐文章

程序员茄子在线接单