作者:雷文霆,爱可生华东交付服务部 DBA 成员,主要负责 MySQL 故障处理及相关技术支持。爱好看书,电影。座右铭,每一个不曾起舞的日子,都是对生命的辜负。
爱可生开源社区出品,原创内容未经授权不得随意使用,转载请联系小编并注明来源。
本文约 2000 字,预计阅读需要 7 分钟。
1为什么要升级?
因为 MySQL 8.0.24 之前有很多 Bug,详见 MySQL 8.0 Release Notes[1],本文定稿时最近版本是 2023 年 7 月18 号发布的 8.0.34。
2升级前 DBA 和业务侧需要做什么?
如果是 MySQL 8.0.x 到 MySQL 8.0.z 的小版本升级,可以直接升级。参数名称的变化和弃用情况,可以在 MySQL 服务启动后,错误日志中看到,更新到配置文件中即可。
如果你没有做过升级或是需要从 MySQL 5.7 到 MySQL 8.0 大版本升级,需要根据官方升级文档[2] 进行检查。
至少要有的初步检查:
- 必须备份数据,只支持 GA。
mysqlcheck -u root -p --all-databases --check-upgrade
util.checkForServerUpgrade()
3升级思路
前提条件:升级到 MySQL 8.0 的检查项都已经检查完毕。
前提条件:升级到 MySQL 8.0 的检查项都已经检查完毕。
根据官方的升级文档,升级分为如下 2 个步骤:
- Step 1: Data dictionary upgrade.
- Step 2: Server upgrade.
在 MySQL 8.0.16 之前:升级用 mysql_upgrade;从 MySQL 8.0.16 开始:mysqld 可以自动升级。
- 依次升级 MGR 的 Secondary 节点
- 切换到新 Primary 节点
- 最后升级旧 Primary 节点
所以理论上如果有 MySQL Router(它在应用程序和 MGR 集群之间,起到代理作用,自动发现后端可写主库),那么不影响业务。但是,实践出真知,升级要通知业务侧,因为常会重启应用程序服务用于验证升级或是验证程序代码。所以申请一个变更窗口是最优解。
4具体的升级步骤是什么?
环境信息:MySQL 8.0.27 升级到 MySQL 8.0.33
从库升级时,建议设置 skip_slave_start=1
或 skip_replica_start=1
4.1 升级前的检查
环境信息:MySQL 8.0.27 升级到 MySQL 8.0.33
从库升级时,建议设置 skip_slave_start=1
或 skip_replica_start=1
# 以下三种方式均可
mysqlsh root@localhost:3306 -e "util.checkForServerUpgrade();"
MySQL JS > util.checkForServerUpgrade("admin@127.0.0.1:3306")
util.checkForServerUpgrade("admin@127.0.0.1:3306", {"targetVersion":"8.0.33","outputFormat":"JSON","configPath":"/data/mysql/3306/my.cnf.3306"})[指定版本检查]
# 辅助检查
mysqlcheck -uadmin -p -h127.0.0.1 --all-databases --check-upgrade
4.2 备份数据和配置文件
逻辑或是物理备份。
cp -rp /data/mysql/data/3306 /data/mysql/data/3306_bak「备份数据目录为可选」
cp my.cnf bak_8.0.xx_my.cnf
4.3 关闭服务和准备 basedir
查看表的状态是否正常(关库之前)
select * from information_schema.tables where TABLE_COMMENT like "%repair%";
安全关闭服务。
set global innodb_fast_shutdown = 0;
# 数据刷到磁盘,关闭快速关机;
shutdown;
# 关闭服务之后检查
ps -ef | grep mysql
如果是从库(无主从延迟)。
show slave status\G
stop slave;
备份数据文件(如果磁盘充足)。
cp -rp /data/mysql/data/3366 /data/mysql/data/3366_bak_1013
准备 basedir
,软连接或是直接替换。
show variables like "%basedir%"; 或 which mysql
# 备份原 base 目录
mv mysql_Basedir mysql_Basedir_bak
chown -R mysql:mysql mysql-8.0.33-linux-glibc2.12-x86_64
# ln -s /目录/新软件包 软连接的目录
ln -s mysql-8.0.xx新版本-linux-glibc2.12-x86_64 mysql_Basedir
chown -R mysql:mysql mysql_Basedir
# 示例
ln -s mysql-8.0.33-linux-glibc2.12-x86_64 base
lrwxrwxrwx 1 mysql mysql 35 Sep 7 16:14 base -> mysql-8.0.33-linux-glibc2.12-x86_64
# 环境变量可选
export PATH=$PATH:/usr/local/mysql/bin
# 或是 mv 替换,修改旧软件目录名称
mv mysql mysql_8.0.xx
mv mysql-8.0.xx-linux-glibc2.12-x86_64 mysql
4.4 启动数据库
启动就是升级,数据字典升级和 server 升级。
记录 MySQL 服务的原启动方式。
查看和检查。
var cluster = dba.getCluster()
cluster.status()
SELECT * FROM performance_schema.replication_group_members;
启动。
# 两种启动方式
systemctl start
mysqld_safe --defaults-file=/*.cnf --user=mysql &
4.5 最后升级旧 Primary 节点之前, 先切主
同版本时,切主命令(我们这次不能使用,因为不同版本不能切换)
# shell 使用8.0
# 不支持5.7.31
cluster.setPrimaryInstance('clusteruser@10.186.65.181:6681')
# 简版
cluster.setPrimaryInstance('mgr01:3306')
# 手动指定主库 >8.0.13 推荐
SELECT group_replication_set_as_primary('select @@server_uuid');
不能切主,怎么办?停止旧主组复制,使其自动切换。
# 低版本不能 SELECT 切换到高版本,通过退出组复制,自动切换。
stop group_replication;
# 启动前配置文件添加防止应用更新
read_only=1;super_read_only=1;
4.7 升级组的通信协议 >MySQL 8.0.16
group_replication_get_communication_protocol
函数返回组支持的最低 MySQL 版本(也就是说这个版本以下的 MySQL 版本无法加入集群)。
SELECT group_replication_get_communication_protocol();
SELECT group_replication_set_communication_protocol("8.0.33");
-- 提示虽然我们 set 成功了,但是依然显示如下低版本号,因为它查到是最低支持的版本。官方建议升级之后升级对应通信协议,所以我们别忘记要set一下哈。
SELECT group_replication_get_communication_protocol();
+------------------------------------------------+
| group_replication_get_communication_protocol() |
+------------------------------------------------+
| 8.0.27 |
+------------------------------------------------+
4.8 验证
已升级成功,大吉大利。
select version();
+-----------+
| version() |
+-----------+
| 8.0.33 |
+-----------+
从库,需要启动复制。
stop group_replication;
5关于回退
如果启动失败,重新以原来的软件版本启动。
- 清理 redo log 文件
rm -f ib_logfile{0,1,2,3}
- 清理 link,启动旧版本
如果启动失败,重新以原来的软件版本启动。
rm -f ib_logfile{0,1,2,3}
参考步骤:
unlink mysql
mv mysql_Basedir mysql_Basedir_bak
ln -s mysql-8.0.xx旧版本-linux-glibc2.12-x86_64 mysql_Basedir
# 启动服务
6关于节点切换
变相自定义切换 (虽说节点切换是自动的)。
- 节点权重
group_replication_member_weight
值越大越优先
server_uuid
越小越容易被选为主
7关于升级中遇到的问题
变相自定义切换 (虽说节点切换是自动的)。
group_replication_member_weight
值越大越优先
server_uuid
越小越容易被选为主
启动数据库时,查看 error 日志,替换或是去除 Warning。
2023-09-04T08:54:54.092942-00:00 0 [Warning] [MY-011068] [Server] The syntax '--admin-ssl=off' is deprecated and will be removed in a future release. Please use --admin-tls-version='' instead.
2023-09-04T08:54:54.092975-00:00 0 [Warning] [MY-011068] [Server] The syntax 'skip_slave_start' is deprecated and will be removed in a future release. Please use skip_replica_start instead.
正确的升级提示信息。
2023-09-04T08:55:10.136353-00:00 7 [System] [MY-013381] [Server] Server upgrade from '80027' to '80033' started.
2023-09-04T08:55:12.621536-00:00 7 [System] [MY-013381] [Server] Server upgrade from '80027' to '80033' completed.
低版本不能切换到高版本。
023-09-07T07:41:09.211541-00:00 59 [ERROR] [MY-013223] [Repl] The function 'group_replication_set_as_primary' failed. Error processing configuration start message: The appointed primary member has a version that is greater than the one of some of the members in the group.
2023-09-07T07:50:34.708283-00:00 0 [ERROR] [MY-013212] [Repl] Plugin group_replication reported: 'Error while executing a group configuration operation: Error processing configuration start message: The appointed primary member has a version that is greater than the one of some of the members in the group.'
# 低版本离开集群之后无法重新加回来stop group_replication;start group_replication; 好在集群会自动切换。
2023-09-07T07:51:47.747695-00:00 0 [ERROR] [MY-011521] [Repl] Plugin group_replication reported: 'Member version is incompatible with the group.'
原因:当新成员加入复制组时,它会检查组的现有成员宣布的通信协议版本。如果加入成员支持该版本,则它将加入组并使用组已宣布的通信协议,即使该成员支持其他通信功能也是如此。如果加入成员不支持通信协议版本,则会将其从组中逐出。
一个 MySQL 服务器 5.7.24 实例无法成功加入使用通信协议版本 8.0.16 的组。(高版本可以加入低版本)
一种不推荐的方式:如果需要更改组的通信协议版本,以便早期版本中的成员可以加入,请使用该
group_replication_set_communication_protocol("5.7.25")
函数指定要允许的最旧成员的 MySQL Server 版本。
8总结
- 此方法属于 in-place upgrade,核心步骤是用新软件包替换旧软件包(basedir),适合小版本升级。
- 其他的升级方式还有逻辑备份(MysqlDump 和 MyDumper)之后导入新版本。
- 如果是大版本升级数据量又大,可以建立 Master 低版本到 Slave 高版本的复制,最后主从切换实现升级。
充分测试之后,请选择自己擅长的方式吧!
参考资料
[1]
MySQL 8.0 Release Notes: https://dev.mysql.com/doc/relnotes/mysql/8.0/en/
[2]
upgrade-prerequisites: https://dev.mysql.com/doc/refman/8.0/en/upgrade-prerequisites.html
本文关键字:#MySQL# #MGR# #升级#
阅读推荐
技术分享 | 基于 MySQL 多通道主主复制的机房容灾方案
故障分析 | MySQL 迁移完不能快速导数据了
技术译文 | 一封写给 MySQL 8.2 贡献者的感谢信
技术译文 | MySQL 8.2 支持读写分离!
技术译文 | MySQL 8.1.0 推出 InnoDB Cluster 只读副本
行业观察 | 2023 年 DBA 有哪些新的挑战?
关于 SQLE
SQLE 是一款全方位的 SQL 质量管理平台,覆盖开发至生产环境的 SQL 审核和管理。支持主流的开源、商业、国产数据库,为开发和运维提供流程自动化能力,提升上线效率,提高数据质量。
SQLE 获取
🔗 Github https://github.com/actiontech/sqle
📚 文档 https://actiontech.github.io/sqle-docs/
💻 官网 https://opensource.actionsky.com/sqle/
👥 微信群 添加管理员微信 ActionOpenSource