必须逐个实例单独升级,因各实例的mysqld二进制、配置文件、数据目录完全独立,混用会导致元数据损坏或启动失败;需通过ps aux | grep mysqld核对--defaults-file、--datadir、--socket、--pid-file路径,替换二进制后显式指向新路径并执行mysql_upgrade -s指定套接字,升级后验证版本、错误日志及系统表更新。

只能逐个实例单独升级,不能“只升一个”却指望其他实例自动适配——因为每个实例的 mysqld 二进制、配置文件、数据目录完全独立,混用会导致元数据损坏或启动失败。
确认目标实例的完整启动参数
升级前必须精确知道该实例实际加载了哪些路径,否则新版二进制一启动就报错。关键不是看端口或服务名,而是看进程真实参数:
- 执行
ps aux | grep mysqld,找到目标实例那行,重点核对--defaults-file(配置文件)、--datadir(数据目录)、--socket(套接字)、--pid-file(PID 文件)是否都指向预期路径 - 特别注意:如果多个实例共用同一份
/etc/my.cnf,而新版本已废弃其中某个参数(如query_cache_type),哪怕只升一个实例,它也会因读到该参数直接拒绝启动 - 验证配置有效性:
/opt/mysql-8.0.33/bin/mysqld --defaults-file=/etc/my3308.cnf --validate-config,返回 0 才算通过
替换二进制并重定向启动入口
不要动全局 /usr/bin/mysqld 或软链接,那是给单实例用的。多实例必须显式绑定新版二进制:
- 下载官方 tar 包(如
mysql-8.0.33-linux-glibc2.17-x86_64.tar.xz),解压到独立路径,例如/opt/mysql-8.0.33 - 修改该实例的启动方式:如果是 systemd,编辑对应 service 文件(如
mysqld@3308.service),把ExecStart=行中的mysqld替换为绝对路径/opt/mysql-8.0.33/bin/mysqld - 如果是自定义脚本启动,直接改脚本里调用的
mysqld路径;别依赖$PATH查找,避免误调旧版 - 检查
LD_LIBRARY_PATH是否包含新版所需的libstdc++.so.6,否则启动时报symbol lookup error
升级系统表必须连到目标实例本身
mysql_upgrade 不是本地命令,它会连接 MySQL 实例并修改其内部表结构。连错实例 = 升错库,后果严重:
- 先停掉目标实例:
mysqladmin -S /data/mysql3308/mysql.sock shutdown - 用新版二进制启动它:
/opt/mysql-8.0.33/bin/mysqld --defaults-file=/etc/my3308.cnf & - 再执行升级:
/opt/mysql-8.0.33/bin/mysql_upgrade -S /data/mysql3308/mysql.sock -u root -p --force(--force仅用于大版本,小版本禁用) - 切记不能省略
-S参数——默认会走 TCP 连localhost:3306,极易升级错实例 - 升级后检查
mysql.help_topic、mysql.user等表是否已更新:运行SELECT COUNT(*) FROM mysql.help_topic;,结果应明显大于升级前
验证时别只看“启动成功”
很多运维看到 systemctl start mysqld@3308 返回 0 就以为完事,但此时 information_schema 可能损坏、复制可能中断、甚至 performance_schema 根本没初始化:
- 登录该实例:
mysql -S /data/mysql3308/mysql.sock -e "SELECT VERSION(), @@hostname;",确认版本号和主机名匹配 - 查错误日志:
tail -n 50 /data/mysql3308/data/error.log,重点关注Failed to initialize、Table 'mysql.xxx' doesn't exist类报错 - 如有从库,运行
SHOW SLAVE STATUS\G,确认Seconds_Behind_Master是数字而非NULL,且IO_Running和SQL_Running均为Yes - 执行一条触发数据字典的操作,比如
CREATE USER 'test'@'localhost';,若报ERROR 1396 (HY000),说明mysql_upgrade没跑成功或跑错实例
最容易被忽略的是:升级后所有实例仍共用同一份 my.cnf 时,未清理废弃参数;或者 systemd 的 EnvironmentFile 里 MYSQLD_BIN 还指向旧路径,导致下次 reload 后启动失败。这些细节不检查,下次重启就出问题。











