技术分享 | MySQL MGR 滚动升级可行么?

2023年 12月 1日 44.2k 0

作者:雷文霆,爱可生华东交付服务部 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 的检查项都已经检查完毕。

根据官方的升级文档,升级分为如下 2 个步骤:

  • Step 1: Data dictionary upgrade.
  • Step 2: Server upgrade.

在 MySQL 8.0.16 之前:升级用 mysql_upgrade;从 MySQL 8.0.16 开始:mysqld 可以自动升级。

  1. 依次升级 MGR 的 Secondary 节点
  2. 切换到新 Primary 节点
  3. 最后升级旧 Primary 节点

所以理论上如果有 MySQL Router(它在应用程序和 MGR 集群之间,起到代理作用,自动发现后端可写主库),那么不影响业务。但是,实践出真知,升级要通知业务侧,因为常会重启应用程序服务用于验证升级或是验证程序代码。所以申请一个变更窗口是最优解。

4具体的升级步骤是什么?

环境信息:MySQL 8.0.27 升级到 MySQL 8.0.33

从库升级时,建议设置 skip_slave_start=1
skip_replica_start=1

4.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,启动旧版本

参考步骤:

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关于升级中遇到的问题

启动数据库时,查看 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

相关文章

Oracle如何使用授予和撤销权限的语法和示例
Awesome Project: 探索 MatrixOrigin 云原生分布式数据库
下载丨66页PDF,云和恩墨技术通讯(2024年7月刊)
社区版oceanbase安装
Oracle 导出CSV工具-sqluldr2
ETL数据集成丨快速将MySQL数据迁移至Doris数据库

发布评论