AWS MySQL社区版大版本升级方案&流程【5.7升级至8.0】
背景介绍
因为MySQL官方5.7版本停止维护,AWS要求MySQL社区版实例最晚于2024年2月29日前完成MySQL版本升级,否则会强制升级,对业务的影响较大。排查到手游有两个实例包含在其中,且实例将于1月16日就强制升级,需要紧急推进处理升级事宜。
AWS各云实例deadline:
方案共创【运维统筹推进】
当前调研三七内部还没有进行数据库5.7升级8.0的先例,外部方案层出不穷,业务影响点又千奇百怪,完全不能形成有效的参考方案,所以决定从0开始,根据实际业务状况,因地制宜。
基于上述背景,我们采用的是共创形式沟通,充分考虑各端的建议,达成统一方案,避免中途折返,功亏一篑。
前期方案探寻
在探寻方案之前,还需要明确一个信息:具体升级到哪个版本?
依据1:首推次新版本。从官网的信息来看,MySQL 8.0 引擎版本升级几乎是每三个月一次迭代。当前最新版本为 8.0.35,发布日期为 2023 年 11 月 9 日,由此推断:下一个最新版本为 8.0.36,发布日期为 2024 年 2 月左右,8.0.35 就是次新版本了。
依据2:避免频繁升级。无论从开发、业务角度,还是运维自身角度来看,尽量避免底层变更是核心参考指标,这将大大降低人力成本和业务风险。从下表可以看出,8.0.35 的终止日期要比 8.0.34 延后 6 个月左右的时间。
基于上述两点,基本已经敲定目标版本为:8.0.35
有了目标版本,就可以输出升级草案:
初步方案敲定
经过会议讨论,大体方案方案逐步清晰,最终确定采用方案1进行,但是需要有一个其他云的兜底链路,以规避极端情况:AWS侧升级失败且短时间完全不可用
方案细化及实施
整体方案概览
如何升级
这个主要是基于全球平台和港澳台两套环境一套代码的现状进行考量的。如果只升级全球平台的数据库,同一套代码是否还能在两套环境兼容?
结论:以最小化改造为前提,当前只升级全球平台实例,但是涉及字符集等配置修改需要全球平台和港澳台一起处理,保证应用层是兼容的。
升级前置检查
实例版本升级兼容性检查
目前 MySQL 官方提供的 MySQL Shell 中有专门用作 MySQL 升级兼容性检查的函数 util.checkForServerUpgrade(),我们可以使用该检查函数在升级之前对相应实例进行初步检查,如果检查中出现升级不兼容项目,输出的日志中会有详细的信息记录,并且会在日志末尾对不兼容项目的数量按照 Error、Warnings 以及 Notices 进行分组统计其数量。对 Amazon RDS 进行实例升级时,升级检查结果记录在 Amazon RDS 的日志记录中,日志文件名为 PrePatchCompatibility.log,当出现直接导致升级失败的错误类型时,也会同时在实例对应 Event 中出现相应的日志记录。
Amazon RDS Event:
Amazon RDS Log:
兼容性检查函数 util.checkForServerUpgrade()会根据目标版本和源版本之间的更改定义兼容性检查项。下面是使用方法以及几种常见的工具使用错误场景。
1) MySQL Shell 升级检查函数 util.checkForServerUpgrade()具体的使用方法如下:
2)使用 MySQL Shell 工具进行前置检查的时候,需选择正确的工具版本。MySQL Shell 8.0.21 及更高版本可用于 RDS 检测,如果版本低于 8.0.21,会出现以下报错:
3)需要注意选择正确版本且保证待检测实例版本与工具版本相匹配。MySQL Shell 默认可检测 8.0.11 至工具版本一致的 MySQL Server 版本。如果选择了与工具版本不相符的实例进行检测,如工具版本为 8.0.21,用来检测 RDS MySQL 5.7.38 版本实例升级至 RDS MySQL 8.0.32 版本会出现以下报错:
如果选择了 RDS MySQL 实例目标版本小于待检测实例的版本,具体报错如下:
该工具检测项目与 RDS 检查项目存在一定的交集,在使用过程中只需关注出错项,部分不适用于 RDS 项不需过多关注,可以使用该工具做一个升级前的不兼容项预检查,以便提前修改不兼容项目。具体的以快照恢复并升级后的测试实例或者实际升级生产实例的输出 PrePatchCompatibility.log 为准。
另外,需要注意的是 Amazon RDS MySQL 的 PrePatchCompatibility.log 中检测结果只有 Errors 或者 Warnings 总数的展示,并没有明确标识出哪一项是直接影响升级结果的 Error,哪一项是需要关注但是不直接影响升级结果的 Warning。
实例版本升级兼容性检查结果分析&解决
1)检查项问题总览:
###说明:
● ERROR:必须整改,否则升级失败
● WARNING:可能需要整改,否则升级后有功能异常或不符合预期
● NOTICE:升级程序会帮您自动处理好,仅仅通知您升级程序会干这操作
2)问题项分析
3)讨论方案&实施
原争议问题分析记录:
字符集问题:
方案1:旧版本mysql5.7直接修改表级别默认字符集为utf8mb4
改动较大,上下游是否兼容?【兼容不影响】
港澳台是否一起修改?【一起修改】
方案2:旧版本不调整,新版本mysql8.0升级时修改默认字符集为utf8mb3
不符合版本趋势,后续utf8mb3可能不存在,只有utf8mb4一种字符集,如何应对?
日期、时间和时间戳零值问题:【暂时不调整,当前sql_mode中不包含禁止零值设置】
方案1:将零值替换为有效值
改动较大,业务当前需要零值,如何调整?
港澳台是否一起修改?
方案2:暂时不调整,保证sql_mode中不含有NO_ZERO_IN_DATE 和 NO_ZERO_DATE
短期内无影响,后续NO_ZERO_IN_DATE会并入严格模式,查询空值报错,如何应对?
业务SQL检查
1)01实例业务SQL验证
整体流程:通过AWS生产实例的快照在测试账户拉起一个新实例,然后把生产实例的日志重放至新实例,pt-upgrate工具显示具体差异。【后续会单独整理一篇pt-update使用详解】
###补充说明
关于pt-upgrade检测原理说明:给定一个SQL,分别在两个不同版本的实例上执行,判断是否一致。具体指标示例如下:
Row count:查询返回的行数是否一致;
Row data:查询的结果是否一致;
Warnings:是否提示warning;
Query time:查询时间是否在同一个量级;
Query errors:查询在一个实例中出现语法错误;【核心观察指标】
SQL errors:查询在两个示例中出现语法错误;【核心观察指标】
关于pt-upgrade工具的使用,一般有两种方式:
直接比较一个文件中的 SQL 在两个实例中的执行效果:pt-upgrade h=host1 h=host2 --type genlog general.log【先生成一个基准测试结果,然后再基于这个结果测试其他环节的兼容性】
需要基于一个结果进行多次测试:pt-upgrade h=host1 --type genlog general.log --save-results /data/mysql/test/ --no-read-only【只针对单个实例测试】
为了节省篇幅,这里省略掉了“如何处理大批量的error”,直接输出结果。【后续有机会再写一篇针对此类问题的WIKI】
从整体的分析来看,并无明显的不兼容情况,存在一个可能不兼容的问题:
第4点:阿里云datawork连接mysql的驱动版本较低,升级后可能存在连接失败的情况,正在验证测试————已验证无影响,可以正常连接
2)01实例业务SQL验证
01实例因为是存储加密,无法跨账户分享快照,而当时在生产账户有一台低配的8.0.35测试数据库,用于开发验证测试活动任务,且实例的总体数据量不大【不到1G数据】。故直接在生产账户使用中控机测试。
日常活动任务调度测试
8.0.35版本的低配测试实例已经交付,运维侧主要完成表结构导入,测试账户构建两个事项,剩余事项开发自行测试。
AWS控制台升级方案测试
1)方案敲定
因为业务要求升级方案尽量减少影响时长,而蓝绿部署是AWS官方首推的,能够尽最大努力减少业务影响。
2)蓝绿部署测试细节&流程
###01. 监控数据库读写性能:持续读写数据库
通过每隔 1 秒循环读/写请求数据库,判断数据库是否工作正常:
###002 创建蓝绿部署实例:测试花费时间26~27min,期间读写不影响
创建蓝绿部署-全新【根据升级的版本创建一个绿色实例】
【蓝色实例】开始创建快照&备份实例:2024.1.2 23:21
【蓝色实例】完成创建快照&备份实例:2024.1.2 23:25
【绿色实例】记录binlog恢复的点位&重启实例:2024.1.2 23:27 mysql-bin-changelog.107503456
【绿色实例】重置用户:2024.1.2 23:28 有4个用户与主用户名匹配;仅重置未绑定到特定主机的
【绿色实例】从快照恢复&停止&重启:2024.1.2 23:29
【绿色实例】完成快照恢复:2024.1.2 23:30
【绿色实例】停止数据库:2024.1.2 23:34
【绿色实例】数据库正在使用双写缓冲区&重启数据库&重置用户:2024.1.2 23:37RDS优化写入与存储配置不兼容
【绿色实例】数据库实例修补完成:2024.1.2 23:38
【绿色实例】启用自动备份&完成蓝绿部署:2024.1.2 23:42
【绿色实例】停止数据库&数据库正在使用双写缓冲区&重启数据库:2024.1.2 23:42
【绿色实例】开始创建快照&备份实例:2024.1.2 23:43
【绿色实例】完成创建快照&备份实例:2024.1.2 23:47
###003 蓝绿部署切换:控制台测试花费时间2~3min【实际写入影响小于30s】
切换操作,从控制台上事件维度显示:
切换
点击开始切换:2024.1.3 00:18
【蓝色实例&绿色实例】实际开始切换:2024.1.3 00:19
记录切换后绿色实例的点位:2024.1.3 00:19 file mysql-bin-changelog.000010 and position 850
切换完成&新实例重命名:2024.1.3 00:19 将mysql57-to-80-test-green-rjxajf重命名为mysql57-to-80-test
旧实例重命名:2024.1.3 00:20 将mysql57to-80-test重命名为mysql57 to-80-test-old1
整个切换完成:2024.1.3 00:20
切换操作,从脚本测试显示:
实际升级过程&结果验证
1)升级过程
考虑到我们的业务特征,全球平台运营中台等业务低峰在15:00左右,所以整体升级方案也是围绕该时间点进行安排的。
2)结果验证
从总的升级过程和影响来看,基本符合测试结果,有个别项因为完全不影响业务,后续以可选项形式进行调整
创建蓝绿部署实例:实际花费2h【多可用区调整和存储配置升级花费1.5h,剔除这两个因素,基本符合预期】
蓝绿部署切换:控制台完成切换实际花费2min【完全符合预期】
蓝绿部署切换影响:读写影响小于30s【完全符合预期】