# 第3章 MySQL升级

第3章 MySQL升级

目录

本章介绍升级MySQL安装的步骤。

升级是一个常见的过程,因为你可以在同一个MySQL版本系列中获取错误修复,或者在MySQL主要版本之间获取重要功能。你首先在一些测试系统上执行此过程,以确保一切顺利运行,然后再在生产系统上执行。

[!NOTE]

在以下讨论中,必须使用具有管理权限的MySQL账户运行的MySQL命令包括在命令行上使用 -u<br /> root 来指定MySQL root 用户。需要 root 密码的命令还包括 -p 选项。由于 -p 后面没有选项值,此类命令会提示输入密码。出现提示时输入密码,然后按Enter键。

可以使用mysql命令行客户端来执行SQL语句(以root身份连接,以确保拥有必要的权限)。

3.1 开始之前

升级前,请查看本节中的信息并执行所有建议的操作。

3.2 升级路径

  • 支持从MySQL 5.7升级到8.0。但是,仅支持在通用可用性(GA)版本之间进行升级。对于MySQL 8.0,要求您从MySQL 5.7 GA版本(5.7.9或更高版本)进行升级。不支持从MySQL 5.7的非GA版本进行升级。
  • 建议在升级到下一个版本之前,先升级到最新版本。例如,在升级到MySQL 8.0之前,先升级到最新的MySQL 5.7版本。
  • 不支持跨版本升级。例如,不支持直接从MySQL 5.6升级到8.0 。
  • 当一个发行系列达到通用可用性(GA)状态时,支持在该发行系列内进行升级(从一个GA版本升级到另一个GA版本)。例如,支持从MySQL 8.0.x 升级到8.0.y。(不支持涉及开发状态的非GA版本的升级。)也支持跳过某个版本。例如,支持从MySQL 8.0.x 升级到8.0.z。MySQL 8.0.11是MySQL 8.0发行系列中的第一个GA状态版本。

3.3 升级最佳实践

MySQL支持在小版本之间(在长期支持系列内)以及升级到下一个大版本(跨长期支持系列)进行升级。升级可提供最新的功能、性能和安全修复。

为做好准备并帮助确保成功升级到最新的 MySQL 版本,我们建议采用以下最佳做法:

确定升级的主版本或次版本

MySQL发布模式对LTS(长期支持)版本和创新版本进行了区分。LTS版本提供8年以上的支持,适用于生产环境。创新版本为用户提供最新的功能特性。了解更多关于MySQL发布模式的信息。

执行小版本升级很简单,而大版本升级则需要在升级前进行战略规划和额外测试。本指南对大版本升级特别有用。

确定升级类型

升级MySQL主要有三种方式,请阅读相关文档,以确定哪种升级类型最适合您的情况。

  • 就地升级:替换MySQL Server软件包。
  • 逻辑升级:将SQL从旧的MySQL实例导出到新实例。
  • 复制拓扑升级:考虑每台服务器的拓扑角色。

查看支持的平台

如果您当前的操作系统不受新版MySQL支持,那么请计划升级操作系统,否则不支持就地升级。

有关当前支持的平台列表,请参阅:https://www.mysql.com/support/supportedplatforms/database.html

了解 MySQL 服务器的变更

每个主要版本都有新功能、行为变化、弃用项和移除项。了解这些对现有应用程序的影响非常重要。

请参阅:3.5节,“MySQL 8.0中的更改”

运行升级检查器并修复不兼容性

MySQL Shell的升级检查器实用程序可检测数据库版本之间的不兼容性,这些不兼容性必须在执行升级之前解决。util.checkForServerUpgrade()函数可验证MySQL服务器实例是否已准备好进行升级。连接到现有的MySQL服务器,并选择计划升级到的MySQL服务器版本,以便该实用程序报告升级前需要解决的问题。这些问题包括数据类型、存储引擎等方面的不兼容性。

当升级检查实用程序不再报告任何问题时,你就可以进行升级了。

在测试环境中运行应用程序

完成升级检查器的要求后,接下来在新的目标MySQL服务器上测试您的应用程序。检查MySQL错误日志和应用程序日志中的错误和警告。

基准测试应用程序和工作负载性能

我们建议通过对比应用程序和工作负载在旧版和新版MySQL上的运行情况,对其进行基准测试。通常情况下,较新的MySQL版本会增加功能并提高性能,但在某些情况下,升级后特定查询的运行速度可能会变慢。可能导致性能下降的问题如下:

  • 先前的服务器配置对于新版本并非最优。
  • 数据类型的更改
  • 多字节字符集支持所需的额外存储空间
  • 存储引擎更改
  • 删除或更改的索引
  • 更强的加密
  • 更强的身份验证
  • SQL优化器变更
  • 较新版本的MySQL需要额外的内存
  • 物理或虚拟硬件速度较慢 - 计算或存储

有关相关信息和可能的缓解方法,请参阅有效性能回归

并行运行两个MySQL版本

为了将风险降至最低,最好在并行运行升级后的系统时,让现有系统继续运行。

运行最终测试升级

在升级生产服务器之前,请进行实践和试运行。在升级生产系统之前,务必全面测试升级流程。

检查MySQL备份

在执行升级之前,检查完整备份是否存在且可用。

升级生产服务器

你已准备好完成升级。

企业支持

如果您是MySQL企业版客户,也可以就任何疑问联系MySQL支持团队的专家。

3.4 MySQL升级过程升级哪些内容

安装新版本的MySQL可能需要升级现有安装的以下部分:

  • mysql系统模式,其中包含一些表,用于存储MySQL服务器运行时所需的信息(见7.3节,“mysql系统模式”)。mysql模式表主要分为两类:
    • 数据字典表,用于存储数据库对象元数据。
    • 系统表(即其余非数据字典表),用于其他操作目的。
  • 其他模式,其中一些是内置的,可能被视为服务器 “拥有” 的,而另一些则不是:

有两个不同的版本号与可能需要升级的安装部分相关:

  • 数据字典版本。这适用于数据字典表。
  • 服务器版本,也称为MySQL版本。这适用于系统表和其他模式中的对象。

在这两种情况下,适用于现有MySQL安装的实际版本存储在数据字典中,而当前预期版本则编译到MySQL的新版本中。当实际版本低于当前预期版本时,与该版本相关的安装部分必须升级到当前版本。如果两个版本都表明需要升级,则必须首先进行数据字典升级。

正如刚才提到的两个不同版本所反映的那样,升级分两步进行:

  • 步骤1:数据字典升级。

    此步骤升级:

    • mysql模式中的数据字典表。如果实际数据字典版本低于当前预期版本,服务器会使用更新后的定义创建数据字典表,将持久化的元数据复制到新表中,以原子方式用新表替换旧表,并重新初始化数据字典。
    • 性能架构、INFORMATION_SCHEMAndbinfo
  • 步骤2:服务器升级。

    此步骤包含所有其他升级任务。如果现有MySQL安装的服务器版本低于新安装的MySQL版本,则必须升级其他所有内容:

    • mysql 模式中的系统表(其余非数据字典表)。
    • “sys”模式。
    • 用户模式。

数据字典升级(步骤1)由服务器负责,除非使用阻止其升级的选项调用,否则服务器会在启动时根据需要执行此任务。从MySQL 8.0.16起,该选项为 --upgrade=NONE,在MySQL 8.0.16之前,该选项为 --no-dd-upgrade

如果数据字典已过时,但服务器无法升级它,则服务器将无法运行,而是会因错误而退出。例如:

[ERROR] [MY-013381] [Server] Server shutting down because upgrade is
required, yet prohibited by the command line option '--upgrade=NONE'.
[ERROR] [MY-010334] [Server] Failed to initialize DD Storage Engine
[ERROR] [MY-010020] [Server] Data Dictionary initialization failed.

MySQL 8.0.16中,步骤2的职责发生了一些变化:

  • 在 MySQL 8.0.16 之前,mysql_upgrade 会升级性能架构、INFORMATION_SCHEMA 以及步骤 2 中描述的对象。预计数据库管理员 (DBA) 会在启动服务器后手动调用 mysql_upgrade
  • 从MySQL 8.0.16开始,服务器会执行以前由mysql_upgrade处理的所有任务。虽然升级仍然是一个两步操作,但服务器会执行这两个步骤,从而使过程更简单。

根据要升级到的 MySQL 版本,原地升级逻辑升级中的说明会指出,是由服务器执行所有升级任务,还是在服务器启动后还必须调用mysql_upgrade

注意

由于服务器会升级性能架构、INFORMATION_SCHEMA以及自 MySQL 8.0.16 起步骤 2 中所述的对象,自该版本起,mysql_upgrade 便不再需要且已被弃用;预计它会在未来的 MySQL 版本中移除。

在步骤2中发生的大多数情况,在MySQL 8.0.16之前及之后都是相同的,尽管可能需要使用不同的命令选项来实现特定效果。

从MySQL 8.0.16开始,--upgrade服务器选项用于控制服务器在启动时是否以及如何执行自动升级:

  • 如果没有选项或带有--upgrade=AUTO,服务器将升级其判定为过时的任何内容(步骤1和2)。
  • 使用--upgrade=NONE时,服务器不进行任何升级(跳过步骤1和步骤2),但如果数据字典必须升级,服务器也会以错误状态退出。无法使用过时的数据字典运行服务器;服务器要么升级数据字典,要么退出。
  • 使用 --upgrade=MINIMAL 时,必要情况下,服务器会升级数据字典、性能架构和 INFORMATION_SCHEMA(步骤1)。请注意,使用此选项升级后,无法启动组复制,因为复制内部机制所依赖的系统表未更新,而且在其他方面也可能会出现功能缩减的情况。
  • 使用--upgrade=FORCE时,如有必要,服务器会升级数据字典、性能架构以及INFORMATION_SCHEMA(步骤1),并强制升级其他所有内容(步骤2)。使用此选项时,预计服务器启动所需时间更长,因为服务器会检查所有模式中的所有对象。

FORCE 用于在服务器认为无必要时强制执行步骤2的操作。FORCEAUTO 的一个区别在于,使用 FORCE 时,如果系统表(如帮助表或时区表)缺失,服务器会重新创建这些表。

以下列表展示了MySQL 8.0.16之前的升级命令以及MySQL 8.0.16及更高版本的等效命令:

在 MySQL 8.0.16 之前,某些 mysql_upgrade 选项会影响其执行的操作。下表展示了从 MySQL 8.0.16 开始,应使用哪些服务器 --upgrade 选项值来实现类似效果。(由于给定的 --upgrade 选项值可能会产生额外影响,所以这些选项值不一定完全等效。)

mysql_upgrade选项 服务器
--skip-sys-schema --upgrade=NONE--upgrade=MINIMAL
--upgrade-system-tables --upgrade=NONE 或 [--upgrade=MINIMAL](https://dev.mysql.com/doc/refman/8.0/en/server-options.html#option_mysqld_upgrad
--force --upgrade=FORCE

关于升级步骤2中发生情况的其他说明:

  • 步骤2会在sys模式未安装时进行安装,否则将其升级到当前版本。如果存在sys模式但没有version视图,则会出错,因为假设缺少该视图意味着这是一个用户创建的模式:

    A sys schema exists with no sys.version view. If
    you have a user created sys schema, this must be renamed for the
    upgrade to succeed.
    

    在这种情况下要进行升级,首先删除或重命名现有的sys模式。然后再次执行升级过程。(可能需要强制执行步骤2。)

    防止进行sys模式检查:

    • 从MySQL 8.0.16版本起:使用--upgrade=NONE--upgrade=MINIMAL选项启动服务器。
    • 在 MySQL 8.0.16 之前:使用mysql_upgrade 并带上--skip-sys-schema选项。
  • 步骤2会升级系统表,以确保其具有当前结构。无论是服务器还是mysql_upgrade执行此步骤,都是如此。关于帮助表和时区表的内容,mysql_upgrade既不会加载这两种表中的任何一种,而服务器会加载帮助表,但不会加载时区表。(也就是说,在MySQL 8.0.16之前,服务器仅在数据目录初始化时加载帮助表。从MySQL 8.0.16开始,它会在初始化和升级时加载帮助表。)加载时区表的过程取决于平台,需要数据库管理员进行决策,因此无法自动完成。

  • 从 MySQL 8.0.30 开始,当步骤 2 在升级 mysql 模式中的系统表时,mysql.dbmysql.tables_privmysql.columns_privmysql.procs_priv 表主键中的列顺序会发生变化,以便将主机名和用户名列放在一起。将主机名和用户名放在一起意味着可以使用索引查找,这将提高 CREATE USERDROP USERRENAME USER 语句的性能,以及针对具有多个权限的多个用户的访问控制列表 (ACL) 检查的性能。如果系统中有大量用户和权限,删除并重新创建索引是必要的,可能需要一些时间。

  • 步骤 2 会根据需要处理所有用户模式中的所有表。表检查可能需要很长时间才能完成。在处理表时,该表会被锁定,因此其他会话无法访问。检查和修复操作可能很耗时,尤其是对于大表。表检查使用 FOR UPGRADE 语句的 CHECK TABLE 选项。有关此选项的详细信息,请参阅 第 15.7.3.2 节,“CHECK TABLE 语句”

    为防止检查表:

    • 从MySQL 8.0.16版本起:使用--upgrade=NONE--upgrade=MINIMAL选项启动服务器。
    • 在 MySQL 8.0.16 之前:使用mysql_upgrade并带上--upgrade-system-tables选项。

    强制检查表:

    • 从 MySQL 8.0.16 起:使用--upgrade=FORCE选项启动服务器。
    • 在 MySQL 8.0.16 之前:使用mysql_upgrade 并带上--force 选项。
  • 步骤2将MySQL版本号保存在数据目录中名为mysql_upgrade_info的文件中。

    要忽略 mysql_upgrade_info 文件并无论如何执行检查:

    • 从 MySQL 8.0.16 起:使用--upgrade=FORCE选项启动服务器。
    • 在 MySQL 8.0.16 之前:使用mysql_upgrade 并带上--force 选项。

    注意

    mysql_upgrade_info文件已过时,预计在未来的MySQL版本中将被移除。

  • 步骤2会使用当前MySQL版本号标记所有已检查和修复的表。这确保了下次使用相同版本的服务器进行升级检查时,可以确定是否需要再次检查或修复某个给定的表。

3.5 MySQL 8.0中的更改

在升级到 MySQL 8.0 之前,请查看本节中描述的更改,以确定哪些更改适用于您当前的 MySQL 安装和应用程序。执行所有建议的操作。

标记为 不兼容更改 的更改与早期版本的 MySQL 不兼容,在 升级之前 您可能需要留意。我们的目标是避免这些更改,但有时为了解决比版本之间不兼容更严重的问题,这些更改是必要的。如果适用于您安装情况的升级问题涉及不兼容性,请遵循说明中给出的指示。

数据字典更改

MySQL Server 8.0 包含一个全局数据字典,其中包含有关事务表中数据库对象的信息。在之前的 MySQL 系列中,字典数据存储在元数据文件和非事务性系统表中。因此,升级过程要求您通过检查特定的先决条件来验证安装是否已做好升级准备。有关更多信息,请参阅3.6 节,“为升级准备安装”。启用数据字典的服务器在常规操作方面存在一些差异;请参阅16.7 节,“数据字典使用差异”

将“caching_sha2_password”作为首选身份验证插

caching_sha2_passwordsha256_password身份验证插件提供了比mysql_native_password插件更安全的密码加密方式,并且caching_sha2_passwordsha256_password具有更好的性能。由于caching_sha2_password在安全性和性能方面的这些优势,自MySQL 8.0起,它成为首选的身份验证插件,同时也是默认的身份验证插件,而非mysql_native_password。这一变化对服务器和libmysqlclient客户端库都有影响:

  • 对于服务器而言,系统变量default_authentication_plugin的默认值从mysql_native_password更改为caching_sha2_password

    此更改仅适用于安装或升级到 MySQL 8.0 或更高版本后创建的新账户。对于升级安装中已存在的账户,其身份验证插件保持不变。希望切换到 caching_sha2_password 的现有用户可以使用 ALTER USER 语句来实现:

    ALTER USER user
      IDENTIFIED WITH caching_sha2_password
      BY 'password';
    
  • libmysqlclient 库将caching_sha2_password 视为默认身份验证插件,而不是mysql_native_password

以下各节讨论caching_sha2_password发挥更重要作用所带来的影响:

caching_sha2_password的兼容性问题及解决方案

[!IMPORTANT]

如果你的MySQL安装必须为8.0之前版本的客户端提供服务,并且在升级到MySQL 8.0或更高版本后遇到兼容性问题,解决这些问题并恢复8.0之前版本兼容性的最简单方法是重新配置服务器,以恢复到之前的默认身份验证插件(mysql_native_password)。例如,在服务器选项文件中使用以下几行内容:

[mysqld]
default_authentication_plugin=mysql_native_password

该设置允许8.0版本之前的客户端连接到8.0版本的服务器,直到您安装中使用的客户端和连接器升级到知晓caching_sha2_password。但是,该设置应被视为临时的,而非长期或永久的解决方案,因为它会导致在此设置生效时创建的新账户无法享受caching_sha2_password提供的增强身份验证安全性。

使用caching_sha2_passwordmysql_native_password提供了更安全的密码哈希(以及随之而来的改进的客户端连接认证)。但是,它也存在兼容性问题,可能会影响现有的MySQL安装:

  • 尚未更新以了解caching_sha2_password的客户端和连接器,在连接配置了caching_sha2_password作为默认身份验证插件的MySQL 8.0服务器时可能会遇到问题,即使是使用并非通过caching_sha2_password进行身份验证的账户也是如此。出现此问题是因为服务器会向客户端指定其默认身份验证插件的名称。如果某个客户端或连接器所基于的客户端/服务器协议实现无法妥善处理无法识别的默认身份验证插件,则可能会出现如下错误:

    Authentication plugin 'caching_sha2_password' is not supported
    
    Authentication plugin 'caching_sha2_password' cannot be loaded:
    dlopen(/usr/local/mysql/lib/plugin/caching_sha2_password.so, 2):
    image not found
    
    Warning: mysqli_connect(): The server requested authentication
    method unknown to the client [caching_sha2_password]
    

    有关编写连接器以妥善处理服务器针对未知默认身份验证插件发出的请求的信息,请参阅身份验证插件连接器编写注意事项

  • 使用通过caching_sha2_password进行身份验证的账户的客户端,必须使用安全连接(使用TCP并通过TLS/SSL凭证建立,或使用Unix套接字文件,或共享内存),或者使用支持使用RSA密钥对进行密码交换的未加密连接。此安全要求不适用于mysql_native_passsword,因此切换到caching_sha2_password可能需要额外配置(见8.4.1.2节,“缓存SHA-2可插拔身份验证”)。不过,MySQL 8.0中的客户端连接默认倾向于使用TLS/SSL,因此已符合该偏好的客户端可能无需额外配置。

  • 尚未更新以了解caching_sha2_password的客户端和连接器无法连接到使用caching_sha2_password进行身份验证的账户,因为它们不认为该插件有效。(这是如身份验证插件客户端/服务器兼容性中所讨论的客户端/服务器身份验证插件兼容性要求如何应用的一个具体例子。)要解决此问题,可以使用MySQL 8.0或更高版本中的libmysqlclient重新链接客户端,或者获取可识别caching_sha2_password的更新连接器。

  • 因为caching_sha2_password现在也是libmysqlclient客户端库中的默认身份验证插件,所以对于从MySQL 8.0客户端到使用mysql_native_password(之前的默认身份验证插件)的账户的连接,身份验证在客户端/服务器协议中需要额外的一次往返,除非客户端程序使用--default-auth=mysql_native_password选项调用。

8.0 之前版本的 MySQL 所使用的 libmysqlclient 客户端库能够连接到 MySQL 8.0 服务器(使用 caching_sha2_password 进行身份验证的账户除外)。这意味着基于 libmysqlclient 的 8.0 之前版本的客户端也应该能够连接。示例:

  • 标准的MySQL客户端,如mysqlmysqladmin,都是基于libmysqlclient的。
  • 用于Perl DBI的DBD::mysql驱动程序是基于libmysqlclient的。
  • MySQL Connector/Python 有一个基于libmysqlclient的 C 扩展模块。要使用它,在连接时包含use_pure=False选项。

当将现有的MySQL 8.0安装升级到MySQL 8.0.4或更高版本时,一些较旧的基于libmysqlclient的客户端如果是动态链接的,可能会“自动”升级,因为它们使用升级时安装的新客户端库。例如,如果用于Perl DBI的DBD::mysql驱动程序使用动态链接,在升级到MySQL 8.0.4或更高版本后,它可以使用libmysqlclient,结果如下:

  • 在升级之前,使用DBD::mysql的DBI脚本可以连接到MySQL 8.0服务器,但使用caching_sha2_password进行身份验证的账户除外。
  • 升级后,相同的脚本也能够使用caching_sha2_password账户。

然而,出现上述结果是因为8.0.4之前的MySQL 8.0安装中的libmysqlclient实例具有二进制兼容性:它们都使用主版本号为21的共享库。对于链接到MySQL 5.7或更早版本的libmysqlclient的客户端,它们链接到的共享库版本号不同,且不具备二进制兼容性。在这种情况下,为了与MySQL 8.0服务器和caching_sha2_password账户完全兼容,客户端必须针对8.0.4或更高版本的libmysqlclient重新编译。

MySQL Connector/J 5.1 至 8.0.8 能够连接到 MySQL 8.0 服务器,但使用caching_sha2_password进行身份验证的账户除外。(连接到使用caching_sha2_password进行身份验证的账户需要 Connector/J 8.0.9 或更高版本。)

使用除libmysqlclient之外的客户端/服务器协议实现的客户端,可能需要升级到较新版本,以便识别新的身份验证插件。例如,在PHP中,MySQL连接通常基于mysqlnd,而该组件目前还不了解caching_sha2_password。在mysqlnd的更新版本发布之前,要让PHP客户端能够连接到MySQL 8.0,方法是重新配置服务器,将默认身份验证插件恢复为mysql_native_password,如前文所述。

如果客户端或连接器支持显式指定默认身份验证插件的选项,请使用该选项指定除 caching_sha2_password 之外的插件。示例:

  • 一些MySQL客户端支持--default-auth选项。(标准的MySQL客户端,如mysqlmysqladmin支持此选项,但即使不使用该选项也能成功连接到8.0版本的服务器。不过,其他客户端可能支持类似的选项。如果是这样,不妨一试。)
  • 使用 libmysqlclient CAPI 的程序可以使用 MYSQL_DEFAULT_AUTH 选项调用 mysql_options() 函数。
  • 使用客户端/服务器协议的原生Python实现的MySQL Connector/Python脚本可以指定auth_plugin连接选项。(或者,使用Connector/Python C扩展,它能够连接到MySQL 8.0服务器,而无需auth_plugin。)

与“caching_sha2_password”兼容的客户端和连接器

如果有已更新以了解 caching_sha2_password 的客户端或连接器可用,那么在连接到配置为以 caching_sha2_password 作为默认身份验证插件的 MySQL 8.0 服务器时,使用该客户端或连接器是确保兼容性的最佳方法。

这些客户端和连接器已升级,以支持caching_sha2_password

  • MySQL 8.0(8.0.4 或更高版本)中的 libmysqlclient 客户端库。标准 MySQL 客户端,如 mysqlmysqladmin 都是基于 libmysqlclient 的,因此它们也具有兼容性。

  • MySQL 5.7(5.7.23 或更高版本)中的libmysqlclient客户端库。诸如mysqlmysqladmin之类的标准 MySQL 客户端都是基于libmysqlclient的,因此它们也具有兼容性。

  • MySQL Connector/C++ 1.1.11或更高版本,或8.0.7或更高版本。

  • MySQL Connector/J 8.0.9 或更高版本。

  • MySQL Connector/NET 8.0.10 或更高版本(通过经典 MySQL 协议)。

  • MySQL Connector/Node.js 8.0.9 或更高版本。

  • PHP:X DevAPI PHP扩展(mysql_xdevapi)支持caching_sha2_password

    PHP:PDO_MySQL和ext/mysqli扩展不支持caching_sha2_password。此外,在PHP 7.1.16之前的版本以及PHP 7.2.4之前的PHP 7.2版本中使用时,即使未使用caching_sha2_password,它们也无法使用default_authentication_plugin=caching_sha2_password进行连接。

caching_sha2_password与root管理账户

对于升级到MySQL 8.0的情况,现有账户的身份验证插件保持不变,包括'root'@'localhost'管理账户的插件。

对于全新安装的MySQL 8.0,初始化数据目录时(使用第2.9.1节“初始化数据目录”中的说明),会创建“'root'@'localhost'”账户,且该账户默认使用“caching_sha2_password”。因此,数据目录初始化完成后,若要连接到服务器,必须使用支持“caching_sha2_password”的客户端或连接器。如果可以做到这一点,但希望安装后“root”账户使用“mysql_native_password”,则按常规方式安装MySQL并初始化数据目录。然后以“root”身份连接到服务器,并按如下方式使用“ALTER USER”更改账户身份验证插件和密码:

ALTER USER 'root'@'localhost'
  IDENTIFIED WITH mysql_native_password
  BY 'password';

如果您使用的客户端或连接器尚不支持caching_sha2_password,则可以使用修改后的数据目录初始化过程,在创建root账户时,立即将该账户与mysql_native_password关联起来。为此,可以使用以下任意一种方法:

caching_sha2_password与复制

在所有服务器均已升级到MySQL 8.0.4或更高版本的复制场景中,到源服务器的副本连接可以使用通过caching_sha2_password进行身份验证的账户。对于此类连接,与使用通过caching_sha2_password进行身份验证的账户的其他客户端适用相同的要求:使用安全连接或基于RSA的密码交换。

要连接用于源/副本复制的caching_sha2_password账户:

  • 使用以下任何一种 CHANGE MASTER TO 选项:

    MASTER_SSL = 1
    GET_MASTER_PUBLIC_KEY = 1
    MASTER_PUBLIC_KEY_PATH='path to RSA public key file'
    
  • 或者,如果在服务器启动时提供了所需的密钥,你可以使用与RSA公钥相关的选项。

要连接用于组复制的caching_sha2_password账户:

  • 对于使用OpenSSL构建的MySQL,设置以下任何一个系统变量:

    SET GLOBAL group_replication_recovery_use_ssl = ON;
    SET GLOBAL group_replication_recovery_get_public_key = 1;
    SET GLOBAL group_replication_recovery_public_key_path = 'path to RSA public key file';
    
  • 或者,如果在服务器启动时提供了所需的密钥,你可以使用与RSA公钥相关的选项。

配置更改

  • 不兼容的更改:现在,MySQL存储引擎负责提供自己的分区处理程序,MySQL服务器不再提供通用的分区支持。InnoDBNDB是MySQL 8.0中仅有的两个提供本地分区处理程序并受支持的存储引擎。使用其他任何存储引擎的分区表,在升级服务器之前,必须进行更改,要么将其转换为InnoDBNDB,要么移除其分区,否则之后将无法使用。

    有关将 MyISAM 表转换为 InnoDB 的信息,请参阅第 17.6.1.5 节,“将表从 MyISAM 转换为 InnoDB”

    在MySQL 8.0中,使用不支持分区的存储引擎创建分区表的表创建语句会报错(ER_CHECK_NOT_IMPLEMENTED)。如果使用mysqldump将在MySQL 5.7(或更早版本)中创建的转储文件中的数据库导入到MySQL 8.0服务器中,必须确保任何创建分区表的语句都不指定不支持的存储引擎,方法是删除任何与分区相关的引用,或将存储引擎指定为InnoDB,或允许默认设置为InnoDB

    注意

    第3.6节“为升级准备安装”中给出的步骤介绍了如何识别在升级到MySQL 8.0之前必须修改的分区表。

    有关更多信息,请参阅26.6.2节“与存储引擎相关的分区限制”

  • 不兼容的更改:有几个服务器错误代码已不再使用并已被移除(列表请参阅MySQL 8.0 中移除的功能)。专门测试其中任何一个错误代码的应用程序应进行更新。

  • 重要更改:默认字符集已从latin1更改为utf8mb4。受影响的系统变量如下:

    因此,除非显式指定字符集和排序规则,否则新对象的默认字符集和排序规则将与以前不同。这包括数据库及其内部的对象,如表、视图和存储程序。假设使用了以前的默认设置,保留这些设置的一种方法是在 my.cnf 文件中使用以下几行启动服务器:

    [mysqld]
    character_set_server=latin1
    collation_server=latin1_swedish_ci
    

    在复制环境中,从MySQL 5.7升级到8.0时,建议在升级前将默认字符集改回MySQL 5.7中使用的字符集。升级完成后,可将默认字符集更改为utf8mb4

    此外,您应该注意,MySQL 8.0 会对给定字符集中允许的字符执行检查,而 MySQL 5.7 则不会;这是一个已知问题。这意味着,在尝试升级之前,您应确保注释中不包含所用字符集未定义的字符。您可以通过以下两种方法之一解决此问题:

    • 将字符集更改为包含相关字符的字符集。
    • 删除违规字符。

    上述内容适用于表、文件和索引注释。

  • 不兼容的更改:从 MySQL 8.0.11 开始,禁止使用与服务器初始化时不同的lower_case_table_names设置启动服务器。此限制很有必要,因为各种数据字典表字段使用的排序规则基于服务器初始化时定义的lower_case_table_names设置,使用不同的设置重新启动服务器会在标识符的排序和比较方面引入不一致性。

服务器更改

  • 在MySQL 8.0.11中,一些与账户管理相关的已弃用功能已被移除,例如使用 GRANT 语句修改用户账户的非特权特性、NO_AUTO_CREATE_USER SQL模式、PASSWORD() 函数以及 old_passwords 系统变量。

    从 MySQL 5.7 到 8.0 复制引用这些已移除功能的语句可能会导致复制失败。使用任何已移除功能的应用程序都应进行修订,尽可能避免使用这些功能并改用替代方案,如 MySQL 8.0 中移除的功能 所述。

    为避免在MySQL 8.0上启动失败,请从MySQL选项文件中的sql_mode系统变量设置中删除任何NO_AUTO_CREATE_USER实例。

    将包含存储程序定义中NO_AUTO_CREATE_USER SQL模式的转储文件加载到MySQL 8.0服务器中会导致失败。从MySQL 5.7.24和MySQL 8.0.13开始,mysqldump会从存储程序定义中移除NO_AUTO_CREATE_USER。使用早期版本的mysqldump创建的转储文件必须手动修改,以移除NO_AUTO_CREATE_USER实例。

  • 在MySQL 8.0.11中,已移除以下弃用的兼容SQL模式:DB2MAXDBMSSQLMYSQL323MYSQL40ORACLEPOSTGRESQLNO_FIELD_OPTIONSNO_KEY_OPTIONSNO_TABLE_OPTIONS。这些模式不能再分配给sql_mode系统变量,也不能用作mysqldump--compatible选项的允许值。

    移除MAXDB意味着,对于CREATE TABLEALTER TABLE语句,TIMESTAMP数据类型不再被视为DATETIME

    从MySQL 5.7到8.0复制引用已移除SQL模式的语句可能会导致复制失败。这包括在当前sql_mode值包含任何已移除模式时执行的存储程序(存储过程和函数、触发器和事件)的CREATE语句的复制。使用任何已移除模式的应用程序应进行修订以避免使用这些模式。

  • 许多MySQL 8.0错误消息的文本已被修订和改进,以提供比MySQL 5.7更多、更好的信息。如果您的应用程序依赖于错误消息的特定内容或格式,您应该对此进行测试,并准备好在执行升级之前相应地更新应用程序。

  • 从 MySQL 8.0.3 开始,空间数据类型允许使用SRID属性,以显式指示存储在该列中的值的空间参考系统 (SRS)。请参见 13.4.1 节,“空间数据类型”

    具有显式 SRID 属性的空间列受 SRID 限制:该列仅接受具有该 ID 的值,并且该列上的 SPATIAL 索引可供优化器使用。优化器会忽略没有 SRID 属性的空间列上的 SPATIAL 索引。请参阅 第 10.3.3 节,“SPATIAL 索引优化”。如果希望优化器考虑不受 SRID 限制的空间列上的 SPATIAL 索引,则应修改每个此类列:

    • 验证列中的所有值是否具有相同的空间参考标识符(SRID)。要确定几何列 col_name 中包含的 SRID,请使用以下查询:

      SELECT DISTINCT ST_SRID(col_name) FROM tbl_name;
      

      如果查询返回不止一行,则该列包含混合的空间参考标识符(SRID)。在这种情况下,修改其内容,使所有值具有相同的空间参考标识符(SRID)。

    • 重新定义该列,使其具有显式的SRID属性。

    • 重新创建 SPATIAL 索引。

  • 在MySQL 8.0.0中,由于空间函数命名空间发生了变化,移除了几个空间函数。对于执行精确操作的函数,实现了ST_前缀;对于基于最小边界矩形执行操作的函数,实现了MBR前缀。在生成列定义中使用已移除的空间函数可能会导致升级失败。在升级之前,运行mysqlcheck --check-upgrade查找已移除的空间函数,并将找到的函数替换为相应的以ST_MBR命名的替代函数。有关已移除的空间函数列表,请参阅MySQL 8.0中移除的功能

  • 在执行到 MySQL 8.0.3 或更高版本的就地升级时,BACKUP_ADMIN 权限会自动授予拥有RELOAD 权限的用户。

  • 从MySQL 8.0.13版本开始,由于基于行的或混合复制模式与基于语句的复制模式在处理临时表的方式上存在差异,因此在运行时切换二进制日志记录格式有了新的限制。

    • 如果会话中有任何打开的临时表,则不能使用SET @@SESSION.binlog_format
    • 如果任何复制通道有任何打开的临时表,则不能使用SET @@global.binlog_formatSET @@persist.binlog_format。如果复制通道有打开的临时表,则允许使用SET<br /> @@persist_only.binlog_format,因为与PERSIST 不同,PERSIST_ONLY 不会修改运行时全局系统变量值。
    • 如果任何复制通道应用程序正在运行,则不能使用SET @@global.binlog_formatSET @@persist.binlog_format。这是因为只有在重新启动复制通道的应用程序时,更改才会在该复制通道上生效,而此时复制通道可能已打开临时表。此行为比以前更加严格。如果任何复制通道应用程序正在运行,允许使用SET<br /> @@persist_only.binlog_format
    • 从MySQL 8.0.27版本起,配置internal_tmp_mem_storage_engine的会话设置需要具备SESSION_VARIABLES_ADMINSYSTEM_VARIABLES_ADMIN权限。
    • 从MySQL 8.0.27版本开始,克隆插件允许在克隆操作进行时,在源MySQL Server实例上并发执行DDL操作。此前,在克隆操作期间会持有备份锁,阻止在源上进行并发DDL操作。若要恢复到克隆操作期间阻止源上并发DDL操作的先前行为,请启用[clone_block_ddl](https://dev.mysql.com/doc/refman/8.0/en/clone-plugin-options-variables.html#sysvar_clone_block_ddl)变量。请参阅[7.6.7.4节,“克隆与并发DDL”](https://dev.mysql.com/doc/refman/8.0/en/clone-plugin-concurrent-ddl.html)
  • 从 MySQL 8.0.30 开始,在 MySQL 服务器启动序列的早期,会隐式加载启动时log_error_services值中列出的错误日志组件。如果您之前使用 INSTALL COMPONENT 安装了可加载的错误日志组件,并且在启动时读取的(例如,从选项文件中读取的)log_error_services 设置中列出了这些组件,则应更新您的配置以避免启动警告。有关更多信息,请参阅错误日志配置方法

InnoDB变更 """ InnoDB Changes

  • 基于InnoDB系统表的INFORMATION_SCHEMA视图已被数据字典表上的内部系统视图取代。受影响的InnoDBINFORMATION_SCHEMA视图已重命名:

    表3.1 重命名的InnoDB信息架构视图

    旧名称 新名称
    INNODB_SYS_COLUMNS INNODB_COLUMNS
    INNODB_SYS_DATAFILES INNODB_DATAFILES
    INNODB_SYS_FIELDS INNODB_FIELDS
    INNODB_SYS_FOREIGN INNODB_FOREIGN
    INNODB_SYS_FOREIGN_COLS INNODB_FOREIGN_COLS
    INNODB_SYS_INDEXES INNODB_INDEXES
    INNODB_SYS_TABLES INNODB_TABLES
    INNODB_SYS_TABLESPACES INNODB_TABLESPACES
    INNODB_SYS_TABLESTATS INNODB_TABLESTATS
    INNODB_SYS_VIRTUAL INNODB_VIRTUAL

    升级到MySQL 8.0.3或更高版本后,请更新所有引用早期InnoDBINFORMATION_SCHEMA视图名称的脚本。

  • MySQL 捆绑的zlib库版本从1.2.3版提升到了1.2.11版。

    zlib 1.2.11 中的 zlib compressBound() 函数对压缩给定字节长度所需的缓冲区大小的估计值,比 zlib 1.2.3 版本中的估计值略高。compressBound() 函数由 InnoDB 函数调用,这些函数用于确定在创建压缩的 InnoDB 表时,或在压缩的 InnoDB 表中插入和更新行时允许的最大行大小。因此,CREATE TABLE ... ROW_FORMAT=COMPRESSEDINSERTUPDATE 操作(其行大小非常接近早期版本中成功的最大行大小)现在可能会失败。为避免此问题,在升级前,在 MySQL 8.0 测试实例上测试包含大行的压缩 InnoDB 表的 CREATE TABLE 语句。

  • 随着--innodb-directories功能的引入,使用绝对路径或在数据目录之外的位置创建的独立表文件和通用表空间文件的位置,应添加到innodb_directories参数值中。否则,InnoDB在恢复期间将无法定位这些文件。要查看表空间文件的位置,请查询信息架构中的FILES表:

    SELECT TABLESPACE_NAME, FILE_NAME FROM INFORMATION_SCHEMA.FILES \G
    
  • 撤销日志不能再存储在系统表空间中。在MySQL 8.0中,撤销日志默认存储在两个撤销表空间中。有关更多信息,请参见17.6.3.4节,“撤销表空间”

    从MySQL 5.7升级到MySQL 8.0时,MySQL 5.7实例中存在的任何撤销表空间都将被移除,并由两个新的默认撤销表空间取代。默认撤销表空间在由 [innodb_undo_directory](https://dev.mysql.com/doc/refman/8.0/en/innodb-parameters.html#sysvar_innodb_undo_directory) 变量定义的位置创建。如果 [innodb_undo_directory](https://dev.mysql.com/doc/refman/8.0/en/innodb-parameters.html#sysvar_innodb_undo_directory) 变量未定义,则在数据目录中创建撤销表空间。从MySQL 5.7升级到MySQL 8.0需要缓慢关闭,以确保MySQL 5.7实例中的撤销表空间为空,从而可以安全地将其移除。

    从早期的 MySQL 8.0 版本升级到 MySQL 8.0.14 或更高版本时,由于 innodb_undo_tablespaces 设置大于 2 而存在于升级前实例中的撤销表空间将被视为用户定义的撤销表空间,升级后,可分别使用 ALTER UNDOTABLESPACEDROP UNDOTABLESPACE 语法停用并删除这些表空间。在 MySQL 8.0 系列版本内进行升级,并非始终需要缓慢关闭,这意味着现有撤销表空间可能包含撤销日志。因此,升级过程不会删除现有撤销表空间。

  • 不兼容的更改:从 MySQL 8.0.17 开始,CREATE TABLESPACE ... ADD DATAFILE 子句不允许循环目录引用。例如,以下语句中的循环目录引用(/../)是不允许的:

    CREATE TABLESPACE ts1 ADD DATAFILE ts1.ibd 'any_directory/../ts1.ibd';
    

    在Linux系统上,这一限制存在一个例外情况,即如果前一个目录是符号链接,则允许存在循环目录引用。例如,如果any_directory是一个符号链接,那么上述示例中的数据文件路径就是允许的。(数据文件路径仍允许以'../'开头。)

    为避免升级问题,在升级到MySQL 8.0.17或更高版本之前,请从表空间数据文件路径中删除任何循环目录引用。若要检查表空间路径,请查询信息架构中的INNODB_DATAFILES表。

  • 由于MySQL 8.0.14引入了一个回归问题,在区分大小写的文件系统上,从MySQL 5.7或MySQL 8.0.14之前的MySQL 8.0版本就地升级到MySQL 8.0.16时,对于包含分区表且lower_case_table_names=1的实例会失败。该失败是由与分区表文件名相关的大小写不匹配问题导致的。引入该回归问题的修复已被撤销,这使得从MySQL 5.7或MySQL 8.0.14之前的MySQL 8.0版本升级到MySQL 8.0.17能够正常进行。但是,该回归问题在MySQL 8.0.14、8.0.15和8.0.16版本中仍然存在。

    在区分大小写的文件系统上进行原地升级,从 MySQL 8.0.14、8.0.15 或 8.0.16 升级到 MySQL 8.0.17 时,如果存在分区表且lower_case_table_names=1,在将二进制文件或软件包升级到 MySQL 8.0.17 后启动服务器时,会出现以下错误:

    Upgrading from server version version_number with
    partitioned tables and lower_case_table_names == 1 on a case sensitive file
    system may cause issues, and is therefore prohibited. To upgrade anyway, restart
    the new server version with the command line option 'upgrade=FORCE'. When
    upgrade is completed, please execute 'RENAME TABLE part_table_name
    TO new_table_name; RENAME TABLE new_table_name
    TO part_table_name;' for each of the partitioned tables.
    Please see the documentation for further information.
    

    如果在升级到MySQL 8.0.17时遇到此错误,请执行以下解决方法:

    1. 使用--upgrade=force重启服务器,以强制升级操作继续进行。

    2. 识别分区表文件名,其中分区名称分隔符为小写(#p##sp#):

      mysql> SELECT FILE_NAME FROM INFORMATION_SCHEMA.FILES WHERE FILE_NAME LIKE '%#p#%' OR FILE_NAME LIKE '%#sp#%';
      
    3. 对于识别出的每个文件,使用临时名称重命名关联表,然后将该表重命名回其原始名称。

      mysql> RENAME TABLE table_name TO temporary_table_name;
      mysql> RENAME TABLE temporary_table_name TO table_name;
      
    4. 验证不存在分区表文件名小写分区名分隔符(应返回空结果集)。

      mysql> SELECT FILE_NAME FROM INFORMATION_SCHEMA.FILES WHERE FILE_NAME LIKE '%#p#%' OR FILE_NAME LIKE '%#sp#%';
      Empty set (0.00 sec)
      
    5. 对每个重命名的表运行 ANALYZE TABLE,以更新 mysql.innodb_index_statsmysql.innodb_table_stats 表中的优化器统计信息。

    由于MySQL 8.0.14、8.0.15和8.0.16版本中仍然存在回归问题,因此在lower_case_table_names=1的区分大小写的文件系统上,不支持将分区表从MySQL 8.0.14、8.0.15或8.0.16导入到MySQL 8.0.17。尝试这样做会导致“表的表空间缺失”错误。

  • MySQL在为表分区构造表空间名和文件名时会使用分隔符字符串。如以下所示,“#p# ”分隔符字符串位于分区名之前,“ #sp#”分隔符字符串位于子分区名之前:

          schema_name.table_name#p#partition_name#sp#subpartition_name
          table_name#p#partition_name#sp#subpartition_name.ibd
    

    从历史上看,在像Linux这样区分大小写的文件系统中,分隔符字符串为大写形式(#P##SP#),而在像Windows这样不区分大小写的文件系统中,分隔符字符串为小写形式(#p##sp#)。从MySQL 8.0.19版本起,在所有文件系统中,分隔符字符串均为小写形式。这一变化避免了在区分大小写和不区分大小写的文件系统之间迁移数据目录时出现问题。大写的分隔符字符串不再使用。

    此外,基于用户指定的分区或子分区名称生成的分区表空间名称和文件名(分区或子分区名称可指定为大写或小写),现在无论lower_case_table_names如何设置,均以小写形式生成(并在内部存储),以确保不区分大小写。例如,如果创建一个名为PART_1的表分区,则表空间名称和文件名会以小写形式生成:

          schema_name.table_name#p#part_1
          table_name#p#part_1.ibd
    

    升级期间,MySQL 会进行检查,并在必要时进行修改:

    • 对磁盘和数据字典中的分区文件名进行处理,确保分隔符和分区名称为小写。
    • 数据字典中分区元数据,用于处理先前错误修复所引入的相关问题。
    • 与之前错误修复所引发的相关问题有关的InnoDB统计数据。

    在表空间导入操作期间,将检查磁盘上的分区表空间文件名称,并在必要时进行修改,以确保分隔符和分区名称为小写。

  • 从 MySQL 8.0.21 开始,如果在启动时或从 MySQL 5.7 升级时发现表空间数据文件位于未知目录中,会将一条警告写入错误日志。已知目录是由 datadirinnodb_data_home_dirinnodb_directories 变量定义的目录。要使某个目录成为已知目录,可将其添加到 innodb_directories 设置中。将目录设置为已知目录可确保在恢复期间能够找到数据文件。有关更多信息,请参见“崩溃恢复期间的表空间发现”。

  • 重要更改:从MySQL 8.0.30开始,innodb_redo_log_capacity变量控制重做日志文件占用的磁盘空间量。随着这一更改,重做日志文件的默认数量及其位置也发生了变化。从MySQL 8.0.30开始,InnoDB 在数据目录中的 #innodb_redo 目录中维护32个重做日志文件。此前,InnoDB 默认在数据目录中创建两个重做日志文件,重做日志文件的数量和大小由 innodb_log_files_in_groupinnodb_log_file_size 变量控制。现在这两个变量已弃用。

    当定义了innodb_redo_log_capacity设置时,innodb_log_files_in_groupinnodb_log_file_size设置将被忽略;否则,将使用这些设置来计算innodb_redo_log_capacity设置(innodb_log_files_in_group * innodb_log_file_size = innodb_redo_log_capacity)。如果这些变量都未设置,则重做日志容量将设置为innodb_redo_log_capacity的默认值,即104857600字节(100MB)。

    与任何升级通常所需的操作一样,此更改在升级前需要正常关闭。

    有关此功能的更多信息,请参阅17.6.5节,“重做日志”

  • 在MySQL 5.7.35之前,采用冗余或紧凑行格式的表中的索引没有大小限制。从MySQL 5.7.35开始,限制为767字节。从5.7.35之前的MySQL版本升级到MySQL 8.0可能会导致表无法访问。如果采用冗余或紧凑行格式的表的索引大于767字节,请在升级到MySQL 8.0之前删除并重新创建该索引。错误消息为:

    mysql> ERROR 1709 (HY000): Index column size too large. The maximum column size is 767 bytes.
    

SQL更改

  • 不兼容的更改:从MySQL 8.0.13开始,已删除ASC或DESC限定符,这些限定符之前用于GROUP BY子句,但已被弃用。以前依赖GROUP BY排序的查询,其结果可能与之前的MySQL版本不同。若要生成特定的排序顺序,请提供ORDER BY子句。 对于MySQL 8.0.12或更低版本中使用ASC或DESC限定符的GROUP BY子句的查询和存储程序定义,应进行修改。否则,升级到MySQL 8.0.13或更高版本可能会失败,复制到MySQL 8.0.13或更高版本的副本服务器也可能失败。

  • 不兼容的更改:从MySQL 8.0.13开始,已删除已弃用的用于 GROUP<br /> BY 子句的 ASCDESC 限定符。以前依赖 GROUP BY 的查询可能会产生与以前MySQL版本不同的结果。要生成给定的排序顺序,请提供 ORDER<br /> BY 子句。

    对于使用 ASCDESC 限定符来定义 GROUP<br /> BY 子句的MySQL 8.0.12 或更低版本的查询和存储程序定义,应进行修改。否则,升级到 MySQL 8.0.13 或更高版本可能会失败,复制到 MySQL 8.0.13 或更高版本的复制服务器也可能失败。

  • 在MySQL 8.0中,某些关键字可能是保留字,但在MySQL 5.7中不是。请参阅第11.3节,“关键字和保留字”。这可能会导致以前用作标识符的单词变为非法。要修复受影响的语句,请使用标识符引用。请参阅第11.2节,“模式对象名称”

  • 升级后,建议测试应用程序代码中指定的优化器提示,以确保仍需这些提示来实现所需的优化策略。优化器的增强有时可能会使某些优化器提示变得不必要。在某些情况下,不必要的优化器提示甚至可能适得其反。

  • 不兼容的更改:在MySQL 5.7中,为InnoDB表指定FOREIGN KEY定义时如果未使用CONSTRAINT symbol<br /> 子句,或者指定CONSTRAINT关键字时未使用symbolInnoDB将使用生成的约束名称。在MySQL 8.0中,该行为发生了变化,InnoDB使用FOREIGN KEY index_name<br /> 的值而不是生成的名称。由于每个模式(数据库)中的约束名称必须唯一,因此该更改会因每个模式中的外键索引名称不唯一而导致错误。为避免此类错误,MySQL 8.0.16中已恢复新的约束命名行为,InnoDB再次使用生成的约束名称。

    为了与 InnoDB 保持一致,基于 MySQL 8.0.16 或更高版本的 NDB 版本在未指定 CONSTRAINT symbol<br /> 子句,或者指定了 CONSTRAINT 关键字但未指定 symbol 时,会使用生成的约束名称。基于 MySQL 5.7 及更早 MySQL 8.0 版本的 NDB 版本使用 FOREIGN KEY index_name<br /> 值。

    上述更改可能会导致依赖于之前外键约束命名行为的应用程序出现不兼容问题。

  • 在MySQL 8.0.22中,MySQL流控制函数(如 IFNULL()CASE())对系统变量值的处理方式发生了变化;现在,系统变量值的处理方式与相同字符和排序规则的列值相同,而不是作为常量处理。一些以前使用这些函数和系统变量成功执行的查询,随后可能会因“排序规则非法混合”而被拒绝。在这种情况下,需将系统变量转换为正确的字符集和排序规则。

  • 不兼容的变更:MySQL 8.0.28 修复了之前 MySQL 8.0 版本中的一个问题,即 CONVERT() 函数有时允许将 BINARY 值无效转换为非二进制字符集。可能依赖此行为的应用程序应进行检查,必要时在升级前进行修改。

    特别是,当CONVERT()作为索引生成列表达式的一部分使用时,函数行为的变化可能会导致升级到MySQL 8.0.28后索引损坏。你可以按照以下步骤防止这种情况发生:

    1. 在执行升级之前,纠正任何无效的输入数据。

    2. 删除然后重新创建索引。

      你也可以改用ALTER TABLE table FORCE 强制重建表。

    3. 升级MySQL软件。

    如果您无法事先验证输入数据,则在升级到MySQL 8.0.28之后,才应重新创建索引或重建表。

更改的服务器默认设置

MySQL 8.0 配备了经过改进的默认设置,旨在提供尽可能最佳的开箱即用体验。这些更改是由于技术不断进步(机器配备更多 CPU、使用固态硬盘等)、存储的数据越来越多、MySQL 不断发展(InnoDB、组复制、AdminAPI 等)等因素推动的。下表总结了为大多数用户提供最佳 MySQL 体验而进行更改的默认设置。

选项/参数 旧默认值 新默认值
服务器更改
字符集服务器 latin1字符集 utf8mb4
排序规则服务器 latin1_swedish_ci(这是一种字符集校对规则,一般不做翻译,直接保留原文使用,若强行翻译可译为“latin1瑞典语校对规则” ) utf8mb4_0900_ai_ci
显式时间戳默认值 关闭
优化器跟踪最大内存大小 16KB 1兆字节
验证密码检查用户名 关闭
积压队列 -1(自动调整大小)自以下内容更改:back_log = 50 + (最大连接数 / 5) -1(自动调整大小)更改为:back_log = max_connections
最大允许数据包 4194304 (4MB) 67108864(64MB)
最大错误计数
事件调度器 关闭 开启
表打开缓存
日志错误详细程度 3(注释) 2(警告)
本地文件 开启(5.7 版本) 关闭
InnoDB变更
innodb回滚表空间
innodb_undo_log_truncate:InnoDB撤销日志截断 关闭
innodb刷新方法 空值 fsync(Unix),无缓冲(Windows)
innodb自动递增锁模式 1(连续) 2(交错)
刷新邻接页 1(启用) 0(禁用)
innodb最大脏页比例低水位线 0(%) 10(%)
innodb最大脏页百分比 75(%) 90(%)
性能模式更改
performance-schema-instrument='wait/lock/metadata/sql/%=ON' 关闭
performance-schema-instrument='memory/%=COUNTED' 关闭 统计的
performance-schema-consumer-events-transactions-current=ON 关闭
performance-schema-consumer-events-transactions-history=ON 关闭
performance-schema-instrument='transaction%=ON' 关闭
复制更改
日志二进制文件 关闭
服务器ID
记录从服务器更新 关闭
日志过期天数
主信息存储库 文件
中继日志信息存储库 文件
事务写集提取 关闭 XX哈希64
从库行查找算法 索引扫描, 表扫描 索引扫描,哈希扫描
从库待处理任务大小上限 16M 128M
gtid已执行压缩周期
组复制更改
组复制自动重新加入尝试次数
组复制退出状态操作 终止服务器 只读
组复制成员驱逐超时时间

有关新增选项或变量的详细信息,请参阅《MySQL Server Version Reference》中的 《MySQL 8.0 的选项和变量更改》

以下各节介绍默认设置的更改以及这些更改可能对部署产生的任何影响。

服务器默认值

  • 系统变量character_set_server 以及命令行选项--character-set-server 的默认值从 latin1 改为了utf8mb4。这是服务器的默认字符集。目前,UTF8MB4 是网络上占主导地位的字符编码,这一更改让绝大多数 MySQL 用户使用起来更加轻松。从 5.7 升级到 8.0 不会改变任何现有数据库对象的字符集,但是,除非你显式设置character_set_server(设置回之前的值,或者设置为新值),否则新的模式默认使用 utf8mb4。我们建议你尽可能迁移到 utf8mb4
  • 系统变量collation_server和命令行参数--collation-server的默认值从latin1_swedish_ci更改为utf8mb4_0900_ai_ci。这是服务器的默认排序规则,即字符集内字符的排序方式。排序规则和字符集之间存在关联,因为每个字符集都有一组可能的排序规则。从5.7升级到8.0不会更改任何现有数据库对象的排序规则,但会对新对象生效。
  • 系统变量explicit_defaults_for_timestamp的默认值已从OFF(MySQL旧版行为)更改为ON(SQL标准行为)。此选项最初在5.6版本中引入,在5.6和5.7版本中为OFF
  • 系统变量optimizer_trace_max_mem_size的默认值从16KB更改为1MB。旧的默认值会导致优化器跟踪在处理任何非简单查询时被截断。此更改确保了大多数查询都能生成有用的优化器跟踪信息。
  • 系统变量validate_password_check_user_name的默认值已从OFF更改为ON。这意味着,当启用validate_password插件时,默认情况下,它现在会拒绝与当前会话用户名匹配的密码。
  • back_log系统变量的自动调整大小算法已更改。自动调整大小的值(-1)现在设置为max_connections的值,该值大于通过50 +(max_connections / 5)计算得出的值。back_log会在服务器无法跟上传入请求的情况下,将传入的IP连接请求排入队列。在最坏的情况下,例如网络故障后,max_connections数量的客户端尝试同时重新连接,它们都可以被缓冲,从而避免出现拒绝 - 重试循环。
  • 系统变量max_allowed_packet的默认值从4194304(4M)更改为67108864(64M)。采用这个更大的默认值的主要好处是,因插入或查询大于max_allowed_packet而报错的可能性降低。该值应与你想要使用的最大的 第13.3.4节,“BLOB和TEXT类型” 一样大。要恢复到之前的行为,请设置max_allowed_packet=4194304
  • 系统变量max_error_count的默认值从 64 更改为 1024。这确保 MySQL 能够处理更多数量的警告,例如一条 UPDATE 语句影响数千行数据且其中许多行都会产生转换警告的情况。许多工具通常会批量执行更新操作,以帮助减少复制延迟。诸如 pt-online-schema-change 之类的外部工具默认值为 1000,而 gh-ost 的默认值为 100。MySQL 8.0 涵盖了这两种用例的完整错误历史记录。由于不存在静态分配,因此此更改仅影响生成大量警告的语句的内存消耗。
  • 系统变量event_scheduler的默认值从OFF更改为ON。换句话说,事件调度器默认启用。这是SYS中新功能的启用条件,例如“终止空闲事务”。
  • 系统变量table_open_cache的默认值从 2000 更改为 4000。这是一项微小改动,能够提高表访问时的会话并发度。
  • 系统变量log_error_verbosity的默认值从 3(注意)改为 2(警告)。目的是让MySQL 8.0错误日志默认情况下不那么冗长。

InnoDB默认设置

  • 不兼容的更改 innodb_undo_tablespaces系统变量的默认值已从 0 更改为 2。该变量用于配置InnoDB使用的撤销表空间数量。在MySQL 8.0中,innodb_undo_tablespaces的最小值为2,并且回滚段不能再在系统表空间中创建。因此,在这种情况下,无法恢复到5.7版本的行为。此更改的目的是能够自动截断撤销日志(见下一项),回收(偶尔出现的)长时间运行的事务(如 mysqldump)所占用的磁盘空间。
  • 系统变量innodb_undo_log_truncate的默认值已从OFF更改为ON。启用时,超过由innodb_max_undo_log_size定义的阈值的撤销表空间将被标记为可截断。只有撤销表空间可以被截断。不支持截断驻留在系统表空间中的撤销日志。从5.7升级到8.0会自动将系统转换为使用撤销表空间,在8.0中不能选择使用系统表空间。
  • 在类Unix系统上,系统变量innodb_flush_method的默认值从NULL变更为fsync,在Windows系统上从NULL变更为unbuffered。这更多是术语和选项的清理,没有任何实际影响。对于Unix系统,这只是一个文档变更,因为在5.7版本中默认值也是fsync(默认值NULL表示fsync)。类似地,在Windows系统上,innodb_flush_method的默认值NULL在5.7版本中表示async_unbuffered,而在8.0版本中被默认值unbuffered取代,结合现有默认值innodb_use_native_aio=ON,其效果相同。
  • 不兼容的更改 innodb_autoinc_lock_mode系统变量的默认值从 1(连续)更改为 2(交错)。默认设置更改为交错锁定模式,反映了从基于语句的复制到基于行的复制的默认复制类型的更改,此更改发生在MySQL 5.7中。 基于语句的复制 需要连续自动递增锁定模式,以确保对于给定的SQL语句序列,以可预测且可重复的顺序分配自动递增的值,而 基于行的复制 对SQL语句的执行顺序不敏感。因此,已知此更改与基于语句的复制不兼容,并且可能会破坏某些依赖于顺序自动递增的应用程序或用户生成的测试套件。可以通过设置 innodb_autoinc_lock_mode=1; 恢复先前的默认设置。
  • 系统变量innodb_flush_neighbors的默认值从 1(启用)更改为 0(禁用)。这样做是因为快速I/O(固态硬盘)现在是部署的默认存储设备。我们预计,对于大多数用户来说,这会带来一些性能提升。使用较慢硬盘的用户可能会看到性能下降,建议这些用户通过设置innodb_flush_neighbors=1恢复到以前的默认值。
  • 系统变量innodb_max_dirty_pages_pct_lwm的默认值从 0(%) 更改为 10(%)。当 innodb_max_dirty_pages_pct_lwm=10 时,若缓冲池中有超过10% 的页面为已修改(“脏”)页面,InnoDB 会增加刷新活动。此更改的目的是略微牺牲峰值吞吐量,以换取更稳定的性能。
  • 系统变量innodb_max_dirty_pages_pct的默认值从 75(%)更改为 90(%)。此更改与 innodb_max_dirty_pages_pct_lwm 的更改相结合,共同确保 InnoDB 平稳的刷新行为,避免突发刷新。要恢复到以前的行为,请设置 innodb_max_dirty_pages_pct=75innodb_max_dirty_pages_pct_lwm=0

性能模式默认设置

  • 性能模式元数据锁定(MDL)检测默认开启。编译时默认的performance-schema-instrument='wait/lock/metadata/sql/%=ON'OFF改为了ON。这为在SYS中添加面向MDL的视图提供了支持。
  • 性能模式内存检测默认开启。编译时默认的performance-schema-instrument='memory/%=COUNTED'OFF改为了COUNTED。这一点很重要,因为如果在服务器启动后启用检测,统计结果会不正确,而且可能会因遗漏一次分配但捕捉到一次释放而得出负余额。
  • 性能模式事务检测默认开启。编译后的默认设置为:performance-schema-consumer-events-transactions-current=ONperformance-schema-consumer-events-transactions-history=ON,以及performance-schema-instrument='transaction%=ON',从 OFF 改为了ON

复制默认设置

  • 系统变量log_bin的默认值已从OFF更改为ON。换句话说,默认启用二进制日志记录。几乎所有生产环境安装都启用了二进制日志,因为它用于复制和时间点恢复。因此,默认启用二进制日志可省去一个配置步骤,而稍后启用则需要重启mysqld。默认启用二进制日志还能提供更好的测试覆盖范围,并且更容易发现性能衰退问题。请记住还要设置server_id(请参阅以下更改)。8.0版本的默认行为就如同执行了./mysqld --log-bin --server-id=1 。如果您使用的是8.0版本且希望保持5.7版本的行为,可以执行./mysqld --skip-log-bin<br /> --server-id=0
  • server_id系统变量的默认值从0更改为1(与log_bin=ON的更改相结合)。服务器可以使用此默认ID启动,但在实际应用中,您必须根据所部署的复制架构设置server-id,以避免出现重复的服务器ID。
  • 系统变量log-slave-updates的默认值从 OFF 更改为 ON。这会使副本将复制的事件记录到其自身的二进制日志中。此选项是组复制所必需的,并且还可确保在如今已成为标准配置的各种复制链设置中行为正确。
  • 系统变量expire_logs_days的默认值已从 0 更改为 30。新的默认值 30 会使 mysqld 定期清除超过 30 天未使用的二进制日志。此更改有助于防止过多磁盘空间浪费在不再用于复制或恢复目的的二进制日志上。旧值 0 会禁用任何自动二进制日志清除功能。
  • 系统变量master_info_repositoryrelay_log_info_repository的默认值从 FILE 更改为TABLE。因此,在 8.0 中,复制元数据默认存储在 InnoDB 中。这提高了可靠性,默认情况下尝试实现崩溃安全复制。
  • 系统变量transaction-write-set-extraction的默认值从 OFF 更改为 XXHASH64。此更改默认启用事务写集。通过使用事务写集,源需要多做一些工作来生成写集,但结果有助于冲突检测。这是组复制的一项要求,新的默认设置使得在源上轻松启用二进制日志写集并行化以加速复制。
  • 系统变量slave_rows_search_algorithms的默认值已从INDEX_SCAN,TABLE_SCAN更改为INDEX_SCAN,HASH_SCAN。这一更改减少了副本应用程序在对没有主键的表应用更改时必须执行的全表扫描次数,从而加快了基于行的复制。
  • 系统变量slave_pending_jobs_size_max的默认值从 16M 更改为128M。此更改增加了多线程副本可用的内存量。
  • gtid_executed_compression_period系统变量的默认值从1000更改为0。这一更改确保仅在需要时以隐式方式压缩mysql.gtid_executed表。

组复制默认值

这些默认设置大多对于开发和生产环境都相当适用。其中的一个例外是--innodb-dedicated-server选项,其默认值仍为 OFF,尽管我们建议在生产环境中设置为 ON。默认设置为 OFF 的原因是,它会导致开发人员笔记本电脑等共享环境无法使用,因为它会占用 所有 能找到的内存。

对于生产环境,我们建议使用--innodb-dedicated-server,该选项会根据可用内存确定以下 InnoDB 变量的值(如果未明确指定):innodb_buffer_pool_sizeinnodb_log_file_sizeinnodb_flush_method。请参阅第 17.8.12 节,“为专用 MySQL 服务器启用自动 InnoDB 配置”

尽管新的默认设置是大多数用例的最佳配置选择,但仍存在特殊情况,以及出于遗留原因而使用现有5.7配置选择的情况。例如,有些人希望在对其应用程序或操作环境进行尽可能少的更改的情况下升级到8.0。我们建议评估所有新的默认设置,并尽可能多地使用它们。大多数新的默认设置都可以在5.7中进行测试,因此您可以在升级到8.0之前,在5.7生产环境中验证这些新的默认设置。对于少数仍需使用5.7旧值的默认设置,可在操作环境中设置相应的配置变量或启动选项。

MySQL 8.0 有 Performance Schemavariables_info 表,该表展示了每个系统变量最近一次设置的来源,以及其取值范围。这提供了一种通过 SQL 来全面了解配置变量及其值的途径。

有效性能回归

预计MySQL 5.7和8.0版本之间会出现性能回归。MySQL 8.0具有更多功能,更改了默认值,更加稳健,并增加了安全功能和额外的诊断信息。此处列出了这些版本之间出现性能回归的合理原因,其中包括潜在的调解方案。这并非详尽无遗的列表。

MySQL 5.7和8.0版本间默认值更改相关的变动:

  • 二进制日志在5.7中默认禁用,在8.0中默认启用。

    中介:在启动时通过指定--skip-log-bin--disable-log-bin选项来禁用二进制日志记录。

  • 默认字符集在8.0版本中从latin1改为了utf8mb4。虽然utf8mb4在8.0版本中的性能比5.7版本有显著提升,但latin1的速度比utf8mb4更快。

    调解:如果在8.0版本中不需要utf8mb4,则使用latin1

事务性数据字典(原子性数据定义语言)于8.0版本引入。

  • 这以牺牲数据定义语言(DDL)性能(创建/删除密集型负载)为代价提高了稳健性/可靠性,但它不应影响数据操作语言(DML)负载(查询/插入/更新/删除)。

    解决方法:无

从5.7.28版本开始使用的更新的传输层安全(TLS)加密算法,在启用传输层安全(TLS)(默认设置)时会生效。

  • 在MySQL 5.7.28之前,MySQL社区版使用yaSSL库,企业版使用OpenSSL。

    从MySQL 5.7.28版本起,MySQL仅使用具有更强TLS加密算法的OpenSSL,这些加密算法在性能方面代价更高。

    从MySQL 5.7.28或更早版本升级到MySQL 8.0可能会导致TLS性能下降。

    缓解措施:无(如果出于安全原因需要TLS)

性能架构(PFS)检测在8.0版本中比5.7版本广泛得多:

  • 在MySQL 8.0中,性能模式(Performance Schema,PFS)无法被编译去除,但可以将其关闭。即使关闭后,某些性能模式检测工具仍会存在,但开销会更小。

    调解:在8.0版本中设置performance_schema = OFF,如果只需要部分而不是全部性能架构(Performance Schema,PFS)功能,则以更细粒度关闭性能架构检测。

在8.0版本中,默认启用截断撤销表空间功能,这可能会对性能产生显著影响:

  • 从历史上看,InnoDB 将撤销日志存储在系统表空间中,但无法回收撤销日志所占用的空间。系统表空间只会不断增长而不会收缩,这促使了相关功能需求的提出以解决这一问题。

    MySQL 8.0 将撤销日志移至单独的表空间,这使得可以手动和自动截断撤销日志。

    然而,自动截断会带来永久性的性能开销,并且可能会导致停顿。

    解决方法:在8.0版本中,将innodb_undo_log_truncate设置为OFF,并根据需要手动截断撤销日志。有关相关信息,请参阅截断撤销表空间

在MySQL 8.0中,字符类[[:alpha:]][[:digit:]] 在诸如REGEXP()RLIKE() 等正则表达式函数中的表现不如在MySQL 5.7中。这是因为在MySQL 8.0中,Spencer正则表达式库被ICU库取代,而ICU库在内部使用UTF - 16。

调解:用 [a-zA-Z] 代替 [[:alpha:]];用 [0-9] 代替 [[:digit:]]

3.6 为升级准备安装环境

在升级到最新的 MySQL 8.0 版本之前,请通过执行以下所述的初步检查,确保当前 MySQL 5.7 或 MySQL 8.0 服务器实例已做好升级准备。否则,升级过程可能会失败。

[!NOTE]

考虑使用MySQL Shell升级检查器实用程序,它使您能够验证MySQL服务器实例是否已准备好进行升级。您可以选择计划升级到的目标MySQL Server版本,范围从MySQL Server 8.0.11到与当前MySQL Shell版本号匹配的MySQL Server版本号。升级检查器实用程序会执行与指定目标版本相关的自动检查,并告知您应手动进行的其他相关检查。升级检查器适用于MySQL的所有Bug修复版、创新版和长期支持版(LTS)。MySQL Shell的安装说明可在此处找到。

初步检查:

  1. 以下问题一定不能出现:

    • 不得有使用过时数据类型或函数的表。

      如果表中包含采用 5.6.4 之前格式的旧时间列(TIMEDATETIME 以及不支持小数秒精度的 TIMESTAMP 列),则不支持就地升级到 MySQL 8.0。如果您的表仍使用旧的时间列格式,请在尝试就地升级到 MySQL 8.0 之前,使用 REPAIR TABLE 对其进行升级。有关更多信息,请参阅 服务器更改,位于 《MySQL 5.7 参考手册》 中。

    • 绝不能有孤立的 .frm 文件。

    • 触发器不能有缺失或为空的定义者,也不能有无效的创建上下文(由 character_set_clientcollation_connectionDatabase<br /> Collation 属性指示,可通过 SHOW TRIGGERSINFORMATION_SCHEMATRIGGERS 表查看)。任何此类触发器都必须转储并恢复以解决该问题。

    要检查这些问题,请执行此命令:

    mysqlcheck -u root -p --all-databases --check-upgrade
    

    如果 mysqlcheck 报告任何错误,请纠正这些问题。

  2. 不得存在使用不具备原生分区支持的存储引擎的分区表。要识别此类表,请执行以下查询:

    SELECT TABLE_SCHEMA, TABLE_NAME
    FROM INFORMATION_SCHEMA.TABLES
    WHERE ENGINE NOT IN ('innodb', 'ndbcluster')
    AND CREATE_OPTIONS LIKE '%partitioned%';
    

    查询所报告的任何表都必须进行修改,以使用InnoDB存储引擎或设置为非分区表。要将表存储引擎更改为InnoDB,请执行以下语句:

    ALTER TABLE table_name ENGINE = INNODB;
    

    有关将 MyISAM 表转换为 InnoDB 的信息,请参阅第 17.6.1.5 节,“将表从 MyISAM 转换为 InnoDB”

    要将分区表变为非分区表,请执行以下语句:

    ALTER TABLE table_name REMOVE PARTITIONING;
    
  3. 在MySQL 8.0中,某些关键字可能是之前版本未保留的保留字。请参见第11.3节“关键字和保留字”。这可能导致以前用作标识符的单词变为非法。要修复受影响的语句,请使用标识符引号。请参见第11.2节“模式对象名称”。

  4. MySQL 5.7的mysql系统数据库中,一定不能有与MySQL 8.0数据字典所使用的表同名的表。要识别具有这些名称的表,请执行此查询:

    SELECT TABLE_SCHEMA, TABLE_NAME
    FROM INFORMATION_SCHEMA.TABLES
    WHERE LOWER(TABLE_SCHEMA) = 'mysql'
    and LOWER(TABLE_NAME) IN
    (
    'catalogs',
    'character_sets',
    'check_constraints',
    'collations',
    'column_statistics',
    'column_type_elements',
    'columns',
    'dd_properties',
    'events',
    'foreign_key_column_usage',
    'foreign_keys',
    'index_column_usage',
    'index_partitions',
    'index_stats',
    'indexes',
    'parameter_type_elements',
    'parameters',
    'resource_groups',
    'routines',
    'schemata',
    'st_spatial_reference_systems',
    'table_partition_values',
    'table_partitions',
    'table_stats',
    'tables',
    'tablespace_files',
    'tablespaces',
    'triggers',
    'view_routine_usage',
    'view_table_usage'
    );
    

    查询所报告的任何表都必须删除或重命名(使用 RENAME TABLE)。这可能还需要对使用受影响表的应用程序进行更改。

  5. 不能有外键约束名长度超过64个字符的表。使用以下查询来识别约束名过长的表:

    SELECT TABLE_SCHEMA, TABLE_NAME
    FROM INFORMATION_SCHEMA.TABLES
    WHERE TABLE_NAME IN
      (SELECT LEFT(SUBSTR(ID,INSTR(ID,'/')+1),
                   INSTR(SUBSTR(ID,INSTR(ID,'/')+1),'_ibfk_')-1)
       FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN
       WHERE CHAR_LENGTH(SUBSTR(ID,INSTR(ID,'/')+1))>64);
    

    对于约束名称超过 64 个字符的表,请删除该约束,然后使用不超过 64 个字符的约束名称重新添加它(使用 ALTER TABLE)。

  6. sql_mode系统变量绝不能定义已过时的SQL模式。尝试使用已过时的SQL模式会导致MySQL 8.0无法启动。使用已过时SQL模式的应用程序应进行修订以避免使用它们。有关MySQL 8.0中移除的SQL模式的信息,请参见“服务器更改”。

  7. 仅升级已正常关闭的 MySQL 服务器实例。如果实例意外关闭,那么在升级之前,重启该实例并使用innodb_fast_shutdown=0将其关闭。

  8. 绝对不能存在显式定义的列名长度超过64个字符的视图(MySQL 5.7中允许列名长度至多为255个字符的视图)。为避免升级错误,应在升级前修改此类视图。目前,识别列名长度超过64个字符的视图的唯一方法是使用 SHOW CREATE VIEW 检查视图定义。您还可以通过查询信息架构的 VIEWS 表来检查视图定义。

  9. 不能有单个ENUMSET列元素的长度超过255个字符或1020字节的表或存储过程。在MySQL 8.0之前,ENUMSET列元素的最大组合长度为64K。在MySQL 8.0中,单个ENUMSET列元素的最大字符长度为255个字符,最大字节长度为1020字节。(1020字节的限制支持多字节字符集)。在升级到MySQL 8.0之前,请修改任何超过新限制的ENUMSET列元素。否则,升级将因错误而失败。

  10. 在升级到MySQL 8.0.13或更高版本之前,共享InnoDB表空间(包括系统表空间和常规表空间)中必须存在显著的分区。通过查询INFORMATION_SCHEMA来识别共享表空间中的表分区:

    如果从 MySQL 5.7 升级,请运行此查询:

    SELECT DISTINCT NAME, SPACE, SPACE_TYPE FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES
      WHERE NAME LIKE '%#P#%' AND SPACE_TYPE NOT LIKE 'Single';
    

    如果是从早期的 MySQL 8.0 版本进行升级,请运行此查询:

    SELECT DISTINCT NAME, SPACE, SPACE_TYPE FROM INFORMATION_SCHEMA.INNODB_TABLES
      WHERE NAME LIKE '%#P#%' AND SPACE_TYPE NOT LIKE 'Single';
    

    使用 [ALTER TABLE ... REORGANIZE PARTITION](https://dev.mysql.com/doc/refman/8.0/en/alter-table.html) 将表分区从共享表空间移动到每个表一个文件的表空间:

    ALTER TABLE table_name REORGANIZE PARTITION partition_name
      INTO (partition_definition TABLESPACE=innodb_file_per_table);
    
  11. 不得有来自 MySQL 8.0.12 或更低版本的查询和存储程序定义,这些查询和存储程序定义对GROUP<br /> BY 子句使用 ASCDESC 限定符。否则,升级到 MySQL 8.0.13 或更高版本可能会失败,复制到 MySQL 8.0.13 或更高版本的副本服务器也可能会失败。有关更多详细信息,请参阅 SQL更改

  12. 你的MySQL 5.7安装不得使用MySQL 8.0不支持的功能。这里的任何更改必然因安装而异,但以下示例说明了需要查找的内容:

    在MySQL 8.0中,一些服务器启动选项和系统变量已被移除。请参阅MySQL 8.0中移除的功能 以及第1.4节,“MySQL 8.0中新增、弃用或移除的服务器和状态变量及选项”。如果您使用了其中任何一项,升级时需要进行配置更改。

    示例:由于数据字典提供了有关数据库对象的信息,服务器不再检查数据目录中的目录名来查找数据库。因此,--ignore-db-dir选项已无关紧要,已被移除。要解决此问题,请从启动配置中删除所有--ignore-db-dir实例。此外,在升级到MySQL 8.0之前,请删除或移动指定的数据目录子目录。(或者,让8.0服务器将这些目录作为数据库添加到数据字典中,然后使用DROP DATABASE删除每个数据库。)

  13. 如果您打算在升级时将lower_case_table_names设置更改为1,请确保在升级前架构和表名均为小写。否则,可能会因架构或表名的字母大小写不匹配而导致失败。您可以使用以下查询来检查包含大写字符的架构和表名:

    mysql> select TABLE_NAME, if(sha(TABLE_NAME) !=sha(lower(TABLE_NAME)),'Yes','No') as UpperCase from information_schema.tables;
    

    从MySQL 8.0.19开始,如果lower_case_table_names=1,升级过程会检查表名和模式名,以确保所有字符均为小写。如果发现表名或模式名包含大写字符,升级过程将因错误而失败。

    注意

    不建议在升级时更改lower_case_table_names设置。

如果由于上述任何问题导致升级到MySQL 8.0失败,服务器将回滚对数据目录的所有更改。在这种情况下,请删除所有重做日志文件,并在现有数据目录上重新启动MySQL 5.7服务器以解决错误。默认情况下,重做日志文件(ib_logfile*)位于MySQL数据目录中。修复错误后,在再次尝试升级之前,执行缓慢关闭(通过设置innodb_fast_shutdown=0)。

3.7 在Unix/Linux上升级基于二进制文件或软件包的MySQL安装

本节介绍如何在Unix/Linux上升级基于MySQL二进制文件和软件包的安装。同时介绍了就地升级和逻辑升级方法。

原地升级

就地升级包括关闭旧的MySQL服务器,用新的MySQL二进制文件或软件包替换旧的,在现有数据目录上重新启动MySQL,以及升级现有安装中任何需要升级的其余部分。有关可能需要升级的内容的详细信息,请参阅3.4节,“MySQL升级过程升级的内容”

[!CAUTION]

如果您要升级最初通过安装多个RPM软件包生成的安装,请升级所有软件包,而不是只升级部分软件包。例如,如果您之前安装了服务器和客户端RPM软件包,请勿仅升级服务器RPM软件包。

对于某些Linux平台,通过RPM或Debian软件包安装MySQL时,会包含对systemd的支持,用于管理MySQL服务器的启动和关闭。在这些平台上,不会安装mysqld_safe。在这种情况下,应使用systemd来启动和关闭服务器,而不是使用以下说明中的方法。请参阅2.5.9节,“使用systemd管理MySQL服务器”

对于升级MySQL集群安装,另请参阅MySQL集群升级

要执行就地升级:

  1. 查看3.1节“开始之前”中的信息。

  2. 通过完成第 3.6 节“为升级准备安装”中的初步检查,确保您的安装已做好升级准备。

  3. 如果使用带有 InnoDB 的 XA 事务,在升级前运行 XA RECOVER 以检查未提交的 XA 事务。如果返回结果,可通过发出 XA COMMITXA ROLLBACK 语句来提交或回滚 XA 事务。

  4. 如果您要从MySQL 5.7.11或更早版本升级到MySQL 8.0,并且存在加密的InnoDB表空间,请通过执行以下语句轮换密钥环主密钥:

    ALTER INSTANCE ROTATE INNODB MASTER KEY;
    
  5. 如果您通常运行的MySQL服务器配置为将innodb_fast_shutdown设置为2(冷关机),则通过执行以下语句之一,将其配置为执行快速或慢速关机:

    SET GLOBAL innodb_fast_shutdown = 1; -- fast shutdown
    SET GLOBAL innodb_fast_shutdown = 0; -- slow shutdown
    

    无论是快速关闭还是慢速关闭,InnoDB 都会将其撤销日志和数据文件保留在一种状态,以便在不同版本之间出现文件格式差异时能够进行处理。

  6. 关闭旧的MySQL服务器。例如:

    mysqladmin -u root -p shutdown
    
  7. 升级MySQL二进制文件或软件包。如果是升级二进制安装,请解压新的MySQL二进制发行版软件包。请参阅获取和解压发行版。对于基于软件包的安装,请安装新的软件包。

  8. 使用现有的数据目录启动MySQL 8.0服务器。例如:

    mysqld_safe --user=mysql --datadir=/path/to/existing-datadir &
    

    如果存在加密的 InnoDB 表空间,请使用 --early-plugin-load 选项加载密钥环插件。

    当启动MySQL 8.0服务器时,它会自动检测数据字典表是否存在。如果不存在,服务器会在数据目录中创建这些表,用元数据填充它们,然后继续其正常的启动序列。在此过程中,服务器会升级所有数据库对象的元数据,包括数据库、表空间、系统表和用户表、视图以及存储程序(存储过程和函数、触发器以及事件调度器事件)。服务器还会删除以前用于元数据存储的文件。例如,从MySQL 5.7升级到MySQL 8.0后,您可能会注意到表不再有.frm文件。

    如果此步骤失败,服务器将回滚对数据目录所做的所有更改。在这种情况下,您应删除所有重做日志文件,在同一数据目录上启动MySQL 5.7服务器,并修复任何错误的原因。然后再次缓慢关闭5.7服务器,并启动MySQL 8.0服务器再次尝试。

  9. 在上一步中,服务器根据需要升级数据字典。现在有必要执行任何剩余的升级操作:

    • 从 MySQL 8.0.16 开始,服务器会在上一步骤中完成此项操作,在 MySQL 5.7 与 MySQL 8.0 之间对mysql 系统数据库进行必要的更改,以便你能够利用新的权限或功能。它还会将 Performance Schema、INFORMATION_SCHEMA 以及 sys 数据库更新到适用于 MySQL 8.0 的版本,并检查所有用户数据库与当前 MySQL 版本是否存在不兼容问题。

    • 在MySQL 8.0.16之前,服务器仅在前一步升级数据字典。MySQL 8.0服务器成功启动后,执行mysql_upgrade以执行其余升级任务:

      mysql_upgrade -u root -p
      

      然后关闭并重启MySQL服务器,以确保对系统表所做的任何更改生效。例如:

      mysqladmin -u root -p shutdown
      mysqld_safe --user=mysql --datadir=/path/to/existing-datadir &
      

      第一次启动 MySQL 8.0 服务器(在前面的步骤中)时,你可能会在错误日志中注意到有关未升级表的消息。如果已成功运行mysql_upgrade,那么第二次启动服务器时,应该不会再有此类消息。

[!CAUTION]

升级过程不会升级时区表的内容。有关升级说明,请参阅7.1.15节,“MySQL服务器时区支持”

如果升级过程使用 mysql_upgrade(即 MySQL 8.0.16 之前的版本),该过程也不会升级帮助表的内容。有关这种情况下的升级说明,请参阅7.1.17 节,“服务器端帮助支持”

逻辑升级

逻辑升级包括使用备份或导出实用程序(如 mysqldumpmysqlpump)从旧的 MySQL 实例导出 SQL,安装新的 MySQL 服务器,并将 SQL 应用到新的 MySQL 实例。有关可能需要升级的详细信息,请参阅 3.4 节,“MySQL 升级过程升级的内容”

注意

[!CAUTION]

对于某些Linux平台,通过RPM或Debian软件包安装MySQL时,会包含对systemd的支持,用于管理MySQL服务器的启动和关闭。在这些平台上,不会安装mysqld_safe。在这种情况下,应使用systemd来启动和关闭服务器,而不是使用以下说明中的方法。请参阅2.5.9节,“使用systemd管理MySQL服务器”

警告

[!WARNING]

将从旧版MySQL版本提取的SQL应用于新版MySQL版本时,由于新特性、已更改特性、已弃用特性或已移除特性及功能所引入的不兼容性,可能会导致错误。因此,从旧版MySQL版本提取的SQL可能需要修改,以实现逻辑升级。

要在升级到最新的 MySQL 8.0 版本之前识别不兼容性,请执行3.6 节“为升级准备安装”中所述的步骤。

要执行逻辑升级:

  1. 查看3.1节“开始之前”中的信息。

  2. 从之前安装的MySQL中导出现有数据:

    mysqldump -u root -p
      --add-drop-table --routines --events
      --all-databases --force > data-for-upgrade.sql
    

    注意

    [!CAUTION]

    如果你的数据库包含存储程序,请使用--routines--events选项与mysqldump配合使用(如上所示)。--all-databases选项会在转储中包含所有数据库,包括保存系统表的mysql数据库。

    重要事项

    [!IMPORTANT]

    如果你的表包含生成列,请使用MySQL 5.7.9或更高版本提供的mysqldump实用程序来创建转储文件。早期版本中提供的mysqldump实用程序在生成列定义时使用了错误的语法(错误编号20769542)。你可以使用信息架构中的COLUMNS表来识别包含生成列的表。

  3. 关闭旧的MySQL服务器。例如:

    mysqladmin -u root -p shutdown
    
  4. 安装MySQL 8.0。有关安装说明,请参阅第2章,安装MySQL

  5. 按照2.9.1节“初始化数据目录”中的描述,初始化一个新的数据目录。例如:

    mysqld --initialize --datadir=/path/to/8.0-datadir
    

    复制显示在屏幕上或写入错误日志的临时'root'@'localhost'密码,以备后用。

  6. 使用新的数据目录启动MySQL 8.0服务器。例如:

    mysqld_safe --user=mysql --datadir=/path/to/8.0-datadir &
    
  7. 重置root密码:

    $> mysql -u root -p
    Enter password: ****  <- enter temporary root password
    
    mysql> ALTER USER USER() IDENTIFIED BY 'your new password';
    
  8. 将之前创建的转储文件加载到新的MySQL服务器中。例如:

    mysql -u root -p --force < data-for-upgrade.sql
    

    注意

    [!CAUTION]

    如果转储文件包含系统表,则不建议在服务器上启用GTID(gtid_mode=ON)时加载转储文件。mysqldump 会为使用非事务性MyISAM存储引擎的系统表发出DML指令,而在启用GTID时不允许这种组合。另外要注意,将启用GTID的服务器上的转储文件加载到另一台启用GTID的服务器上,会生成不同的事务标识符。

  9. 执行任何剩余的升级操作:

    • 在MySQL 8.0.16及更高版本中,关闭服务器,然后使用--upgrade=FORCE选项重新启动服务器,以执行其余的升级任务:

      mysqladmin -u root -p shutdown
      mysqld_safe --user=mysql --datadir=/path/to/8.0-datadir --upgrade=FORCE &
      

      使用--upgrade=FORCE重新启动后,服务器会对MySQL 5.7与MySQL 8.0之间的mysql系统模式进行所有必要的更改,以便您能够利用新的权限或功能。它还会将性能模式、INFORMATION_SCHEMAsys模式更新到适用于MySQL 8.0的最新状态,并检查所有用户模式与当前MySQL版本之间是否存在不兼容问题。

    • 在 MySQL 8.0.16 之前,执行 mysql_upgrade 来完成其余的升级任务:

      mysql_upgrade -u root -p
      

      然后关闭并重启MySQL服务器,以确保对系统表所做的任何更改生效。例如:

      mysqladmin -u root -p shutdown
      mysqld_safe --user=mysql --datadir=/path/to/8.0-datadir &
      

注意

[!CAUTION]

升级过程不会升级时区表的内容。有关升级说明,请参阅7.1.15节,“MySQL服务器时区支持”

如果升级过程使用mysql_upgrade(即 MySQL 8.0.16 之前的版本),该过程也不会升级帮助表的内容。有关这种情况下的升级说明,请参阅7.1.17节,“服务器端帮助支持”

注意

[!CAUTION]

正在加载包含MySQL 5.7 mysql 模式的转储文件时,会重新创建两个不再使用的表:eventproc。(对应的MySQL 8.0表是 eventsroutines,这两个表都是数据字典表,受到保护。)确认升级成功后,可以通过执行以下SQL语句删除 eventproc 表:

DROP TABLE mysql.event;
DROP TABLE mysql.proc;

MySQL 集群升级

本节中的信息是对 就地升级 中所述就地升级过程的补充,供升级 MySQL 集群时使用。

从MySQL 8.0.16版本起,MySQL集群升级可以按常规滚动升级方式进行,遵循常见的三个有序步骤:

  1. 升级管理节点。
  2. 一次升级一个数据节点。
  3. 一次升级一个API节点(包括MySQL服务器)。

每个节点的升级方式与MySQL 8.0.16之前几乎相同,因为数据字典升级和系统表升级是分开的。升级每个单独的mysqld 有两个步骤:

  1. 导入数据字典。

    使用--upgrade=MINIMAL选项启动新服务器,以升级数据字典,但不升级系统表。这本质上与MySQL 8.0.16之前启动服务器且不调用mysql_upgrade的操作相同。

    要完成此阶段,MySQL服务器必须连接到 NDB。如果存在任何 NDBNDBINFO 表,且服务器无法连接到集群,则会退出并显示错误消息:

    Failed to Populate DD tables.
    
  2. 升级系统表。

    在 MySQL 8.0.16 之前,数据库管理员会调用mysql_upgrade 客户端来升级系统表。从 MySQL 8.0.16 起,服务器执行此操作:要升级系统表,请在不使用--upgrade=MINIMAL 选项的情况下,重启每个单独的 mysqld

3.8 使用MySQL Yum仓库升级MySQL

对于受支持的基于Yum的平台(有关列表,请参阅2.5.1节,“使用MySQL Yum存储库在Linux上安装MySQL”),你可以使用MySQL Yum存储库对MySQL进行就地升级(即替换旧版本,然后使用旧数据文件运行新版本)。

注意事项

  1. 选择目标系列

    默认情况下,MySQL Yum 仓库会在安装期间将 MySQL 更新到你所选发行系列中的最新版本(详情请参阅选择发行系列),这意味着,例如,5.7.x 版本的安装不会自动更新到 8.0.x 版本。要更新到另一个发行系列,你必须首先禁用(默认或你自行选择的)已选系列的子仓库,并启用目标系列的子仓库。要执行此操作,请参阅选择发行系列中的通用说明。要从 MySQL 5.7 升级到 8.0,请执行与选择发行系列中所示步骤相反的操作,即禁用 MySQL 5.7 系列的子仓库并启用 MySQL 8.0 系列的子仓库。

    一般来说,要从一个发行版本系列升级到另一个发行版本系列,应升级到下一个系列,而不是跳过一个系列。例如,如果您当前正在运行MySQL 5.6,并且希望升级到8.0,那么在升级到8.0之前,请先升级到MySQL 5.7。

    重要提示

    有关从 MySQL5.7 升级到 8.0 的重要信息,请参阅从 MySQL 5.7 升级到 8.0

  2. 升级MySQL

    对于不支持dnf的平台,可通过以下命令升级MySQL及其组件:

    sudo yum update mysql-server
    

    对于支持dnf的平台:

    sudo dnf upgrade mysql-server
    

    或者,你可以通过让Yum更新系统上的所有内容来更新MySQL,这可能会花费更多时间。对于不支持dnf的平台:

    sudo yum update
    

    对于支持dnf的平台:

    sudo dnf upgrade
    
  3. 正在重启MySQL

    使用Yum更新后,MySQL服务器总会重启。在MySQL 8.0.16之前,服务器重启后运行mysql_upgrade,检查并可能解决旧数据与升级后的软件之间的任何不兼容问题。mysql_upgrade还执行其他功能;详情请参阅6.4.5节,“mysql_upgrade — 检查并升级MySQL表”。从MySQL 8.0.16开始,不再需要此步骤,因为服务器会执行以前由mysql_upgrade处理的所有任务。

你也可以仅更新特定组件。使用以下命令列出MySQL组件的所有已安装包(对于启用了dnf的系统,将命令中的yum替换为dnf):

sudo yum list installed | grep "^mysql"

确定您所选组件的包名后,使用以下命令更新该包,将 package-name 替换为实际的包名。对于不支持dnf的平台:

sudo yum update package-name

对于支持dnf的平台:

sudo dnf upgrade package-name

升级共享客户端库

使用Yum存储库更新MySQL后,使用旧版本共享客户端库编译的应用程序应该仍能继续运行。

如果重新编译应用程序并将其与更新后的库进行动态链接: 对于共享库的新版本,通常会在新旧库之间的符号版本控制方面存在差异或新增内容(例如,在较新的标准8.0共享客户端库与Linux发行版软件仓库或其他来源本地提供的某些旧版本(先前版本或变体版本)的共享库之间)。使用更新后的较新共享库编译的任何应用程序,在部署这些应用程序的系统上都需要这些更新后的库。不出所料,如果这些库不存在,需要共享库的应用程序将无法运行。因此,请务必在这些系统上部署MySQL共享库的软件包。要执行此操作,需将MySQL Yum仓库添加到系统中(请参阅 添加MySQL Yum仓库),并按照 使用Yum安装其他MySQL产品和组件 中的说明安装最新的共享库。

3.9 使用MySQL APT仓库升级MySQL

在Debian和Ubuntu平台上,要对MySQL及其组件执行就地升级,请使用MySQL APT仓库。请参阅《使用MySQL APT仓库快速指南》中的“使用MySQL APT仓库升级MySQL”。

3.10 使用MySQL SLES仓库升级MySQL

在SUSE Linux企业服务器(SLES)平台上,要对MySQL及其组件执行就地升级,请使用MySQL SLES存储库。请参阅《使用MySQL SLES存储库快速指南》中的“使用MySQL SLES存储库升级MySQL”。

3.11 在 Windows 上升级 MySQL

在Windows上升级MySQL有两种方法:

你选择的方法取决于现有安装的执行方式。在继续操作之前,请查看第 3 章“升级 MySQL”,以获取有关升级 MySQL(非特定于 Windows)的更多信息。

注意

无论选择哪种方法,在执行升级之前,请务必备份当前的MySQL安装。请参阅9.2节,“数据库备份方法”

不支持非通用可用性(GA)版本之间的升级(或从非GA版本升级到GA版本)。非GA版本中会进行重大开发变更,您可能会遇到兼容性问题或服务器启动问题。

注意

MySQL安装程序不支持社区版发行版和商业版发行版之间的升级。如果您需要这种类型的升级,请使用ZIP存档方法进行升级。

使用MySQL安装程序升级MySQL

当当前服务器安装是通过MySQL安装程序进行的,并且升级在当前发行系列内时,使用MySQL安装程序执行升级是最佳方法。MySQL安装程序不支持发行系列之间的升级,例如从5.7到8.0,并且它不提供升级指示来提示您进行升级。有关发行系列之间升级的说明,请参阅使用Windows ZIP分发版升级MySQL

要使用 MySQL 安装程序执行升级:

  1. 启动MySQL安装程序。

  2. 从仪表板中,点击“目录”以下载目录的最新更改。仅当仪表板在服务器版本号旁显示一个箭头时,才能升级已安装的服务器。

  3. 点击“升级”。所有有新版本的产品现在都会显示在列表中。

    注意

    MySQL安装程序会取消选择同一版本系列中里程碑版本(预发布版本)的服务器升级选项。此外,它会显示一条警告,表明不支持该升级,指出继续升级的风险,并提供手动执行升级的步骤摘要。您可以重新选择服务器升级并自行承担风险。

  4. 除非您打算此时升级其他产品,否则取消选择除MySQL服务器产品之外的所有产品,然后单击“下一步”。

  5. 点击“执行”开始下载。下载完成后,点击“下一步”开始升级操作。

    升级到 MySQL 8.0.16 及更高版本时,可能会显示一个选项,用于跳过系统表的升级检查和处理。有关此选项的更多信息,请参阅重要的服务器升级条件

  6. 配置服务器。

使用Windows ZIP压缩包分发版升级MySQL

要使用Windows ZIP存档发行版执行升级:

  1. https://dev.mysql.com/downloads/ 下载最新的 MySQL Windows ZIP 归档发行版。

  2. 如果服务器正在运行,请将其停止。如果服务器作为服务安装,请从命令提示符处使用以下命令停止该服务:

    C:\> SC STOP mysqld_service_name
    

    或者,使用 NET STOP*mysqld_service_name*

    如果未将MySQL服务器作为服务运行,请使用mysqladmin将其停止。例如,从MySQL 5.7升级到8.0之前,按如下方式使用MySQL 5.7的mysqladmin

    C:\> "C:\Program Files\MySQL\MySQL Server 5.7\bin\mysqladmin" -u root shutdown
    

    注意

    如果MySQL的root用户账户设有密码,可使用-p选项调用mysqladmin,并在提示时输入密码。

  3. 解压ZIP归档文件。你可以覆盖现有的MySQL安装(通常位于C:\mysql),也可以将其安装到其他目录,例如C:\mysql8。建议覆盖现有安装。

  4. 重新启动服务器。例如,如果将MySQL作为服务运行,请使用 SC START*mysqld_service_name*NET START*mysqld_service_name* 命令,否则直接调用 mysqld

  5. 在 MySQL 8.0.16 之前,需以管理员身份运行 mysql_upgrade 来检查表,必要时尝试修复,并在授权表发生变化时进行更新,以便利用新功能。请参阅 6.4.5 节,“mysql_upgrade — 检查并升级 MySQL 表”。从 MySQL 8.0.16 开始,此步骤不再必要,因为服务器会执行以前由 mysql_upgrade 处理的所有任务。

  6. 如果遇到错误,请参阅2.3.5节“Microsoft Windows 上MySQL 服务器安装故障排除”

3.12 升级MySQL的Docker安装版本

要升级MySQL的Docker安装,请参阅升级MySQL服务器容器

3.13 升级故障排除

  • 在MySQL 5.7实例中,表的.frm文件与InnoDB数据字典之间的模式不匹配,可能会导致升级到MySQL 8.0失败。这种不匹配可能是由于.frm文件损坏造成的。要解决此问题,在再次尝试升级之前,转储并恢复受影响的表。
  • 如果出现问题,例如新的mysqld服务器无法启动,请确认你没有之前安装留下的旧的 my.cnf 文件。你可以使用--print-defaults选项来检查(例如,mysqld --print-defaults)。如果此命令显示的内容不只是程序名称,那么你有一个正在生效的 my.cnf 文件,它会影响服务器或客户端的操作。
  • 如果升级后,编译的客户端程序出现问题,例如Commands out of<br /> sync或意外的核心转储,那么在编译程序时,您可能使用了旧的头文件或库文件。在这种情况下,请检查mysql.h文件和libmysqlclient.a库的日期,以确认它们来自新的MySQL发行版。如果不是,请使用新的头文件和库重新编译程序。如果共享客户端库的主版本号发生了变化(例如,从libmysqlclient.so.20变为libmysqlclient.so.21),针对共享客户端库编译的程序可能也需要重新编译。
  • 如果已创建了一个给定名称的可加载函数,并且将 MySQL 升级到实现了一个同名新内置函数的版本,则该可加载函数将无法访问。要解决此问题,请使用 DROP FUNCTION 删除可加载函数,然后使用 CREATE FUNCTION 以一个不同的、无冲突的名称重新创建该可加载函数。如果新版本的 MySQL 实现了一个与现有存储函数同名的内置函数,情况也是如此。有关描述服务器如何解释对不同类型函数的引用的规则,请参见 11.2.5 节,“函数名解析和解决”
  • 如果由于3.6节“为升级准备安装”中所述的任何问题导致升级到MySQL 8.0失败,服务器将撤消对数据目录的所有更改。在这种情况下,删除所有重做日志文件,并在现有数据目录上重新启动MySQL 5.7服务器以解决错误。重做日志文件(ib_logfile*)默认位于MySQL数据目录中。修复错误后,在再次尝试升级之前,执行慢速关闭(通过设置innodb_fast_shutdown=0)。

3.14 重建或修复表或索引

本节介绍如何重新构建或修复表或索引,出现以下情况时可能需要执行这些操作:

  • MySQL处理数据类型或字符集方式的变更。例如,校对规则中的错误可能已得到纠正,这就需要重建表以更新使用该校对规则的字符列的索引。
  • CHECK TABLEmysqlcheckmysql_upgrade 报告的所需表修复或升级。

重建表的方法包括:

转储并重新加载方法

如果由于二进制(原地)升级或降级后,不同版本的MySQL无法处理表而需要重建表,则必须使用转储并重新加载的方法。在升级或降级之前,使用原始版本的MySQL转储表。然后在升级或降级之后重新加载表。

如果仅为重建索引而使用转储并重新加载的方法来重建表,那么可以在升级或降级之前或之后执行转储操作。但重新加载操作仍必须在之后进行。

如果由于 CHECK TABLE 操作表明需要对表进行升级而需要重建 InnoDB 表,请使用 mysqldump 创建转储文件,并使用 mysql 重新加载该文件。如果 CHECK TABLE 操作表明存在损坏或导致 InnoDB 失败,请参阅第 17.21.3 节“强制 InnoDB 恢复”,了解有关使用 innodb_force_recovery 选项重新启动 InnoDB 的信息。要了解 CHECK TABLE 可能遇到的问题类型,请参阅第 15.7.3.2 节“CHECK TABLE 语句”中的 InnoDB 说明。

要通过转储和重新加载来重建表,请使用mysqldump创建转储文件,并使用mysql重新加载该文件:

mysqldump db_name t1 > dump.sql
mysql db_name < dump.sql

要重建单个数据库中的所有表,请指定数据库名称,后面无需跟表名:

mysqldump db_name > dump.sql
mysql db_name < dump.sql

要重建所有数据库中的所有表,请使用--all-databases选项:

mysqldump --all-databases > dump.sql
mysql < dump.sql

修改表结构方法

要使用 ALTER TABLE 重建表,请使用“空”修改;也就是说,使用一个 ALTER TABLE 语句,将表“更改”为使用其已有的存储引擎。例如,如果 t1 是一个 InnoDB 表,请使用以下语句:

ALTER TABLE t1 ENGINE = InnoDB;

如果不确定在 ALTER TABLE 语句中指定哪个存储引擎,请使用 SHOW CREATE TABLE 来显示表定义。

修复表方法

REPAIR TABLE 方法仅适用于 MyISAMARCHIVECSV 表。

如果表检查操作表明存在损坏或需要升级,则可以使用 REPAIR TABLE。例如,要修复 MyISAM 表,请使用以下语句:

REPAIR TABLE t1;

mysqlcheck --repair 提供了对 REPAIR TABLE 语句的命令行访问。这可能是一种更方便的修复表的方法,因为你可以分别使用 --databases--all-databases 选项来修复特定数据库或所有数据库中的所有表:

mysqlcheck --repair --databases db_name ...
mysqlcheck --repair --all-databases

3.15 将MySQL数据库复制到另一台机器

在需要在不同架构之间传输数据库的情况下,你可以使用 mysqldump 创建一个包含SQL语句的文件。然后,你可以将该文件传输到另一台机器上,并将其作为输入提供给 mysql 客户端。

使用 mysqldump --help 查看有哪些可用选项。

注意

[!CAUTION]

如果在创建转储的服务器上使用了GTID(gtid_mode=ON),默认情况下,mysqldump 会在转储中包含gtid_executed 集合的内容,以便将这些内容传输到新机器上。其结果可能会因涉及的MySQL Server版本而异。查看 mysqldump的--set-gtid-purged 选项说明,了解使用的版本会有什么情况发生,以及如果默认行为的结果不适合您的情况,如何更改该行为。

在两台机器之间迁移数据库最简单(尽管不是最快)的方法是在数据库所在的机器上运行以下命令:

mysqladmin -h 'other_hostname' create db_name
mysqldump db_name | mysql -h 'other_hostname' db_name

如果你想通过慢速网络从远程机器复制数据库,可以使用以下命令:

mysqladmin create db_name
mysqldump -h 'other_hostname' --compress db_name | mysql db_name

你也可以将转储存储在文件中,将文件传输到目标机器,然后将文件加载到那里的数据库中。例如,你可以在源机器上像这样将数据库转储到压缩文件中:

mysqldump --quick db_name | gzip > db_name.gz

将包含数据库内容的文件传输到目标机器,并在那里运行以下命令:

mysqladmin create db_name
gunzip < db_name.gz | mysql db_name

你还可以使用 mysqldumpmysqlimport 来传输数据库。对于大表,这比单纯使用 mysqldump 要快得多。在以下命令中,DUMPDIR 表示用于存储 mysqldump 输出内容的目录的完整路径名。

首先,创建用于存放输出文件的目录并转储数据库:

mkdir DUMPDIR
mysqldump --tab=DUMPDIR
   db_name

然后将DUMPDIR目录中的文件传输到目标机器上的相应目录,并在那里将文件加载到MySQL中:

mysqladmin create db_name           # create database
cat DUMPDIR/*.sql | mysql db_name   # create tables in database
mysqlimport db_name
   DUMPDIR/*.txt   # load data into tables

不要忘记复制mysql数据库,因为授权表就存储在那里。在新机器上,你可能需要以MySQL root用户身份运行命令,直到你将mysql数据库安装到位。

在新机器上导入mysql数据库后,执行mysqladmin flush - privileges,以便服务器重新加载授权表信息。

posted @ 2025-09-13 10:15  Samchensir  阅读(27)  评论(0)    收藏  举报