MySQL 升级
5.7.33 升级到 8.0.23。
一、必知事项
1. 建议
- 升级前必须备份数据,且备份需包含 mysql 库
- 升级后需重新安装 MySQL 语言接口
2. 升级路径
- 从 5.6 升级到 5.7,建议先升级到 5.6 最新版本,再升级到 5.7
- 不支持跨系列跳版本升级(如 5.5 直接升级到 5.7)
- 支持同系列内升级或跳版本升级(如 5.7.x 到 5.7.y、5.7.x 到 5.7.z)
3. 了解目标版本变化
MySQL 8.0 与 5.7 差异较大,建议查阅官方文档了解详细变化。
二、升级前的准备
1. 检查事项
参考官方文档:https://dev.mysql.com/doc/refman/8.0/en/upgrade-prerequisites.html
2. 升级检查器(MySQL Shell)
MySQL Shell 可检查服务器实例的兼容性错误和升级问题,最低支持检查 5.7 GA 版本,还可检查配置文件中目标版本已删除或默认值变化的系统变量。
(1)安装
-
下载:
wget https://dev.mysql.com/get/Downloads/MySQL-Shell/mysql-shell-8.0.23-linux-glibc2.12-x86-64bit.tar.gz -
解压:
tar -xvf mysql-shell-8.0.23-linux-glibc2.12-x86-64bit.tar.gz -C /opt/ -
创建软链接:
ln -s /opt/mysql-shell-8.0.23-linux-glibc2.12-x86-64bit /opt/mysqlsh -
添加环境变量:在
/etc/profile中添加MYSQLSH_HOME=/opt/mysqlsh export PATH=$PATH:$MYSQLSH_HOME/bin使配置生效:
source /etc/profile -
验证:
$ mysqlsh MySQL Shell 8.0.23 ... Type '\help' or '\?' for help; '\quit' to exit. MySQL JS
(2)语法
util.checkForServerUpgrade([connectionData][, options])
- 可选参数:
- ConnectionData:提供连接数据
- options:选项字典,部分选项如下
- password:密码
- targetVersion:目标版本(建议指定完整版本号)
- configPath:配置文件路径
- outputFormat:输出格式(TEXT 默认,JSON 便于解析)
(3)查看帮助与状态
-
帮助:
mysqlsh> util.help("checkForServerUpgrade") -
当前实例状态:
MySQL JS> \status MySQL Shell version 8.0.23 Not Connected.
(4)使用方法
支持登录 MySQL Shell 内部调用函数或直接命令行启动。
-
登录后调用:
MySQL JS> util.checkForServerUpgrade('172.16.0.30:3306', {"password":"root", "targetVersion":"8.0.23", "outputFormat":"JSON", "configPath":"/mdata/3306/my.cnf"}) { "serverAddress": "172.16.0.30:3306", "serverVersion": "5.7.32-log - MySQL Community Server (GPL)", "targetVersion": "8.0.23", "errorCount": 0, "warningCount": 24, "noticeCount": 1, "summary": "No fatal errors were found that would prevent an upgrade, but some potential issues were detected. Please ensure that the reported issues are not significant before upgrading." ... -
命令行启动:
-
TCP/IP 方式:
mysqlsh -- util checkForServerUpgrade root@'172.16.0.30':3306 --target-version=8.0.23 --output-format=JSON --config-path=/mdata/3306/my.cnf mysqlsh -- util check-for-server-upgrade { --user=root --host='172.16.0.30' --port=3306 } --target-version=8.0.23 --output-format=JSON --config-path=/mdata/3306/my.cnf -
socket 方式:
mysqlsh --socket=/mdata/3306/mysql.sock --user=root -e "util.checkForServerUpgrade()"
-
三、升级方式
1. 原地升级
(1)结束未提交的 XA 事务
-
检查未提交的 XA 事务:
-- 若有返回结果,需结束事务 XA recover; -
结束事务:
XA COMMIT xid [ONE PHASE] XA ROLLBACK xid
(2)轮换 InnoDB 主密钥(若存在加密表空间)
ALTER INSTANCE ROTATE INNODB MASTER KEY;
(3)设置缓慢关闭
建议 5.7 升级到 8.0 时使用。
-- innodb_fast_shutdown 取值 0(缓慢关闭)、1(快速关闭)、2(冷关闭)
-- 5.7 版本设置缓慢关闭
SET GLOBAL innodb_fast_shutdown = 0;
-- 8.0 版本可选择快速或缓慢关闭(此处为说明,升级前无需操作 8.0)
SET GLOBAL innodb_fast_shutdown = 1; -- 快速关闭
-- 或
SET GLOBAL innodb_fast_shutdown = 0; -- 缓慢关闭
(4)关闭 MySQL 服务器
mysqladmin -uroot -p -S /mdata/3306/mysql.sock shutdown
(5)升级软件版本
将新安装包解压到安装目录,创建软链接,修改环境变量。
(6)启动新 MySQL 服务器
# 使用原有数据目录
mysqld_safe --user=mysql --datadir=/mdata/3306/data &
Note:8.0 版本若有加密的 InnoDB 表空间,需用 --early-plugin-load 选项加载 keyring 插件;启动时会自动升级数据字典等信息,不会升级时区表内容。
(7)登录验证
mysql -uroot -p -S /mdata/3306/mysql.sock
Note:生产环境需对库表、数据及应用程序做全面验证。
2. 逻辑升级
类似数据迁移,使用备份工具导出再恢复。
(1)备份数据
mysqldump -u root -p -S /mdata/3306/mysql.sock --add-drop-table -R --events -A \
--ignore-table=mysql.innodb_index_stats \
--ignore-table=mysql.innodb_table_stats --force /tmp/full.sql
Note:若备份文件包含系统表,不建议在服务器上启用 GTID。
(2)关闭原 MySQL 服务器
mysqladmin -uroot -p -S /mdata/3306/mysql.sock shutdown
(3)部署新实例
(步骤略,需安装配置 MySQL 8.0.23)
(4)恢复数据到新实例
mysql -u root -p -S /tmp/mysql.sock --force < /tmp/full.sql
(5)执行剩余升级操作
# 8.0.16 版本之前
mysql_upgrade -uroot -p -S /tmp/mysql.sock
mysqladmin -u root -p -S /tmp/mysql.sock shutdown
mysqld_safe --user=mysql --datadir=/mdata/data &
# 8.0.16 版本之后(mysql_upgrade 已废弃)
mysqladmin -u root -p -S /tmp/mysql.sock shutdown
mysqld_safe --user=mysql --datadir=/mdata/data --upgrade=FORCE &
(6)删除多余表(MySQL 8.0 不再使用)
DROP TABLE mysql.event;
DROP TABLE mysql.proc;
(7)登录验证
生产环境需对库表、数据及应用程序做全面验证。
mysql -uroot -p -S /tmp/mysql.sock
四、错误汇总
1. 逻辑升级恢复时的权限与主键冲突错误
- 报错信息
$ mysql -u root -proot -S /tmp/mysql.sock --force < /tmp/full_gtid.sql
mysql: [Warning] Using a password on the command line interface can be insecure.
ERROR 3554 (HY000) at line 318: Access to system table 'mysql.innodb_index_stats' is rejected.
ERROR 3554 (HY000) at line 321: Access to system table 'mysql.innodb_index_stats' is rejected.
ERROR 3554 (HY000) at line 338: Access to system table 'mysql.innodb_index_stats' is rejected.
ERROR 1062 (23000) at line 340: Duplicate entry 'mysql-gtid_executed-PRIMARY-n_diff_pfx01' for key 'innodb_index_stats.PRIMARY'
ERROR 3554 (HY000) at line 348: Access to system table 'mysql.innodb_table_stats' is rejected.
ERROR 3554 (HY000) at line 351: Access to system table 'mysql.innodb_table_stats' is rejected.
ERROR 3554 (HY000) at line 366: Access to system table 'mysql.innodb_table_stats' is rejected.
ERROR 1062 (23000) at line 368: Duplicate entry 'mysql-gtid_executed' for key 'innodb_table_stats.PRIMARY'
- 报错原因
主要因 8.0 与 5.7 系统表差异导致(8.0 前系统表使用 MyISAM 引擎)。
- 解决方法
备份时使用 --ignore-table 选项跳过报错表:--ignore-table=mysql.innodb_index_stats --ignore-table=mysql.innodb_table_stats
-
扩展说明
-
innodb_index_stats:保存优化器的索引统计信息
-
innodb_table_stats:保存优化器的表统计信息
-
复制时,这两张表仅复制结构,不复制内容
-