mysql如何升级到新版本_mysql步骤详细解析

3次阅读

停服务前必须做三件事:备份(逻辑+权限+物理)、检查(兼容性扫描)、清理(断连+安全关库);升级需替换二进制、配置default_authentication_plugin和字符集、用mysqld_safe启动触发自动升级;升级后必验版本、认证插件、引擎、group by行为及错误日志。

mysql如何升级到新版本_mysql步骤详细解析

停服务前必须做三件事:备份、检查、清理

直接升级 MySQL 5.7 → 8.0 不是“替换二进制再启动”就完事了——90% 的失败都卡在升级前没做对这三步。

  • 备份要分层:用 mysqldump -u root -p --all-databases --routines --triggers --events 备业务库;用 mysql -e "select CONCAT('SHOW GRANTS for ''',user,'''@''',host,''';') FROM mysql.user" | mysql | sed 's/$/;/g' 单独导出权限;再用 cp -rp /var/lib/mysql /var/lib/mysql.bak.57 做物理快照(别只信逻辑备份)
  • 检查不能跳过:MySQL 8.0 不支持 MyISAM 系统表、NO_AUTO_CREATE_USER 模式、查询缓存等。先在 5.7 上跑 mysqlcheck --check-upgrade,再用 mysqlsh -uroot -p -S /tmp/mysql.sock -e "util.checkForServerUpgrade()" 做兼容性扫描——它会明确告诉你哪张表引擎不合法、哪个用户密码策略过期、哪些 SQL 模式已废弃
  • 清理连接和状态:执行 show processlist; 确认无活跃连接;设 SET GLOBAL innodb_fast_shutdown = 0; 避免脏页残留;再 shutdown; 关库——别用 kill -9,否则 8.0 启动时可能报 InnoDB: Database page corruption

in-place 升级实操:替换、启动、自动升级系统表

centos/ubuntu 下 in-place 升级本质是「换 bin 目录 + 换配置 + 启动触发自升级」,不是重装。

  • 停库后,把新版本 mysql-8.0.31-linux-glibc2.12-x86_64 解压到新路径(如 /opt/mysql8),用软链指向它:ln -sf /opt/mysql8 /usr/local/mysql
  • 复用原 my.cnf,但必须显式加两行:default_authentication_plugin=mysql_native_password(避免应用连不上)、character-set-server=utf8mb4(防止 utf8mb4 表被降级成 latin1)
  • 启动命令要用 mysqld_safe --defaults-file=/etc/my.cnf --user=mysql & ——注意不是 systemctl start mysqld,否则 systemd 可能调用旧 service 文件;首次启动时,8.0.16+ 会自动执行系统表升级(mysql_upgrade 已弃用),日志里出现 Upgrading system tables. 即表示成功

升级后必验的五个致命点

服务起来≠升级完成。MySQL 8.0 默认行为变化极多,不验证等于埋雷。

  • SELECT @@version, @@sql_mode; 看是否真为 8.0.x,且 sql_mode 里没有 NO_AUTO_CREATE_USER(否则建用户报错)
  • SELECT user, host, plugin FROM mysql.user; 检查 root 是否还是 mysql_native_password,不是的话用 ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'xxx'; 改回来
  • SHOW ENGINES; 确认 InnoDB 是默认引擎,且 MyISAM 状态为 NO(8.0 系统表全 InnoDB,老 MyISAM 表需手动 ALTER TABLE t ENGINE=InnoDB;
  • 用原应用连接测试,重点看带 GROUP BY 的语句是否报 Expression #1 of SELECT list is not in GROUP BY clause ——这是 8.0 严格模式默认启用,需调整 sql_mode 或重写 SQL
  • Error log 最后 200 行,确认无 Failed to upgrade serverTable upgrade failed 类错误;有则立即停库,回退到备份

为什么建议跳过 5.7.x → 8.0.y 直升,先打补丁?

不是所有 5.7 都能平滑升 8.0。官方只保证从「5.7 最新 GA 版」(如 5.7.40)开始升级路径受支持。

  • 若你还在用 5.7.23、5.7.30 这类老版本,先升级到 5.7.40(只需 rpm -Uvh 或 tar 替换),再升 8.0——可避开大量已知 bug,比如 5.7.32 之前存在 innodb_undo_log_truncate 兼容问题,升 8.0 时直接卡死
  • 8.0.16 是关键分水岭:此前必须手动跑 mysql_upgrade;此后由 mysqld 自动完成。但自动升级只处理系统库,你的业务库字符集、索引、json 字段仍需人工核对
  • 最易被忽略的是时区表:5.7 的 mysql.time_zone* 表结构与 8.0 不兼容,升级后若发现 CONVERT_TZ() 返回 NULL,就得手动运行 mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -u root -p mysql
text=ZqhQzanResources