问: 是否可以直接从 MySQL 5.7 升级到 8.4(或跳过主要版本) ?
答: 不支持跨主版本升级(例如,直接从 MySQL 5.7 升级到 8.4)。 必须从 5.7 升级到 8.0,然后从 8.0 升级到 8.4。 如果将来发布了新的 MySQL 主版本,则不支持跳过主要版本的直接升级。 必须按顺序执行每个主版本升级。
问: 这是否会导致服务器的停机,如果是这样,多久?
答: 若要最大程度地减少升级期间的停机时间,请按照建议的主要版本升级过程中跨主要版本的步骤操作。 服务器在升级过程中不可用,因此请在计划内维护时段执行此操作。 估计的停机时间取决于数据库大小、预配的存储大小(已预配的 IOP)和数据库上的表数。 升级时间与服务器上的表数成正比。 若要估算服务器环境的停机时间,请先对服务器的还原副本执行升级。
问: 我使用的是 HA 服务器。是否可以预期主版本升级的几乎零停机体验,类似于常规维护?
答: 否。 主要版本升级与日常维护有很大不同。 HA 主服务器与备用服务器之间跨主版本的复制不稳定,因此 Azure Database for MySQL 无法在此类升级期间提供近乎零停机的体验。
问: 升级后我的备份会发生什么情况?
答: 当您恢复在主版本升级之前创建的备份(自动或按需创建的)时,系统会将其恢复到运行先前版本的服务器。 当您还原在主版本升级后创建的备份(自动或按需创建)时,将还原到已升级版本的服务器。 在执行主要版本升级之前,先进行一次按需备份,以便在需要时轻松回滚。
已知问题和限制
Microsoft Entra ID 身份验证在副本上被阻止
如果将主服务器及其副本配置为Microsoft Entra身份验证,并且对副本执行主版本升级(从 5.7 升级到 8.0 或从 8.0 到 8.4),则对主服务器上的Microsoft Entra身份验证配置进行后续更改可能会导致升级的副本出现问题。 具体而言,副本的身份验证方法从“MySQL 和Microsoft Entra身份验证”重置为“仅 MySQL 身份验证”,从而阻止副本上的Entra ID身份验证。
解决方案
为了避免此问题,请不要在主服务器和副本服务器在不同的 MySQL 版本上运行时修改Microsoft Entra身份验证配置。 只有在复制层次结构中的每个服务器都升级到同一版本后,才更改Entra ID身份验证设置。
如果已遇到此问题,请使用以下步骤进行恢复:
- 将主服务器升级到版本 8.0(或 8.4),并配置所需的Microsoft Entra管理员用户。
- 在版本 8.0(或 8.4)上创建新副本。
- 停用复制已中断的旧副本。
- 将工作负载切换到使用新副本。
与 5.7 相比,8.0 中的 CPU 使用率缓慢或较高
视工作负载而定,与 5.7 相比,你可能会发现 8.0 版本运行变慢或 CPU 使用率较高。 升级只读副本或还原并升级到 Azure Database for MySQL 灵活服务器 8.0。 在升级主副本之前,使用副本测试和优化生产负载和查询。
如果发现更新、插入或删除等查询速度缓慢,请在服务器的门户页面侧窗格中的“设置计算 + 存储”>下在服务器上启用加速日志可能会有所帮助。
从 5.7 升级到 8.0(以及 8.4)后,插入带分数秒和时区偏移量的时间戳字面量时会出现静默数据不一致问题
在 MySQL 8.0 中,同时包含小数秒和时区偏移量的时间戳字面量(例如 '2025-01-01 12:00:00.123+00:00')在 INSERT 或 UPDATE 操作期间,可能会在未发出提示的情况下被静默转换为错误的值。 错误的值在没有任何报错或警告提示的情况下被存储,这可能导致难以在事后发现的数据不一致。 如果应用程序以此格式插入日期时间值,则从 MySQL 5.7 升级到 8.0(和 8.4)的客户可能会遇到此问题。
此问题是已知的 MySQL 社区 bug。 有关详细信息,请参阅 MySQL Bug #118011。
解决方案
在上游修补程序可用之前和之后,在升级前后采取以下预防措施:
- 审核将小数秒与时区偏移量组合在一起的时间戳文本的应用程序代码,并在插入前将其规范化为 UTC(或单个时区),而无需内联偏移量。
- 显式设置会话或服务器
time_zone,并写入不带内联偏移量的日期时间值,以便服务器始终一致地应用已配置的时区。 - 在升级后验证新插入行的代表性示例,以确认存储的值是否与预期值匹配。
升级到 8.4 后对索引字符串列的 IN() 查询的性能回归
在 MySQL 8.4 中,对于对带索引的非二进制字符串列使用 IN() 谓词的查询(例如,VARCHAR 使用 utf8mb4 或 utf8mb3 这类非二进制排序规则,如 utf8mb4_0900_ai_ci),如果 IN() 列表中的至少一个值长度超过该列的定义长度,或者超过前缀索引的定义长度,则该查询可能会退化为全表扫描或全索引扫描。 以前对 MySQL 5.7 或 8.0 中的相同数据使用高效索引范围扫描的查询在升级到 8.4 后可能会遇到性能下降的情况。
此问题是已知的 MySQL 社区 bug。 有关详细信息,请参阅 MySQL Bug #118009。
解决方案
在 Azure Database for MySQL 灵活服务器上提供修补程序之前,请使用以下一个或多个缓解措施:
- 审核对索引字符串列使用的
IN()应用程序查询,并在应用程序端筛选或截断值,使值均不超过列定义的长度(或前缀索引长度)。 - 对于受影响的查询,请将
IN()列表拆分为多个较短IN()的列表或OR排除过大值的条件,以便优化器可以继续使用索引范围扫描。 - 对受影响的列使用二进制排序规则(例如
utf8mb4_bin),或latin1字符集,因为这些排序规则不受此回归的影响。 在采用更改之前,根据应用程序的排序和比较要求评估更改。 - 升级后,使用
EXPLAIN查看查询计划,以识别已从range访问切换为ALL或index访问的查询,并优先对其进行缓解。
升级到 8.0 或 8.4 后,带有大型 IN() 列表的 SELECT 查询执行缓慢或 CPU 使用率高
升级到 MySQL 8.0 或 8.4 后, SELECT 使用 IN() 具有大量值的谓词的查询(例如,单个 IN() 列表中的几千个或更多值)可能与 MySQL 5.7 上的同一工作负荷相比,查询延迟和 CPU 使用率明显较高。 优化器处理大型 IN() 列表的成本更高,在 8.0 和 8.4 中,成本随列表中的值数而增加。
解决方案
- 减少列表中
IN()传递的值数。 在可能的情况下,重构应用程序以为每个查询发送一组更小、更具选择性的值。 - 对于需要根据大量值进行筛选的工作负载,请将这些值加载到临时表或暂存表中,并针对该表使用
JOIN,而不是使用单个很大的IN()列表。 - 将查询批处理到包含较短
IN()列表的多个较小查询中,并将结果合并到应用程序层中。 - 在将更改应用到主服务器之前,应先在只读副本或服务器的还原副本上测试重构后的查询。