MySQL8.0新增功能

本文总结了已添加到,已弃用和从MySQL 8.0中删除的内容。伴随的章节列出了在MySQL 8.0中已添加,不建议使用或删除的MySQL服务选项和变量。请参见 “在MySQL 8.0中添加,不建议使用或删除的服务器和状态变量及选项”

MySQL 8.0中添加的功能

以下功能已添加到MySQL 8.0:

  • 数据字典。 MySQL现在合并了一个事务性数据字典,用于存储有关数据库对象的信息。在以前的MySQL版本中,字典数据存储在元数据文件和非事务表中。有关更多信息,请参见MySQL数据字典

  • 原子数据定义语句(Atomic DDL)。 原子DDL语句将数据字典更新,存储引擎操作以及与DDL操作关联的二进制日志写入操作组合到单个原子事务中。有关更多信息,请参见 “原子数据定义语句支持”

  • 升级程序。 以前,在安装新版本的MySQL之后,MySQL服务会在下次启动时自动升级数据字典表,此后,DBA有望 手动调用mysql_upgrade来升级mysql模式中的系统表 以及其他模式中的对象。例如sys模式和用户模式。

    从MySQL 8.0.16开始,服务执行以前由mysql_upgrade处理的任务。在安装新的MySQL版本之后,服务将在下次启动时自动执行所有必要的升级任务,而不依赖于DBA调用 mysql_upgrade。另外,服务同时更新帮助表的内容( mysql_upgrade没做的事情)。新的 --upgrade服务选项可控制服务如何执行自动数据字典和服务器升级操作。有关更多信息,请参见 “ MySQL升级过程将升级什么”

  • 安全性和帐户管理。 添加了这些增强功能,以提高安全性并在帐户管理中提供更大的DBA灵活性:

    • 现在 ,mysql系统数据库中的授权表是InnoDB (事务性)表。以前,这些是 MyISAM(非事务性)表。授权表存储引擎的更改会引起帐户管理语句行为的伴随更改。以前,帐户管理语句(例如 CREATE USERDROP USER),命名多个用户可以对某些用户成功,而对其他用户则失败。现在,每个语句都是事务性的,并且对于所有指定的用户都成功,或者回滚,如果发生任何错误,则无效。如果成功,则将语句写入二进制日志;如果失败,则不写入语句。在这种情况下,将发生回滚并且不进行任何更改。有关更多信息,请参见“原子数据定义语句支持”

    • 一个新的caching_sha2_password 身份验证插件已可用。像sha256_password插件一样 , caching_sha2_password实现SHA-256密码哈希,但是使用缓存来解决连接时的延迟问题。它还支持更多的连接协议,并且不需要针对基于RSA密钥对的密码交换功能而针对OpenSSL进行链接。请参见 “缓存SHA-2可插拔身份验证”

      caching_sha2_passwordsha256_password认证插件提供比mysql_native_password更安全的密码加密 插件,并 且caching_sha2_password提供了比sha256_password更好的性能。由于caching_sha2_password的这些优越的安全性和性能特征 ,它现在是首选的身份验证插件,并且也是默认的身份验证插件,而不是 mysql_native_password。有关此默认插件更改对服务器操作以及服务器与客户端和连接器的兼容性的影响的信息,请参阅 caching_sha2_password作为首选身份验证插件

    • MySQL现在支持角色,这些角色被称为特权集合。可以创建和删除角色。角色可以具有授予和撤销的特权。可以向用户帐户授予角色或从用户帐户撤消角色。可以从授予该帐户的角色中选择该帐户的活动适用角色,并且可以在该帐户的会话期间进行更改。有关更多信息,请参见“使用角色”

    • MySQL现在合并了用户帐户类别的概念,根据系统用户和普通用户是否具有SYSTEM_USER特权来区分它们 。请参见“帐户类别”

    • 以前,除了某些模式之外,不可能授予全局适用的特权。现在,如果启用了 partial_revokes系统变量,则可以这样做。请参见 “使用部分撤销的权限限制”

    • GRANT语句有一个AS user[WITH ROLE]子句,用于指定有关用于语句执行的特权上下文的其他信息。尽管此语法在SQL级别上可见,但其主要目的是通过使这些限制出现在二进制日志中,从而在由部分吊销施加的授予者特权限制的所有节点之间实现统一复制。请参见 “ GRANT语句”

    • MySQL现在维护有关密码历史记录的信息,从而可以限制重复使用以前的密码。DBA可能要求在一定数量的密码更改或一段时间内,不要从以前的密码中选择新密码。可以在全局范围内以及每个帐户基础上建立密码重用策略。

      现在可以要求通过指定要替换的当前密码来验证更改帐户密码的尝试。这使DBA可以防止用户在不证明他们知道当前密码的情况下更改密码。可以在全局范围内以及每个帐户基础上建立密码验证策略。

      现在允许帐户具有双重密码,这使得在复杂的多服务器系统中无缝执行阶段性密码更改而无需停机。

      MySQL现在使管理员能够配置用户帐户,以使由于密码错误而导致的连续登录失败过多,从而导致临时帐户锁定。每个帐户可以配置所需的失败次数和锁定时间。

      这些新功能使DBA可以更全面地控制密码管理。有关更多信息,请参见“密码管理”

    • 如果使用OpenSSL进行编译,MySQL现在支持FIPS模式,并且在运行时可以使用OpenSSL库和FIPS对象模块。FIPS模式对加密操作施加了条件,例如对可接受的加密算法的限制或对更长密钥长度的要求。请参见“ FIPS支持”

    • 服务用于新连接的TLS上下文现在可以在运行时重新配置。例如,此功能可能很有用,可避免重新启动一直运行已久的MySQL服务器(其SSL证书已过期)。请参阅 服务器端运行时配置和监视加密连接

    • 如果服务器和客户端均使用OpenSSL 1.1.1或更高版本进行编译,则OpenSSL 1.1.1支持TLS v1.3协议进行加密连接,而MySQL 8.0.16和更高版本也支持TLS v1.3。请参见 “加密的连接TLS协议和密码”

    • 现在,MySQL将授予命名管道上的客户端的访问控制设置为在Windows上成功进行通信所需的最低要求。较新的MySQL客户端软件无需任何其他配置即可打开命名管道连接。如果不能立即升级旧的客户端软件, 则可以使用新的named_pipe_full_access_group 系统变量为Windows组授予打开命名管道连接所需的权限。完全访问组的成员资格应受到限制且是临时的。

  • 资源管理。 MySQL现在支持创建和管理资源组,并允许将服务中运行的线程分配给特定的组,以便线程根据该组可用的资源执行。使用组属性可以控制其资源,以启用或限制组中线程的资源消耗。DBA可以修改这些属性以适合不同的工作负载。当前,CPU时间是一种可管理的资源,以“ 虚拟CPU ”的概念表示包括CPU内核,超线程,硬件线程等的术语。服务在启动时确定有多少个虚拟CPU可用,具有适当特权的数据库管理员可以将这些CPU与资源组关联,并为组分配线程。有关更多信息,请参见 “资源组”

  • 表加密管理。 现在,可以通过定义和强制执行加密默认值来全局管理表加密。 default_table_encryption 变量为新创建的模式和常规表空间定义加密默认值。创建模式时,也可以使用DEFAULT ENCRYPTION子句定义模式的加密默认值。默认情况下,表继承在其创建的模式或常规表空间的加密。通过启用 table_encryption_privilege_check 变量。当使用不同于设置的加密设置创建或更改模式或常规表空间default_table_encryption 时,或者使用不同于默认模式加密的加密设置创建或更改表时,将进行特权检查 。 启用 table_encryption_privilege_check特权后,TABLE_ENCRYPTION_ADMIN将允许覆盖默认的加密设置 。有关更多信息,请参见 为架构和常规表空间定义加密默认值

  • InnoDB增强功能。 这些InnoDB增强功能已添加:

    • 每次值更改时,当前最大自动增量计数器值都会写入redo日志,并保存到每个检查点的引擎专用系统表中。这些更改使当前的最大自动增量计数器值在服务器重新启动期间保持不变。另外:

      • 重新启动服务器不再取消 AUTO_INCREMENT = N表格选项的作用。如果将自动递增计数器初始化为特定值,或者将自动递增计数器值更改为较大的值,则新值将在服务器重新启动后保留。
      • ROLLBACK 操作之后立即重新启动服务 不再导致重用分配给回滚事务的自动增量值。
      • 如果将AUTO_INCREMENT 列值修改为大于当前最大自动增量值的值(例如,在一个 UPDATE操作中),则将保留新值,并且后续 INSERT操作将从较大的新值开始分配自动增量值。

      有关更多信息,请参见 “ InnoDB中的AUTO_INCREMENT处理”InnoDB AUTO_INCREMENT计数器初始化

    • 遇到索引树损坏时, InnoDB将损坏标志写入redo日志,这会使损坏标志安全崩溃。InnoDB还将内存损坏标志数据写入每个检查点上的引擎专用系统表。在恢复期间, InnoDB在将内存表和索引对象标记为已损坏之前,从两个位置读取损坏标志并合并结果。

    • InnoDBmemcached插件支持多个 get操作(读取在一个单一的多键-值对分布式缓存 查询)和范围查询。请参见 “ InnoDB memcached多重获取和范围查询支持”

    • 新的动态变量 innodb_deadlock_detect可以用于禁用死锁检测。在高并发系统上,当多个线程等待相同的锁时,死锁检测会导致速度变慢。有时,禁用死锁检测并在innodb_lock_wait_timeout 发生死锁时依靠设置进行事务回滚可能会更有效 。

    • INFORMATION_SCHEMA.INNODB_CACHED_INDEXES 表报告InnoDB每个索引在缓冲池中缓存的索引页数 。

    • InnoDB现在在共享临时表空间ibtmp1中创建临时表 。

    • InnoDB 表空间加密功能支持重做日志和撤销日志数据的加密。请参阅 重做日志加密撤消日志加密

    • InnoDB支持 NOWAITSKIP LOCKED选项SELECT ... FOR SHARE以及SELECT ... FOR UPDATE锁定读取语句。 NOWAIT如果请求的行被另一个事务锁定,则导致该语句立即返回。SKIP LOCKED从结果集中删除锁定的行。请参阅 使用NOWAIT和SKIP LOCKED锁定读取并发

      SELECT ... FOR SHARE替代 SELECT ... LOCK IN SHARE MODE,但 LOCK IN SHARE MODE仍可用于向后兼容。这些语句是等效的。然而,FOR UPDATEFOR SHARE支持 NOWAITSKIP LOCKEDOF tbl_name选项。请参见“ SELECT语句”

      OF tbl_name 将锁定查询应用于命名表。

    • ADD PARTITIONDROP PARTITIONCOALESCE PARTITIONREORGANIZE PARTITION,和REBUILD PARTITION ALTER TABLE选项由本地分区就地API支持,可能与ALGORITHM={COPY|INPLACE}LOCK子句一起使用 。

      DROP PARTITIONALGORITHM=INPLACE一起 删除分区中存储的数据并删除分区。但是, DROP PARTITION使用 ALGORITHM=COPYold_alter_table=ON 重建分区表,并尝试将数据从删除的分区移动到具有兼容PARTITION ... VALUES 定义的另一个分区。无法移动到另一分区的数据将被删除。

    • 现在 ,InnoDB存储引擎使用MySQL数据字典,而不是其自己的特定于存储引擎的数据字典。有关数据字典的信息,请参见 MySQL数据字典

    • 现在,mysql在MySQL数据目录中命名为mysql.ibd单独InnoDB表空间文件中 创建系统表和数据字典表 。以前,这些表是在mysql数据库目录中InnoDB的单个表空间文件中创建的。

    • MySQL 8.0中引入了以下撤消表空间更改:

      • 默认情况下,撤消日志现在位于初始化MySQL实例时创建的两个撤消表空间中。撤消日志不再在系统表空间中创建。

      • 从MySQL 8.0.14开始,可以在运行时使用CREATE UNDO TABLESPACE语法在选定位置创建其他撤消表空间 。

        CREATE UNDO TABLESPACE tablespace_name ADD DATAFILE 'file_name.ibu';
        

        使用CREATE UNDO TABLESPACE语法创建的撤消表空间 可以在运行时使用DROP UNDO TABLESPACE语法删除 。

        DROP UNDO TABLESPACE tablespace_name;
        

        ALTER UNDO TABLESPACE 语法可用于将撤消表空间标记为活动或不活动。

        ALTER UNDO TABLESPACE tablespace_name SET {ACTIVE|INACTIVE};
        

        一个STATE列显示了表空间的状态列被添加到 INFORMATION_SCHEMA.INNODB_TABLESPACES 表中。撤消表空间必须处于 empty状态才能被删除。

      • 默认情况下启用 innodb_undo_log_truncate 变量。

      • innodb_rollback_segments 变量定义每个撤消表空间的回滚段数。以前, innodb_rollback_segments 指定了MySQL实例的回滚段总数。此更改增加了可用于并发事务的回滚段的数量。更多的回滚段会增加并发事务将单独的回滚段用于撤消日志的可能性,从而减少资源争用。

    • 修改了影响缓冲池预刷新和刷新行为的变量的默认值:

      • 现在 innodb_max_dirty_pages_pct_lwm 默认值为10。先前的默认值0禁用缓冲池预刷新。当缓冲池中的脏页百分比超过10%时,值为10启用预刷新。启用预刷新可提高性能一致性。
      • innodb_max_dirty_pages_pct 默认值从75到90。InnoDB尝试从缓冲池刷新数据,使脏页的百分比不超过这个值。增加的默认值允许缓冲池中脏页的百分比更高。
    • 现在默认 innodb_autoinc_lock_mode 设置为2(交错)。交错锁定模式允许并行执行多行插入,从而提高了并发性和可伸缩性。新的 innodb_autoinc_lock_mode 默认设置反映了从基于语句的复制到基于行的复制的更改,这是MySQL 5.7中的默认复制类型。基于语句的复制需要连续的自动增量锁定模式(以前的默认设置),以确保按照给定的SQL语句序列以可预测和可重复的顺序分配自动增量值,而基于行的复制对SQL语句不敏感。 SQL语句的执行顺序。有关更多信息,请参见 InnoDB AUTO_INCREMENT锁定模式

      对于使用基于语句的复制的系统,新的 innodb_autoinc_lock_mode 默认设置可能会破坏依赖于顺序自动增量值的应用程序。要恢复以前的默认设置,请设置 innodb_autoinc_lock_mode 为1。

    • ALTER TABLESPACE ... RENAME TO语法 支持重命名常规表空间 。

    • 新的 innodb_dedicated_server变量,默认情况下禁用 ,可用于InnoDB根据服务上检测到的内存量自动配置以下选项:

      此选项适用于在专用服务器上运行的MySQL服务实例。有关更多信息,请参见 “为专用的MySQL服务器启用自动配置”

    • INFORMATION_SCHEMA.INNODB_TABLESPACES_BRIEF 视图为InnoDB表空间提供空间,名称,路径,标志和空间类型数据。

    • 与MySQL捆绑在一起 的zlib库版本从1.2.3版本提高到1.2.11版本。MySQL在zlib库的帮助下实现了压缩。

      如果使用InnoDB压缩表,请参见“ MySQL 8.0中的更改”以获取相关的升级含义。

    • InnoDB除全局临时表空间和撤消表空间文件外 ,所有表空间文件中都存在序列化字典信息(SDI)。SDI是表和表空间对象的序列化元数据。SDI数据的存在提供了元数据冗余。例如,如果数据字典变得不可用,则可以从表空间文件中提取字典对象元数据。使用ibd2sdi工具执行SDI提取。SDI数据以JSON格式存储。

      在表空间文件中包含SDI数据会增加表空间文件的大小。SDI记录需要一个索引页,默认情况下大小为16KB。但是,在存储SDI数据时会对其进行压缩,以减少存储空间。

    • 现在 ,InnoDB存储引擎支持原子DDL,即使服务在操作期间停止运行,它也可以确保DDL操作完全提交或回退。有关更多信息,请参见“原子数据定义语句支持”

    • 使用innodb_directories 选项,在服务脱机时,可以将表空间文件移动或还原到新位置 。有关更多信息,请参见 “在服务器脱机时移动表空间文件”

    • 实现了以下redo日志优化:

      • 用户线程现在可以并发写入日志缓冲区,而无需同步写入。
      • 用户线程现在可以按无约束的顺序将脏页添加到刷新列表中。
      • 现在,专用的日志线程负责将日志缓冲区写入系统缓冲区,将系统缓冲区刷新到磁盘,通知用户线程有关已写入和已刷新的redo,维护无约束的刷新列表顺序所需的滞后时间,以及写入检查点。
      • 添加了系统变量,用于配置用户线程使用的等待刷新redo的回旋延迟:
      • innodb_log_buffer_size 变量是现在动态的,服务运行时允许其调整日志缓冲区的大小。

      有关更多信息,请参见 “优化InnoDB重做日志”

    • 从MySQL 8.0.12开始,对大对象(LOB)数据的小更新支持撤消日志记录,从而提高了大小为100字节或更小的LOB更新的性能。以前,LOB更新的大小至少为一个LOB页,对于可能只修改几个字节的更新而言,这不是最佳的。此增强功能基于MySQL 8.0.4中添加的对LOB数据的部分更新的支持。

    • 从MySQL 8.0.12开始,ALGORITHM=INSTANTALTER TABLE操作支持 :

      • 添加一列。此功能也称为 “ 即时 ADD COLUMN ”。有限制条件。请参见 “在线DDL操作”
      • 添加或删除虚拟列。
      • 添加或删除列默认值。
      • 修改ENUMSET列的定义 。
      • 更改索引类型。
      • 重命名表。

      支持ALGORITHM=INSTANT的操作仅会 修改数据字典中的元数据。在表上没有采取任何元数据锁,并且表数据不受影响,从而使操作立即进行。如果未明确指定,ALGORITHM=INSTANT则默认情况下由支持它的操作使用。如果 ALGORITHM=INSTANT指定但不支持,则操作立即失败并显示错误。

      有关支持的操作的更多信息 ALGORITHM=INSTANT,请参见 “在线DDL操作”

    • 从MySQL 8.0.13开始,TempTable 存储引擎支持二进制大对象(BLOB)类型列的存储。此增强功能提高了使用包含BLOB数据的临时表的查询的性能。以前,包含BLOB数据的临时表存储在internal_tmp_disk_storage_engine定义的磁盘存储引擎中 。有关更多信息,请参见 “ MySQL中的内部临时表使用”

    • 从MySQL 8.0.13开始,InnoDB的data-at-rest加密功能支持常规表空间。以前,只能加密file-per-table表空间。一般的表空间支持加密CREATE TABLESPACEALTER TABLESPACE语法需扩展包括 ENCRYPTION子句。

      INFORMATION_SCHEMA.INNODB_TABLESPACES 表现在包括一ENCRYPTION 列,该列指示表空间是否已加密。

      stage/innodb/alter tablespace (encryption)性能模式阶段手段的加入允许监测一般表空间的加密操作。

    • 禁用 innodb_buffer_pool_in_core_file 变量可通过排除InnoDB缓冲池页面来减少核心文件的大小 。要使用此变量,core_file 必须启用该变量,并且操作系统必须支持Linux 3.4及更高版本支持的的MADV_DONTDUMP非POSIX扩展madvise()。有关更多信息,请参见“从核心文件中排除缓冲池页面”

    • 从MySQL 8.0.13开始,由用户创建的临时表和由优化程序创建的内部临时表存储在会话临时表空间中,该会话临时表空间是从临时表空间池中分配给会话的。当会话断开连接时,其临时表空间将被截断并释放回池中。在以前的版本中,临时表是在全局临时表空间(ibtmp1)中创建的,在删除临时表后,该临时表不会将磁盘空间返回给操作系统。

      innodb_temp_tablespaces_dir 变量定义创建会话临时表空间的位置。默认位置是 数据目录中的#innodb_temp目录。

      INNODB_SESSION_TEMP_TABLESPACES 表提供有关会话临时表空间的元数据。

      现在,全局临时表空间(ibtmp1)存储了回滚段,用于对用户创建的临时表所做的更改。

    • 从MySQL 8.0.14开始,InnoDB支持并行聚合索引读取,这可以提高 CHECK TABLE性能。此功能不适用于二级索引扫描。 并行聚合索引读取发生要求会话变量 innodb_parallel_read_threads必须被设置为一个大于1的值。默认值为4。用于执行并行聚合索引读取的实际线程数取决于 innodb_parallel_read_threads 设置或要扫描的索引子树的数量,以较小者为准。

    • 从8.0.14开始, 启用 innodb_dedicated_server变量后,将根据自动配置的缓冲池大小来配置日志文件的大小和数量。以前,日志文件的大小是根据在服务上检测到的内存量来配置的,而日志文件的数量不是自动配置的。

    • 从8.0.14开始,CREATE TABLESPACE 语句的ADD DATAFILE子句是可选的,它允许没有FILE特权的用户 创建表空间。一个CREATE TABLESPACE执行的语句没有 ADD DATAFILE子句将隐式地创建一个独特的文件名的表空间的数据文件。

    • 默认情况下,当TempTable存储引擎占用的内存量超过temptable_max_ram 变量定义的内存限制时 ,TempTable存储引擎将开始从磁盘分配内存映射的临时文件。从MySQL 8.0.16开始,此行为由temptable_use_mmap 变量控制 。禁用 temptable_use_mmap 会导致TempTable存储引擎将 InnoDB磁盘内部临时表而不是内存映射文件用作其溢出机制。有关更多信息,请参阅 内部临时表存储引擎

    • 从MySQL 8.0.16开始,InnoDB 的data-at-rest加密功能支持对mysql系统表空间的加密。 mysql系统表空间包含 mysql系统数据库和MySQL数据字典表。有关更多信息,请参见 “ InnoDB静态数据加密”

    • MySQL 8.0.16中引入 的innodb_spin_wait_pause_multiplier 变量提供了对自旋锁轮询延迟持续时间的更好控制,自旋锁轮询延迟是在线程等待获取互斥量或读写锁时发生的。可以对延迟进行更精细的调整,以解决不同处理器体系结构上PAUSE指令持续时间的差异。有关更多信息,请参见 “配置自旋锁定轮询”

    • 在MySQL 8.0.17中,InnoDB 通过更好地利用读取线程,减少了并行扫描期间发生的预取活动的读取线程I/O来改善了大型数据集的并行读取线程性能,并支持了分区的并行扫描。

      并行读取线程功能由innodb_parallel_read_threads 变量控制 。现在,最大设置为256,这是所有客户端连接的线程总数。如果达到线程限制,连接将退回到使用单个线程。

    • MySQL 8.0.18中引入 的innodb_idle_flush_pct 变量允许限制空闲期间的页面刷新,这可以帮助延长固态存储设备的寿命。请参见 在空闲期间限制缓冲区刷新

    • InnoDB从MySQL 8.0.19开始,为了生成直方图统计数据,已经 对数据进行了有效采样。请参见 直方图统计分析

    • 从MySQL 8.0.20开始,doublewrite缓冲区存储区位于doublewrite文件中。在以前的版本中,存储区位于系统表空间中。将存储区域移出系统表空间可减少写延迟,增加吞吐量并提供关于双写缓冲区页放置的灵活性。为高级双写缓冲区配置引入了以下系统变量:

      有关更多信息,请参见 “ Doublewrite缓冲区”

    • MySQL 8.0.20中改进了竞争感知事务调度(CATS)算法,该算法优先考虑等待锁的事务。现在,事务调度权重计算完全在单独的线程中执行,从而提高了计算性能和准确性。

      删除了也用于事务调度的先进先出(FIFO)算法。CATS算法的增强使FIFO算法变得多余。以前由FIFO算法执行的事务调度现在由CATS算法执行。

      INFORMATION_SCHEMA.INNODB_TRX表中添加了 一个TRX_SCHEDULE_WEIGHT列 ,该列允许查询由CATS算法分配的事务调度权重。

      INNODB_METRICS添加了 以下计数器来监视代码级事务调度事件:

      • lock_rec_release_attempts

        尝试释放记录锁定的次数。

      • lock_rec_grant_attempts

        授予记录锁定的尝试次数。

      • lock_schedule_refreshes

        分析等待图表以更新事务调度权重的次数。

      有关更多信息,请参见 “事务调度”

  • 字符集支持。 默认字符集已从latin1更改 为utf8mb4utf8mb4字符集有几个新的排序规则,其中包括 utf8mb4_ja_0900_as_cs,提供对Unicode在MySQL中第一个日本语言特定的可用排序。有关更多信息,请参见 “ Unicode字符集”

  • JSON增强。 对MySQL的JSON功能进行了以下增强或添加:

    • 添加了 ->> (内联路径)运算符,等效于在JSON_EXTRACT()的结果上调用 JSON_UNQUOTE()

      这是对MySQL 5.7中引入的列路径运算符->的改进 ; col->>"$.path"等同于 JSON_UNQUOTE(col->"$.path")。内联路径运算符可以用来随时随地代替使用 JSON_UNQUOTE(JSON_EXTRACT())地方,如 SELECT列列表, WHEREHAVING 子句,ORDER BYGROUP BY子句。有关更多信息,请参见运算符的描述以及JSON Path Syntax

    • 添加了两个JSON聚合函数 JSON_ARRAYAGG()JSON_OBJECTAGG()JSON_ARRAYAGG()将列或表达式作为其参数,并将结果聚合为单个JSON数组。该表达式可以求值为任何MySQL数据类型;这不一定是一个JSON值。 JSON_OBJECTAGG()接受两列或表达式,将其解释为键和值;它将结果作为单个JSON 对象返回。有关更多信息和示例,请参见 “聚合(GROUP BY)函数”

    • 添加了JSON实用函数JSON_PRETTY(),该函数以易于阅读的格式输出现有JSON 值;每个JSON对象成员或数组值都打印在单独的一行上,并且子对象或数组相对于其父对象要有2个空格。

      此函数还可以与可解析为JSON值的字符串一起使用。

      有关更多详细信息和示例,请参见 “ JSON实用程序函数”

    • 现在,使用ORDER BY来对查询中的JSON值进行 排序时,每个值现在都由sort键的可变长度部分表示,而不是由固定的1K大小的一部分表示。在许多情况下,这可以减少过多的使用。例如,标量INT甚至 BIGINT值实际上需要很少的字节,因此该空间的其余部分(最多90%或更多)被填充占用。此更改具有以下性能优势:

      • 现在可以更有效地使用排序缓冲区空间,因此文件排序不需要像固定长度排序键那样早或经常刷新到磁盘。这意味着可以在内存中整理更多数据,避免不必要的磁盘访问。
      • 比起较长的键,可以更快地比较较短的键,从而显着提高性能。对于完全在内存中执行的排序以及需要写入磁盘和从磁盘读取的排序,都是如此。
    • 在MySQL 8.0.2中添加了对JSON列值的部分就地更新的支持,这比完全删除现有JSON值并在其位置写入一个新的JSON效率更高,就像以前在更新任何JSON列时所做的那样 。要应用这种优化,更新必须使用应用 JSON_SET()JSON_REPLACE()JSON_REMOVE()。无法将新元素添加到要更新的JSON文档中;文档中的值不能占用比更新前更多的空间。请参阅 JSON值的部分更新,以详细讨论要求。

      可以将JSON文档的部分更新写入二进制日志,比记录完整的JSON文档占用更少的空间。使用基于语句的复制时,始终会记录部分更新。为了使其与基于行的复制一起使用,必须首先设置 binlog_row_value_options=PARTIAL_JSON; 有关更多信息,请参见此变量的说明。

    • 添加了JSON实用函数 JSON_STORAGE_SIZE()JSON_STORAGE_FREE()JSON_STORAGE_SIZE()在进行任何部分更新之前,返回用于JSON文档的二进制表示形式的存储空间(以字节为单位)(请参阅上一项)。 JSON_STORAGE_FREE()显示JSON使用JSON_SET()JSON_REPLACE() 部分更新的类型的表列中剩余的空间量。如果新值的二进制表示形式小于先前值的二进制表示形式,则该值大于零。

      每个函数还接受JSON文档的有效字符串表示形式。对于这样的值, JSON_STORAGE_SIZE()返回其转换为JSON文档后其二进制表示形式使用的空间。对于包含JSON文档的字符串表示形式的变量, JSON_STORAGE_FREE()返回零。如果无法将其(非null)参数解析为有效的JSON文档则两个函数都会返回错误,如果参数为NULL则都会返回 NULL

      有关更多信息和示例,请参见 “ JSON实用程序函数”

      JSON_STORAGE_SIZE()JSON_STORAGE_FREE()在MySQL 8.0.2中实现。

    • 在MySQL 8.0.2中添加了对范围(例如 $[1 to 5]XPath表达式)的支持。在此版本中还添加了对 last关键字和相对寻址的支持,因此$[last]始终选择数组中的最后一个(最高编号)元素以及 $[last-1]最后一个相邻元素。 last和使用它的表达式也可以包含在范围定义中。例如, $[last-2 to last-1]返回最后两个元素,但返回数组中的一个。有关其他信息和示例,请参见 搜索和修改JSON值

    • 添加了旨在符合RFC 7396的JSON合并函数 , JSON_MERGE_PATCH(),当用于2个JSON对象时,将它们合并为一个具有以下集合的并集的单个JSON对象:

      • 第一个对象的每个成员,在第二个对象中不存在具有相同键的成员。
      • 第二个对象的每个成员,在第一个对象中没有成员具有相同的键,并且其值不是JSON null文字。
      • 每个成员都具有在两个对象中都存在的键,并且其在第二个对象中的值不是JSON null文字。

      作为这项工作的一部分, JSON_MERGE()函数已重命名 JSON_MERGE_PRESERVE()JSON_MERGE()仍然被认为是JSON_MERGE_PRESERVE()MySQL 8.0 的别名 ,但现在已被弃用,并且可能在将来的MySQL版本中删除。

      有关更多信息和示例,请参见 “修改JSON值的函数”

    • 实现重复键的 “ 最后重复键获胜 ” 规范化,与 RFC 7159和大多数JavaScript解析器一致。此行为的示例在此处显示,其中仅保留具有x键的最右边的成员:

      mysql> SELECT JSON_OBJECT('x', '32', 'y', '[true, false]',
           >                     'x', '"abc"', 'x', '100') AS Result;
      +------------------------------------+
      | Result                             |
      +------------------------------------+
      | {"x": "100", "y": "[true, false]"} |
      +------------------------------------+
      1 row in set (0.00 sec)
      

      插入MySQL JSON列中的值 也以这种方式标准化,如以下示例所示:

      mysql> CREATE TABLE t1 (c1 JSON);
      
      mysql> INSERT INTO t1 VALUES ('{"x": 17, "x": "red", "x": [3, 5, 7]}');
      
      mysql> SELECT c1 FROM t1;
      +------------------+
      | c1               |
      +------------------+
      | {"x": [3, 5, 7]} |
      +------------------+
      

      与以前的MySQL版本相比,这是一个不兼容的更改, 在这种情况下,使用了“ 首次重复键赢 ”算法。

      有关更多信息和示例请参见JSON值的规范化,合并和自动包装

    • JSON_TABLE() 在MySQL 8.0.4中 添加了该功能。此函数接受JSON数据,并将其作为具有指定列的关系表返回。

      该函数的语法为JSON_TABLE(expr, path COLUMNS column_list) [AS] alias) ,其中 expr 是返回JSON数据的表达式,*path*是应用于源的JSON路径,以及 *column_list*列定义的列表。这里显示一个示例:

      mysql> SELECT *
          -> FROM
          ->   JSON_TABLE(
          ->     '[{"a":3,"b":"0"},{"a":"3","b":"1"},{"a":2,"b":1},{"a":0},{"b":[1,2]}]',
          ->     "$[*]" COLUMNS(
          ->       rowid FOR ORDINALITY,
          ->
          ->       xa INT EXISTS PATH "$.a",
          ->       xb INT EXISTS PATH "$.b",
          ->
          ->       sa VARCHAR(100) PATH "$.a",
          ->       sb VARCHAR(100) PATH "$.b",
          ->
          ->       ja JSON PATH "$.a",
          ->       jb JSON PATH "$.b"
          ->     )
          ->   ) AS  jt1;
      +-------+------+------+------+------+------+--------+
      | rowid | xa   | xb   | sa   | sb   | ja   | jb     |
      +-------+------+------+------+------+------+--------+
      |     1 |    1 |    1 | 3    | 0    | 3    | "0"    |
      |     2 |    1 |    1 | 3    | 1    | "3"  | "1"    |
      |     3 |    1 |    1 | 2    | 1    | 2    | 1      |
      |     4 |    1 |    0 | 0    | NULL | 0    | NULL   |
      |     5 |    0 |    1 | NULL | NULL | NULL | [1, 2] |
      +-------+------+------+------+------+------+--------+
      

      JSON源表达式可以是产生有效JSON文档的任何表达式,包括JSON文字,表列或返回JSON的函数调用,例如JSON_EXTRACT(t1, data, '$.post.comments')。有关更多信息,请参见 “ JSON表函数”

  • 数据类型支持。 MySQL现在支持使用表达式作为数据类型规范中的默认值。这包括使用表达式作为默认值 BLOBTEXTGEOMETRY,和 JSON数据类型,这在以前是根本不会被分配缺省值。有关详细信息,请参见“数据类型默认值”

  • 优化器。 添加了这些优化器增强功能:

    • MySQL现在支持不可见索引。优化器根本不会使用不可见的索引,但它会正常维护。默认情况下,索引可见。不可见的索引使测试删除索引对查询性能的影响成为可能,而无需进行破坏性的更改,如果确实需要索引,则必须撤消该更改。请参见 “不可见索引”

    • MySQL现在支持降序索引: DESC索引定义不再被忽略,而是导致键值以降序存储。以前,索引可以以相反的顺序进行扫描,但会降低性能。降序索引可以按正向顺序进行扫描,这样效率更高。当最有效的扫描顺序混合某些列的升序和其他列的降序时,降序索引还使优化程序可以使用多列索引。请参见“降序索引”

    • MySQL现在支持创建功能索引键部分的索引表达式值而不是列值。功能性关键部分支持对无法通过其他方式索引的值(例如JSON值)进行索引 。有关详细信息,请参见“ CREATE INDEX语句”

    • 在MySQL 8.0.14和更高版本中,WHERE在准备过程中而不是在优化过程中删除了常量文字表达式引起的琐碎 条件。在过程的早期删除条件可以简化具有琐碎条件的外部联接的查询的联接,例如:

      SELECT * FROM t1 LEFT JOIN t2 ON condition_1 WHERE condition_2 OR 0 = 1
      

      现在,优化器在准备过程中会看到0 = 1始终为false,从而使其成为OR 0 = 1 冗余,然后将其删除,从而保持以下状态:

      SELECT * FROM t1 LEFT JOIN t2 ON condition_1 where condition_2
      

      现在,优化器可以将查询重写为内部联接,如下所示:

      SELECT * FROM t1 LEFT JOIN t2 WHERE condition_1 AND condition_2
      

      有关更多信息,请参见 “外部联接优化”

    • 在MySQL 8.0.16及更高版本中,MySQL可以在优化时使用常量折叠来处理列与常量值之间的比较,其中常量超出范围或相对于列的类型在范围边界上,而不是在执行时对于每一行操作。例如,给定一个带有TINYINT UNSIGNEDc的表t ,优化器可以重写条件,例如WHERE c < 256to WHERE 1(并完全优化该条件)或 WHERE c >= 255to WHERE c = 255

      有关更多信息请参见“恒定折叠优化”

    • 从MySQL 8.0.16开始,与IN子查询一起使用的半联接优化现在也可以应用于EXISTS子查询。另外,优化器现在在子查询附加的WHERE条件下对琐碎相关的相等谓词进行解相关 ,以便可以将它们与IN子查询中的表达式进行类似的处理。这适用于EXISTSIN子查询。

      有关更多信息,请参见“使用半联接转换优化IN和EXISTS子查询谓词”

    • 从MySQL 8.0.17开始,服务会在WHERE value <> 0语境化 阶段在内部重写所有不完整的SQL谓词(即,谓词的形式为WHERE value ,其中 *value*是列名或常量表达式,并且不使用比较运算符),以便查询解析程序,查询优化程序和查询执行程序仅需要使用完整的谓词。

      此更改的一个明显效果是,对于布尔值,EXPLAIN现在输出显示truefalse,而不是 1and 0

      此更改的另一个影响是,在SQL布尔上下文中对JSON值求值会对JSON整数0进行隐式比较。考虑如下所示创建和填充的表:

      mysql> CREATE TABLE test (id INT, col JSON);
      
      mysql> INSERT INTO test VALUES (1, '{"val":true}'), (2, '{"val":false}');
      

      以前,服务器 在SQL布尔上下文中进行比较时,尝试将提取的truefalse值转换为 SQL布尔,如以下查询所示 IS TRUE

      mysql> SELECT id, col, col->"$.val" FROM test WHERE col->"$.val" IS TRUE;
      +------+---------------+--------------+
      | id   | col           | col->"$.val" |
      +------+---------------+--------------+
      |    1 | {"val": true} | true         |
      +------+---------------+--------------+
      

      在MySQL 8.0.17及更高版本中,提取的值与JSON整数0的隐式比较导致不同的结果:

      mysql> SELECT id, col, col->"$.val" FROM test WHERE col->"$.val" IS TRUE;
      +------+----------------+--------------+
      | id   | col            | col->"$.val" |
      +------+----------------+--------------+
      |    1 | {"val": true}  | true         |
      |    2 | {"val": false} | false        |
      +------+----------------+--------------+
      

      从MySQL 8.0.21开始,可以 在执行测试之前对提取的值使用JSON_VALUE()进行类型转换,如下所示:

      mysql> SELECT id, col, col->"$.val" FROM test
          ->     WHERE JSON_VALUE(col, "$.val" RETURNING UNSIGNED) IS TRUE;
      +------+---------------+--------------+
      | id   | col           | col->"$.val" |
      +------+---------------+--------------+
      |    1 | {"val": true} | true         |
      +------+---------------+--------------+
      

      同样从MySQL 8.0.21开始,服务提供警告。在SQL布尔上下文中评估JSON值会对JSON整数0进行隐式比较。如果这不是您想要的,则以这种方式在SQL布尔上下文中比较提取的值时,请考虑使用JSON_VALUE RETURNING将JSON转换为SQL数字类型。

    • 在MySQL 8.0.17及更高版本中,WHERE 具有 NOT IN (subquery)NOT EXISTS (subquery) 的条件在内部转换为反连接。(一个反联接返回表中没有与联接条件相匹配的行的表中的所有行,并且符合联接条件。)这将删除子查询,因为该子查询的表现在在顶部处理,因此可以更快地执行查询。

      这类似于并重用现有的IS NULLNot exists)外连接优化。请参阅 EXPLAIN Extra Information

  • 通用表表达式。 MySQL现在支持通用表表达式,包括非递归和递归的。通用表表达式允许使用命名的临时结果集,通过允许在SELECT语句之前的WITH子句和某些其他语句来实现。有关更多信息,请参见 “ WITH(公用表表达式)”

    从MySQL 8.0.19开始,递归SELECT的递归通用表表达式(CTE)部分支持 LIMIT子句。LIMITOFFSET也支持。有关更多信息,请参见 递归公用表表达式

  • 窗口函数。 MySQL现在支持窗口函数,对于查询的每一行,都使用与该行相关的行来执行计算。这些包括诸如 RANK()LAG(),和 NTILE()。此外,现在可以将几个现有的聚合函数用作窗口函数(例如 SUM()AVG())。有关更多信息,请参见“窗口函数”

  • 横向派生表。 现在,派生表之前可以带有 LATERAL关键字,以指定允许它引用(取决于)同一FROM子句中先前表的列。横向派生表使某些SQL操作成为可能,而这些操作无法由非横向派生表完成,或者需要效率较低的解决方法。请参见 “侧面衍生表”

  • 单表DELETE语句中的别名。 在MySQL 8.0.16和更高版本中,单表 DELETE语句支持使用表别名。

  • 正则表达式支持。 此前,MySQL的使用Henry Spencer正则表达式库来支持正则表达式运算符(REGEXPRLIKE)。使用Unicode国际组件(ICU)重新实现了对正则表达式的支持,该组件提供了完整的Unicode支持并且是多字节安全的。REGEXP_LIKE()函数以REGEXPRLIKE 运算符的方式执行正则表达式匹配 ,它们现在是该函数的同义词。此外, REGEXP_INSTR()REGEXP_REPLACE(),和 REGEXP_SUBSTR()函数可用于查找匹配位置并分别执行子字符串替换和提取。 regexp_stack_limitregexp_time_limit系统变量提供匹配引擎资源消耗的控制。有关更多信息,请参见 “正则表达式”。有关实现更改可能影响使用正则表达式的应用程序的方式的信息,请参见 正则表达式兼容性注意事项

  • 内部临时表。 TempTable存储引擎替换MEMORY存储引擎作为默认引擎用于在内存中的内部临时表。TempTable存储引擎提供了有效的存储 VARCHARVARBINARY列。 internal_tmp_mem_storage_engine 会话变量定义了用于在存储器内的临时表的存储引擎。允许的值为 TempTable(默认值)和 MEMORYtemptable_max_ram 变量定义TempTable在将数据存储到磁盘之前存储引擎可以使用的最大内存量 。

  • 日志记录。 错误记录已重写为使用MySQL组件体系结构。传统的错误日志记录是使用内置组件实现的,而日志记录使用系统日志的新实现则是可加载的组件。此外,还提供了可加载的JSON日志编写器。要控制要启用的日志组件,请使用 log_error_services系统变量。有关更多信息,请参见 “错误日志”

  • 备份锁。 一种新型的备份锁可以在联机备份期间允许DML,同时防止可能导致快照不一致的操作。LOCK INSTANCE FOR BACKUPUNLOCK INSTANCE语法支持新的备份锁 。具有 BACKUP_ADMIN权限才能使用这些语句。

  • 复制。 对MySQL复制进行了以下增强:

    • MySQL复制现在支持使用紧凑的二进制格式对JSON文档的部分更新进行二进制日志记录,从而在记录完整的JSON文档时节省了日志空间。当使用基于语句的日志记录时,这种紧凑的日志记录会自动完成,并且可以通过将新的binlog_row_value_options系统变量设置为PARTIAL_JSON来启用 。有关更多信息,请参见JSON值的部分更新以及binlog_row_value_options的描述 。
  • 连接管理。 MySQL服务现在允许专门为管理连接配置TCP/ IP端口。这提供了用于普通连接的网络接口上允许的单个管理连接的替代方法,即使 max_connections个已经建立连接也是如此。请参见 “连接接口”

    MySQL现在提供了对压缩使用的更多控制,以最大程度减少通过与服务器的连接发送的字节数。以前,给定的连接未压缩或已使用zlib压缩算法。现在,也可以使用该zstd算法,并选择zstd连接的压缩级别。可以在服务端以及连接原始端配置允许的压缩算法,包括通过客户端程序以及参与主/从复制或组复制的服务进行的连接。有关更多信息,请参见 “连接压缩控制”

  • 配置。 在整个MySQL中,主机名的最大允许长度已从以前的60个字符增加到255个ASCII字符。例如,这适用于数据字典中与主机名相关的列, mysql系统模式,性能模式INFORMATION_SCHEMAsys SCHEMACHANGE MASTER TO语句的 MASTER_HOST值 ;SHOW PROCESSLIST语句输出中的Host列 ;帐户名称中的主机名(例如使用在帐户管理语句和 DEFINER属性);以及与主机名相关的命令选项和系统变量。

    注意事项:

    • 允许的主机名长度增加会影响在主机名列上具有索引的表。例如,mysql系统模式中索引主机名的表现在具有显式 ROW_FORMAT属性, DYNAMIC以容纳更长的索引值。
    • 某些基于文件名的配置设置可能是基于服务主机名构造的。允许的值受基础操作系统的约束,该操作系统可能不允许文件名足够长以包含255个字符的主机名。这会影响到 general_log_filelog_errorpid_filerelay_log,和 slow_query_log_file 系统变量和相应的选项。如果基于主机名的值对于OS而言太长,则必须提供明确的较短值。
    • 尽管服务现在支持255个字符的主机名,但是与使用--ssl-mode=VERIFY_IDENTITY 选项建立的服务的连接 受到OpenSSL支持的最大主机名长度的限制。主机名匹配与SSL证书的两个字段有关,它们的最大长度如下:公用名:最大长度为64;主题备用名称:根据RFC#1034的最大长度。
  • 插件。 以前,MySQL插件可以用C或C ++编写。插件使用的MySQL头文件现在包含C ++代码,这意味着插件必须用C ++而不是C编写。

  • C API。 MySQL C API现在支持异步功能,用于与MySQL服务器的非阻塞通信。每个功能都是现有同步功能的异步对应项。如果从服务器连接读取或写入服务器连接,则必须等待同步功能。异步功能使应用程序可以检查服务器连接上的工作是否准备就绪。如果不是,应用程序可以执行其他工作,然后再进行检查。请参见 “ C API异步接口”

  • casts的其他目标类型。 函数CAST()CONVERT()现在支持转换到类型 DOUBLEFLOATREAL。在MySQL 8.0.17中添加。请参见“Cast函数和运算符”

  • JSON模式验证。 MySQL 8.0.17添加了两个函数 JSON_SCHEMA_VALID()JSON_SCHEMA_VALIDATION_REPORT() 用于再次验证JSON文档JSON模式。 JSON_SCHEMA_VALID()如果文档根据模式进行验证,则返回TRUE(1),否则通过FALSE(0)返回。 JSON_SCHEMA_VALIDATION_REPORT()返回一个JSON文档,其中包含有关验证结果的详细信息。以下语句适用于这两个功能:

    • 模式必须符合JSON模式规范的草案4。
    • 支持required属性。
    • 不支持 外部资源和$ref 关键字。
    • 支持正则表达式模式;无效模式将被静默忽略。

    有关更多信息和示例,请参见“ JSON模式验证函数”

  • 多值索引。 从MySQL 8.0.17开始, InnoDB支持创建多值索引,该索引是在JSON存储值数组的列上定义的辅助索引,并且单个数据记录可以具有多个索引记录。这样的索引使用诸如 CAST(data->'$.zipcode' AS UNSIGNED ARRAY)的关键部分定义。MySQL优化程序会自动使用多值索引进行合适的查询,如EXPLAIN的输出所示 。

    作为这项工作的一部分,MySQL添加了一个新函数 JSON_OVERLAPS()和一个新MEMBER OF()运算符用于处理JSON文档,此外,还使用一个新ARRAY关键字扩展了CAST()函数, 如下表所示:

    • JSON_OVERLAPS()比较两个 JSON文档。如果它们包含任何共同的键值对或数组元素,则该函数返回TRUE(1); 否则返回FALSE(0)。如果两个值都是标量,则该函数将执行一个简单的相等性测试。如果一个参数是JSON数组,另一个参数是标量,则将标量视为数组元素。因此,JSON_OVERLAPS()可 作为JSON_CONTAINS()的补充。
    • MEMBER OF()测试第一个操作数(标量或JSON文档)是否是作为第二个操作数传递的JSON数组的成员,如果是则返回TRUE(1),否则返回FALSE(0)。不执行操作数的类型转换。
    • CAST(expression AS type ARRAY)允许通过将在*json_path*下JSON文档中找到的JSON数组转换为SQL数组来创建功能索引 。类型说明符仅限于由已经支持的那些CAST()BINARY除外 (不支持)。CAST()(和 ARRAY关键字)的这种用法 仅受 InnoDB支持,并且仅用于创建多值索引。

    有关多值索引的详细信息(包括示例),请参见 多值索引“搜索JSON值的函数”,提供了有关JSON_OVERLAPS()和的 信息MEMBER OF()以及使用示例。

  • 提示time_zone。 从MySQL 8.0.17开始,使用SET_VAR可以提示会话变量 time_zone

  • Redo日志归档。 从MySQL 8.0.17开始,InnoDB支持Redo日志归档。在进行备份操作时,复制Redo日志记录的备份工具有时可能无法跟上Redo日志生成的步伐,由于这些记录被覆盖,导致丢失Redo日志记录。Redo日志归档功能通过将Redo日志记录顺序写入存档文件来解决此问题。备份工具可以根据需要从存档文件复制Redo日志记录,从而避免潜在的数据丢失。有关更多信息,请参阅重做日志归档

  • 克隆插件。 从MySQL 8.0.17开始,MySQL提供了一个克隆插件,允许InnoDB在本地或从远程MySQL服务实例克隆数据。本地克隆操作将克隆的数据存储在运行MySQL实例的同一服务器或节点上。远程克隆操作通过网络将克隆的数据从贡献者MySQL服务实例传输到发起克隆操作的接收者服务或节点。

    克隆插件支持复制。除了克隆数据之外,克隆操作还从贡献者提取并传输复制坐标,并将其应用于接收者,从而可以使用克隆插件来配置组复制成员和复制从属。与复制大量事务相比,使用克隆插件进行配置要快得多,效率也更高。还可以将组复制成员配置为使用克隆插件作为替代的恢复方法,以便成员自动选择从种子成员中检索组数据的最有效方法。

    有关更多信息,请参见“克隆插件”“克隆分布式恢复”

  • 哈希联接优化。 从MySQL 8.0.18开始,只要联接中的每对表都至少包含一个equi-join条件,就使用哈希联接。哈希联接不需要索引,并且在大多数情况下比块嵌套循环算法更有效。可以通过这种方式优化如此处所示的联接:

    SELECT *
        FROM t1
        JOIN t2
            ON t1.c1=t2.c1;
    
    SELECT *
        FROM t1
        JOIN t2
            ON (t1.c1 = t2.c1 AND t1.c2 < t2.c2)
        JOIN t3
            ON (t2.c1 = t3.c1)
    

    哈希联接也可以用于笛卡尔积-即使,未指定联接条件时。

    您可以使用EXPLAIN FORMAT=TREEEXPLAIN ANALYZE查看何时将哈希联接优化用于特定查询 。(在MySQL 8.0.20及更高版本中,您也可以使用EXPLAIN,省略 FORMAT=TREE。)

    哈希联接可用的内存量受join_buffer_size的值限制 。在磁盘上执行需要更多内存的哈希联接;磁盘上的哈希联接可以使用的磁盘文件数受 open_files_limit限制。

    从MySQL 8.0.19开始,hash_join 不再支持MySQL 8.0.18中引入的优化器开关(hash_join = on仍显示为optimizer_switch值的一部分,但设置不再有效)。HASH_JOINNO_HASH_JOIN优化提示也不再支持。开关和提示现在都已弃用,并将在将来的MySQL版本中删除。在MySQL 8.0.18及更高版本中,可以使用NO_BNL优化器开关禁用哈希联接 。

    在MySQL 8.0.20中,MySQL服务器中不再使用块嵌套循环,并且即使查询中不包含equi-join条件,也可以在以前使用块嵌套循环的任何时间使用哈希联接。这适用于内部非等联接,半联接,反联接,左外部联接和右外部联接。这也意味着系统变量optimizer_switchblock_nested_loop标志不再起作用。 BNLNO_BNL仍支持优化程序提示来控制哈希联接的使用。此外,内部联接和外部联接(包括半联接和反联接)现在都可以使用批处理键访问(BKA),该批处理键访问(BKA)递增地分配联接缓冲内存,这样单个查询就不需要消耗解析所需的大量资源。仅支持内部联接的BKA从MySQL 8.0.18开始。

    MySQL 8.0.20还用迭代执行器替换了以前版本的MySQL中使用的执行器。这项工作包括替换管理格式为WHERE value IN (SELECT column FROM table WHERE ...)那些IN查询尚未优化为半联接的旧索引子查询引擎,以及以前依赖于旧执行程序的相同形式实现的查询。

    有关更多信息和示例,请参见 “哈希联接优化”。另请参阅 批处理键访问联接

  • EXPLAIN ANALYZE语句。 MySQL 8.0.18中实现了 一种新形式的EXPLAIN 语句EXPLAIN ANALYZE,它以处理查询所使用的每个迭代器的TREE格式提供了有关SELECT语句 执行的扩展信息 ,并使得可以将估计成本与查询的实际成本进行比较。该信息包括启动成本,总成本,此迭代器返回的行数以及执行的循环数。

    在MySQL 8.0.21和更高版本中,此语句还支持 FORMAT=TREE说明符。 TREE是唯一受支持的格式。

    有关更多信息,请参见使用EXPLAIN ANALYZE获取信息。

  • 查询cast注入。 在8.0.18及更高版本中,MySQL将cast操作注入表达式和条件内的查询条目树中,在该表达式和条件中,参数的数据类型与预期的数据类型不匹配。这对查询结果或执行速度没有影响,但是使查询的执行等同于符合SQL标准的查询,同时保持了与MySQL早期版本的向后兼容性。

    现在这样的隐式转换在时间类型(DATEDATETIMETIMESTAMPTIME)和数字类型(SMALLINTTINYINTMEDIUMINTINT/ INTEGERBIGINT; DECIMAL/ NUMERIC; FLOATDOUBLEREALBIT)之间执行,只要他们正在使用任何标准的数字比较运算符相较(=>=><<=<>/ !=<=>)。在这种情况下,任何尚未为DOUBLE的值 都将强制转换为Double。现在还执行cast注入,在比较DATETIME值与 DATETIME值,其中,必要时将参数强制转换 为 DATETIME

    从MySQL 8.0.21开始,在将字符串类型与其他类型进行比较时,也会执行此类转换。被cast字符串类型包括CHARVARCHARBINARYVARBINARYBLOBTEXTENUM,和 SET。将字符串类型的值与数字类型或 YEAR进行比较时,字符串强制转换为 DOUBLE; 如果其他参数的类型不是FLOATDOUBLE或者REAL,它也cast为 DOUBLE。在将字符串类型与一个 DATETIMETIMESTAMP值 进行比较时 ,字符串将强制转换为DATETIME; 将字符串类型与DATE比较时,字符串被强制转换为DATE

    因此能够看到浏览输出时cast注入到一个给定的查询,通过EXPLAIN ANALYZEEXPLAIN FORMAT=JSON或者,如下所示,EXPLAIN FORMAT=TREE

    mysql> CREATE TABLE d (dt DATETIME, d DATE, t TIME);
    Query OK, 0 rows affected (0.62 sec)
    
    mysql> CREATE TABLE n (i INT, d DECIMAL, f FLOAT, dc DECIMAL);
    Query OK, 0 rows affected (0.51 sec)
    
    mysql> CREATE TABLE s (c CHAR(25), vc VARCHAR(25),
        ->     bn BINARY(50), vb VARBINARY(50), b BLOB, t TEXT,
        ->     e ENUM('a', 'b', 'c'), se SET('x' ,'y', 'z'));
    Query OK, 0 rows affected (0.50 sec)
    
    mysql> EXPLAIN FORMAT=TREE SELECT * from d JOIN n ON d.dt = n.i\G
    *************************** 1. row ***************************
    EXPLAIN: -> Inner hash join (cast(d.dt as double) = cast(n.i as double))
    (cost=0.70 rows=1)
        -> Table scan on n  (cost=0.35 rows=1)
        -> Hash
            -> Table scan on d  (cost=0.35 rows=1)
    
    mysql> EXPLAIN FORMAT=TREE SELECT * from s JOIN d ON d.dt = s.c\G
    *************************** 1. row ***************************
    EXPLAIN: -> Inner hash join (d.dt = cast(s.c as datetime(6)))  (cost=0.72 rows=1)
        -> Table scan on d  (cost=0.37 rows=1)
        -> Hash
            -> Table scan on s  (cost=0.35 rows=1)
    
    1 row in set (0.01 sec)
    
    mysql> EXPLAIN FORMAT=TREE SELECT * from n JOIN s ON n.d = s.c\G
    *************************** 1. row ***************************
    EXPLAIN: -> Inner hash join (cast(n.d as double) = cast(s.c as double))  (cost=0.70 rows=1)
        -> Table scan on s  (cost=0.35 rows=1)
        -> Hash
            -> Table scan on n  (cost=0.35 rows=1)
    
    1 row in set (0.00 sec)
    

    也可以通过执行EXPLAIN [FORMAT=TRADITIONAL]看到这种强制类型转换,在这种情况下,也有必要在执行EXPLAIN语句之后 发出SHOW WARNINGS

  • TIMESTAMP和DATETIME的时区支持。 从MySQL 8.0.19开始,服务器接受带有插入的datetime(TIMESTAMPDATETIME)值的时区偏移量。该偏移量使用与设置time_zone系统变量时使用的格式相同的格式,不同之处在于,当偏移量的小时部分小于10且'-00:00'不允许时,前导零是必需的 。日期时间文字,其中包括时区偏移的例子是 '2019-12-11 10:40:30-05:00''2003-04-14 03:30:00+10:00''2020-01-01 15:35:45+05:30'

    选择日期时间值时不显示时区偏移量。

    包含时区偏移量的Datetime文字可用作准备好的语句参数值。

    作为这项工作的一部分,用于设置 time_zone系统变量的值现在也被限制为 -14:00+14:00,包括在内。(它仍然可以分配名称值以 time_zone诸如 'EST''Posix/Australia/Brisbane''Europe/Stockholm'至该变量,条件是MySQL的时区表被加载;另见 填充的时区表)。

    有关更多信息和示例,请参见 “ MySQL服务器时区支持”以及 “ DATE,DATETIME和TIMESTAMP类型”

  • 有关JSON模式CHECK约束失败的精确信息。JSON_SCHEMA_VALID()用于指定CHECK约束时,MySQL 8.0.19及更高版本提供有关此类约束失败原因的准确信息。

    有关示例和更多信息,请参见 JSON_SCHEMA_VALID()和CHECK约束。另请参见“检查约束”

  • ON DUPLICATE KEY UPDATE中行和列的别名。 从MySQL 8.0.19开始,可以使用别名引用要插入的行,以及(可选)引用其列。考虑在具有列 ab的表t上的以下 INSERT语句 :

    INSERT INTO t SET a=9,b=5
        ON DUPLICATE KEY UPDATE a=VALUES(a)+VALUES(b);
    

    使用新行的别名new,在某些情况下,使用别名m以及 n标识该行的列,可以用许多不同的方式重写INSERT语句,此处显示了一些示例:

    INSERT INTO t SET a=9,b=5 AS new
        ON DUPLICATE KEY UPDATE a=new.a+new.b;
    
    INSERT INTO t VALUES(9,5) AS new
        ON DUPLICATE KEY UPDATE a=new.a+new.b;
    
    INSERT INTO t SET a=9,b=5 AS new(m,n)
        ON DUPLICATE KEY UPDATE a=m+n;
    
    INSERT INTO t VALUES(9,5) AS new(m,n)
        ON DUPLICATE KEY UPDATE a=m+n;
    

    欲了解更多信息和示例,请参见 “INSERT … ON DUPLICATE KEY UPDATE语句”

  • SQL标准的显式表子句和表值构造函数。 根据SQL标准添加了表值构造函数和显式表子句。这些分别在MySQL 8.0.19中作为 TABLE语句和 VALUES语句实现。

    TABLE语句具有格式TABLE table_name,并且等效于SELECT * FROM table_name。它支持ORDER BYLIMIT子句(后者带有可选的 OFFSET),但不允许选择单个表列。 TABLE可以在您使用等效 SELECT语句的任何地方使用;这包括joins,unions,INSERT ... SELECTREPLACECREATE TABLE ... SELECT 语句和子查询。例如:

    • TABLE t1 UNION TABLE t2 相当于 SELECT * FROM t1 UNION SELECT * FROM t2
    • CREATE TABLE t2 TABLE t1 相当于 CREATE TABLE t2 SELECT * FROM t1
    • SELECT a FROM t1 WHERE b > ANY (TABLE t2)等同于SELECT a FROM t1 WHERE b > ANY (SELECT * FROM t2)

    VALUES可用于一个表值提供给一个INSERTREPLACESELECT语句,和表现为VALUES关键字随后进行了一系列行构造(的ROW())由逗号分隔。例如,该语句 INSERT INTO t1 VALUES ROW(1,2,3), ROW(4,5,6), ROW(7,8,9)提供与SQL兼容的等效于MySQL特定的INSERT INTO t1 VALUES (1,2,3), (4,5,6), (7,8,9)。您还可以像选择表一样从VALUES表值构造函数中进行选择 ,请记住,这样做时必须提供表别名,并且SELECT必须像使用其他别名一样使用它 。还包括联接,联合和子查询。

    有关详细信息TABLEVALUES和其使用的示例,请参阅本文档的以下部分:

  • FORCE INDEX,IGNORE INDEX的优化程序提示。 MySQL 8.0引入了索引级优化器提示,这些提示与“索引提示”中所述的传统索引提示类似。这里列出的新的提示,与他们FORCE INDEXIGNORE INDEX 等价:

    例如,以下两个查询是等效的:

    SELECT a FROM t1 FORCE INDEX (i_a) FOR JOIN WHERE a=1 AND b=2;
    
    SELECT /*+ JOIN_INDEX(t1 i_a) */ a FROM t1 WHERE a=1 AND b=2;
    

    前面列出的优化器提示在语法和用法上与现有索引级优化器提示遵循相同的基本规则。

    这些优化器提示旨在替换FORCE INDEXIGNORE INDEX,我们计划在将来的MySQL版本中弃用,然后从MySQL中删除。他们没有实现USE INDEX的单个精确等效项;相反,你可以使用一个或多个 NO_INDEXNO_JOIN_INDEXNO_GROUP_INDEX,或 NO_ORDER_INDEX达到同样的效果。

    有关更多信息和使用示例,请参见 索引级优化器提示

  • JSON_VALUE()函数。 MySQL 8.0.21实现了一个JSON_VALUE()旨在简化JSON 列索引的新功能 。在最基本的形式中,它将JSON文档和指向该文档中单个值的JSON路径作为参数,以及(可选)允许您使用RETURNING关键字指定返回类型 。JSON_VALUE(json_doc, path RETURNING type) 等效于此:

    CAST(
        JSON_UNQUOTE( JSON_EXTRACT(json_doc, path) )
        AS type
    );
    

    您还可以指定ON EMPTYON ERROR或两个子句,与它们跟 JSON_TABLE()一起使用相同。

    您可以使用JSON_VALUE()在如下的JSON列上的表达式上创建索引:

    CREATE TABLE t1(
        j JSON,
        INDEX i1 ( (JSON_VALUE(j, '$.id' RETURNING UNSIGNED)) )
    );
    
    INSERT INTO t1 VALUES ROW('{"id": "123", "name": "shoes", "price": "49.95"}');
    

    使用此表达式的查询(例如此处所示)可以使用索引:

    SELECT name, price FROM t1
        WHERE JSON_VALUE(j, '$.id' RETURNING UNSIGNED) = 123;
    

    在许多情况下,这比从该JSON列创建一个生成的列然后在生成的列上创建索引要简单得多。

    有关更多信息和示例,请参见的描述 JSON_VALUE()

  • 用户注释和用户属性。 MySQL 8.0.21引入了在创建或更新用户帐户时设置用户注释和用户属性的功能。用户注释包括作为参数传递给与CREATE USERALTER USER语句一起使用的COMMENT子句的任意文本。用户属性由JSON对象形式的数据组成,该数据作为参数传递给与这两个语句之一一起使用的ATTRIBUTE 子句。该属性可以包含JSON对象表示法中的任何有效键值对。仅一个 COMMENTATTRIBUTE 可以在单一使用CREATE USERALTER USER 声明。

    用户注释和用户属性在内部作为JSON对象存储在一起,注释文本作为元素的值comment作为其键。可以从 INFORMATION_SCHEMA.USER_ATTRIBUTES表的ATTRIBUTE列中 检索此信息 。由于它是JSON格式,因此您可以使用MySQL的JSON函数和运算符来解析其内容(请参见 “ JSON函数”)。使用JSON_MERGE_PATCH() 函数时,对用户属性的连续更改将与其当前值合并。

    例:

    mysql> CREATE USER 'mary'@'localhost' COMMENT 'This is Mary Smith\'s account';
    Query OK, 0 rows affected (0.33 sec)
    
    mysql> ALTER USER 'mary'@'localhost'
        -≫     ATTRIBUTE '{"fname":"Mary", "lname":"Smith"}';
    Query OK, 0 rows affected (0.14 sec)
    
    mysql> ALTER USER 'mary'@'localhost'
        -≫     ATTRIBUTE '{"email":"mary.smith@example.com"}';
    Query OK, 0 rows affected (0.12 sec)
    
    mysql> SELECT
        ->    USER,
        ->    HOST,
        ->    ATTRIBUTE->>"$.fname" AS 'First Name',
        ->    ATTRIBUTE->>"$.lname" AS 'Last Name',
        ->    ATTRIBUTE->>"$.email" AS 'Email',
        ->    ATTRIBUTE->>"$.comment" AS 'Comment'
        -> FROM INFORMATION_SCHEMA.USER_ATTRIBUTES
        -> WHERE USER='mary' AND HOST='localhost'\G
    *************************** 1. row ***************************
          USER: mary
          HOST: localhost
    First Name: Mary
     Last Name: Smith
         Email: mary.smith@example.com
       Comment: This is Mary Smith's account
    1 row in set (0.00 sec)
    

    有关更多信息和示例,请参见 “ CREATE USER语句”“ ALTER USER语句”“ INFORMATION_SCHEMA USER_ATTRIBUTES表”

  • 新的optimizer_switch标志。 MySQL 8.0.21为optimizer_switch系统变量添加了两个新标志, 如下表所示:

    • prefer_ordering_index 标志

      默认情况下, 只要优化器确定这将导致更快的执行速度,MySQL就会尝试对具有LIMIT子句的任何查询ORDER BYGROUP BY查询使用有序索引。由于在某些情况下为此类查询选择不同的优化实际上可能会更好地执行,因此现在可以通过将prefer_ordering_index标志 设置为off来禁用此优化 。

      此标志的默认值为 on

    • subquery_to_derived 标志

      当此标志设置on为时,优化程序将合格的标量子查询转换为派生表上的联接。例如,查询 SELECT * FROM t1 WHERE t1.a > (SELECT COUNT(a) FROM t2)被重写为 SELECT t1.a FROM t1 JOIN ( SELECT COUNT(t2.a) AS c FROM t2 ) AS d WHERE t1.a > d.c

      这种优化可以应用到子查询其是SELECTWHEREJOIN,或 HAVING子句的一部分; 包含一个或多个聚合函数,但没有GROUP BY 子句;不相关 并且不使用任何不确定的函数。

      优化也可应用于表子查询作为INNOT INEXISTS,或 NOT EXISTS的参数,并且其不包含GROUP BY。例如,查询SELECT * FROM t1 WHERE t1.b < 0 OR t1.a IN (SELECT t2.a + 1 FROM t2)被重写为SELECT a, b FROM t1 LEFT JOIN (SELECT DISTINCT 1 AS e1, t2.a AS e2 FROM t2) d ON t1.a + 1 = d.e2 WHERE t1.b < 0 OR d.e1 IS NOT NULL

      通常禁用此优化,因为它在大多数情况下不会产生明显的性能优势,因此默认情况下将标志设置为off

    有关更多信息,请参见 “可切换的优化”。另请参见 “ LIMIT查询优化”“使用半联接转换优化IN和EXISTS子查询谓词”“通过合并优化派生表,视图引用和公用表表达式”或物化”

  • XML增强功能。 从MySQL 8.0.21开始,LOAD XML语句现在支持 CDATA段作为要导入的XML中的部分。

MySQL 8.0中不推荐的功能

以下功能在MySQL 8.0中已弃用,并且可能在以后的系列中被删除或将被删除。在显示替代方案的地方,应更新应用程序以使用它们。

对于使用在更高版本的MySQL系列中已删除的MySQL 8.0中不推荐使用的功能的应用程序,将语句从MySQL 8.0主服务器复制到更高系列的从服务器时,语句可能会失败,或者可能会对主服务器和从服务器产生不同的影响。为避免此类问题,应修改使用8.0中不推荐使用的功能的应用程序,以避免出现这种情况,并在可能的情况下使用替代方法。

  • utf8mb3字符集已被弃用。请改用utf8mb4

  • 因为caching_sha2_password是MySQL 8.0中的默认身份验证插件,并且提供了sha256_password身份验证插件的功能的超集 , 所以sha256_password已弃用,并将在以后的MySQL版本中将其删除。MySQL帐户验证使用的sha256_password应改为使用caching_sha2_password

  • validate_password插件已被重新实现以使用服务器组件架构。插件形式的validate_password仍然可用,但已过时,并将在MySQL的未来版本中删除。使用插件的MySQL安装应过渡到使用组件。请参见 “过渡到密码验证组件”

  • ALTER TABLESPACEDROP TABLESPACE语句 的ENGINE子句 已弃用。

  • PAD_CHAR_TO_FULL_LENGTH 的SQL模式已经弃用。

  • AUTO_INCREMENT不支持类型 FLOATDOUBLE(以及任何同义词)的列。考虑从此类列中删除AUTO_INCREMENT 属性,或将其转换为整数类型。

  • UNSIGNED属性已弃用,在类型为FLOATDOUBLEDECIMAL(和任何同义词)的列。考虑对此类列使用简单CHECK约束。

  • FLOAT(M,D)DOUBLE(M,D)语法指定的位数数目 FLOATDOUBLE(和任何同义词)类型的列是一个非标准MySQL扩展。不建议使用此语法。

  • 对于数字数据类型,不建议使用ZEROFILL属性,对于整数数据类型,则不建议使用显示宽度属性。考虑使用替代方法来产生这些属性的效果。例如,应用程序可以使用 LPAD()功能将数字零填充到所需宽度,或者将格式化的数字存储在CHAR 列中。

  • 对于字符串数据类型,BINARY 属性是非标准的MySQL扩展,它是用于指定_bin列字符集(如果未指定列字符集,则为表默认字符集)的二进制()归类的简写形式。在MySQL 8.0中,这种非标准用法 BINARY是不明确的,因为 utf8mb4字符集具有多个 _bin排序规则,因此不推荐使用BINARY属性,并且在将来的MySQL版本中将删除对该 属性的支持。应将应用程序调整为使用显式 _bin排序规则。

    BINARY用于指定数据类型或字符集 的用法保持不变。

  • 非标准C风格 &&||!操作符认为是标准的SQL同义词 ANDORNOT操作符,分别已被弃用。使用非标准运算符的应用程序应调整为使用标准运算符。

    注意

    使用||已不推荐 ,除非启用PIPES_AS_CONCATSQL模式。在这种情况下,||表示SQL标准字符串串联运算符。

  • JSON_MERGE()函数已弃用。使用 JSON_MERGE_PRESERVE() 代替。

  • 不建议使用SQL_CALC_FOUND_ROWS查询修饰符和附带FOUND_ROWS() 函数。有关替代策略的信息,请参见FOUND_ROWS() 说明。

  • 从MySQL 8.0.13开始,CREATE TEMPORARY TABLE不 支持TABLESPACE = innodb_file_per_tableTABLESPACE = innodb_temporary子句 。

  • 对于SELECT语句,使用INTO子句在FROM之后, 而不是在SELECT的结尾,在MySQL 8.0.20中被弃用。最好将INTO放在 语句的末尾。

    对于UNION语句,INTO自MySQL 8.0.20起已弃用了这两个变体:

    • 在查询表达式的结尾查询块中,使用INTOFROM之前。
    • 在查询表达式的带括号的尾随块中,请使用INTO,而不管其相对于FROM的位置。

    请参见“ SELECT … INTO语句”“ UNION子句”

  • mysql_upgrade客户端已被弃用,因为它的升级mysql的系统表系统模式和对象在其他模式功能已移动到MySQL服务。请参见 “ MySQL升级过程将升级什么”

  • --no-dd-upgrade服务器选项已被弃用。--upgrade选项取代了该 选项,该选项可以更好地控制数据字典和服务升级行为。

  • mysql_upgrade_info文件(已创建数据目录并用于存储MySQL版本号)已被弃用,并将在以后的MySQL版本中删除。

  • 不建议使用relay_log_info_file系统变量和--master-info-file选项。以前,这些被用来指定relay日志和master info日志的名称,当 relay_log_info_repository=FILEmaster_info_repository=FILE 分别设置,但这些设置已被弃用。crash-safe从表已取代了使用relay日志信和masterinfo日志文件,这是MySQL 8.0的默认设置。

  • 由于优化器的更改, max_length_for_sort_data变量已过时且无效,现在已弃用该 系统变量。

  • 不建议使用这些旧参数来压缩与服务器的连接: --compress客户端命令行选项;C API函数mysql_options()MYSQL_OPT_COMPRESS选项 ; slave_compressed_protocol 系统变量。有关替代使用的参数的信息,请参见 “连接压缩控制”

  • 不建议使用MYSQL_PWD环境变量来指定MySQL密码。

  • 从MySQL 8.0.20开始,不赞成 使用VALUES()来访问INSERT ... ON DUPLICATE KEY UPDATE中的新行值 。请为新的行和列使用别名。

  • 因为在调用JSON_TABLE()时指定ON ERRORON EMPTY之前 违反 了SQL标准,所以现在在MySQL中不推荐使用此语法。从MySQL 8.0.20开始,只要您尝试这样做,服务就会打印警告。在单个JSON_TABLE() 调用中指定这两个子句时,请确保首先使用ON EMPTY子句。

  • 将具有索引前缀的列作为表分区键的一部分从未得到支持。以前,在创建,更改或升级分区表时允许这样,但表的分区函数将它们排除在外,服务表明已发生这种情况也不会发出警告。现在已弃用这种允许的行为,并且会在将来的MySQL版本中删除该行为,在该版本的MySQL中,在分区键中使用任何此类列都会导致拒绝CREATE TABLEALTER TABLE语句。

    从MySQL 8.0.21开始,每当将使用索引前缀的列指定为分区键的一部分时,都会为每个此类列生成警告。每当 CREATE TABLEALTER TABLE语句由于提议的分区键中的所有列都具有索引前缀而被拒绝时,所产生的错误现在将提供拒绝的确切原因。在这两种情况下,都包括通过使用空PARTITION BY KEY()子句将分区函数中使用的列隐式定义为表的主键中的列的情况 。

    有关更多信息和示例,请参阅 键分区不支持的列索引前缀

MySQL 8.0中删除的功能

以下各项已废弃,并且已在MySQL 8.0中删除。在显示替代方案的地方,应更新应用程序以使用它们。

对于使用在MySQL 8.0中删除的功能的MySQL 5.7应用程序,将语句从MySQL 5.7主服务器复制到MySQL 8.0从服务器时,语句可能会失败,或者可能对主服务器和从服务器产生不同的影响。为避免此类问题,应修改使用MySQL 8.0中已删除功能的应用程序,以避免它们出现,并在可能的情况下使用替代方法。

  • innodb_locks_unsafe_for_binlog系统变量已删除。READ COMMITTED隔离级别提供了类似的功能。

  • information_schema_statsMySQL 8.0.0中引入 的变量已删除,并 在MySQL 8.0.3中被information_schema_stats_expiry替换 。

    information_schema_stats_expiry定义缓存INFORMATION_SCHEMA表统计信息的到期设置 。有关更多信息,请参见 “优化INFORMATION_SCHEMA查询”

  • 与已废弃的InnoDB系统表相关的代码已在MySQL 8.0.3中删除。 INFORMATION_SCHEMA基于InnoDB系统表的视图被数据字典表上的内部系统视图替换。受影响的 InnoDB INFORMATION_SCHEMA视图已重命名:

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

    旧名称新名字
    INNODB_SYS_COLUMNSINNODB_COLUMNS
    INNODB_SYS_DATAFILESINNODB_DATAFILES
    INNODB_SYS_FIELDSINNODB_FIELDS
    INNODB_SYS_FOREIGNINNODB_FOREIGN
    INNODB_SYS_FOREIGN_COLSINNODB_FOREIGN_COLS
    INNODB_SYS_INDEXESINNODB_INDEXES
    INNODB_SYS_TABLESINNODB_TABLES
    INNODB_SYS_TABLESPACESINNODB_TABLESPACES
    INNODB_SYS_TABLESTATSINNODB_TABLESTATS
    INNODB_SYS_VIRTUALINNODB_VIRTUAL

    升级到MySQL 8.0.3或更高版本后,请更新所有引用先前InnoDB INFORMATION_SCHEMA视图名称的脚本。

  • 与帐户管理相关的以下功能已删除:

    • 使用GRANT创建用户。而是使用CREATE USER替代。遵循这种做法会使 NO_AUTO_CREATE_USERSQL模式对于GRANT 语句不重要,因此也将其删除,并且当选项文件中sql_mode选项的值的存在阻止mysqld启动时,现在会将错误写入服务日志。

    • 使用GRANT修改不是权限指派而是其他帐户属性。这包括身份验证,SSL和资源限制属性。应该是在创建帐户时使用CREATE USER或在之后使用 ALTER USER进行修改。

    • IDENTIFIED BY PASSWORD 'auth_string'CREATE USERGRANT的 语法。而是使用IDENTIFIED WITH auth_plugin AS 'auth_string'CREATE USERALTER USER语句中,其中 'auth_string'值的格式与命名插件兼容。

      此外,由于IDENTIFIED BY PASSWORD语法已删除,因此 log_builtin_as_identified_by_password 系统变量是多余的,因此也删除。

    • PASSWORD()功能。此外,PASSWORD()删除意味着SET PASSWORD ... = PASSWORD('auth_string') 语法不再可用。

    • old_passwords系统变量。

  • 查询缓存已删除。删除包括以下项目:

    • FLUSH QUERY CACHERESET QUERY CACHE语句。
    • 这些系统变量: query_cache_limitquery_cache_min_res_unitquery_cache_sizequery_cache_typequery_cache_wlock_invalidate
    • 这些状态变量: Qcache_free_blocksQcache_free_memoryQcache_hitsQcache_insertsQcache_lowmem_prunesQcache_not_cachedQcache_queries_in_cacheQcache_total_blocks
    • 这些线程状态:checking privileges on cached querychecking query cache for queryinvalidating query cache entriessending cached result to clientstoring result in query cacheWaiting for query cache lock
    • SQL_CACHE SELECT修饰符。

    这些不赞成使用的查询缓存项仍然不赞成使用,但没有效果,将在以后的MySQL版本中删除:

    • SQL_NO_CACHE SELECT 修饰符。
    • ndb_cache_check_time系统变量。

    have_query_cache系统变量保持过时,总有一个值 NO,并会在将来的MySQL版本中删除。

  • 数据字典提供有关数据库对象的信息,因此服务器不再检查数据目录中的目录名称以查找数据库。因此, --ignore-db-dir选项和 ignore_db_dirs系统变量是多余的并被删除。

  • DDL日志(也称为元数据日志)已被删除。从MySQL 8.0.3开始,此功能由数据字典innodb_ddl_log表处理 。请参阅 查看DDL日志

  • tx_isolationtx_read_only系统变量已被删除。使用transaction_isolationtransaction_read_only代替。

  • sync_frm系统变量已被删除,因为.frm文件已经废弃。

  • secure_auth系统变量和 --secure-auth客户端选项已被删除。C API函数mysql_options()MYSQL_SECURE_AUTH选项已删除。

  • multi_range_count系统变量已删除。

  • log_warnings系统变量和 --log-warnings服务器选项已被删除。请改用 log_error_verbosity系统变量。

  • sql_log_bin系统变量 的全局范围 已删除。sql_log_bin仅具有会话作用域,应调整依赖于@@GLOBAL.sql_log_bin访问的应用程序 。

  • metadata_locks_cache_sizemetadata_locks_hash_instances系统变量被删除。

  • 未使用的date_formatdatetime_formattime_format,和 max_tmp_tables系统变量被删除。

  • 这些弃用兼容性SQL模式被移除: DB2MAXDBMSSQLMYSQL323MYSQL40ORACLEPOSTGRESQLNO_FIELD_OPTIONSNO_KEY_OPTIONSNO_TABLE_OPTIONS。它们不能再分配给sql_mode系统变量或用作mysqldump --compatible选项的允许值 。

    删除MAXDB意味着将CREATE TABLEALTER TABLETIMESTAMP数据类型 视为 TIMESTAMP,而不再视为DATETIME

  • GROUP BY子句 的已弃用ASCDESC限定符将被删除。先前依赖于GROUP BY排序的查询所产生的结果可能与以前的MySQL版本不同。要产生给定的排序顺序,请提供一个ORDER BY 子句。

  • EXPLAIN语句的EXTENDEDPARTITIONS关键字 已删除。这些关键字是不必要的,因为它们的效果始终处于启用状态。

  • 这些与加密有关的项目已删除:

    • ENCODE()DECODE()函数。
    • ENCRYPT()函数。
    • DES_ENCRYPT()DES_DECRYPT()函数, --des-key-file选项, have_crypt系统变量,FLUSH语句的 DES_KEY_FILE选项 和 CMake的 HAVE_CRYPT选项。

    代替已删除的加密函数:对于 ENCRYPT(),请考虑SHA2()改为使用 单向哈希。对于其他,请考虑使用 AES_ENCRYPT()AES_DECRYPT()代替。

  • 在MySQL 5.7,一些空间函数提供了多个名称被弃用使得空间函数的命名空间向更一致的方向移动,其目标是使每个空间的函数名称以ST_开头如果执行精确的操作,或者与MBR一起,如果它执行基于最小边界矩形的操作。在MySQL 8.0中,不推荐使用的函数被删除,仅留下相应的ST_MBR函数:

    • 这些函数已删除推荐 MBR名称: Contains()Disjoint()Equals()Intersects()Overlaps()Within()
    • 这些函数已删除推荐 ST_名称:Area()AsBinary()AsText()AsWKB()AsWKT()Buffer()Centroid()ConvexHull()Crosses()Dimension()Distance()EndPoint()Envelope()ExteriorRing()GeomCollFromText()GeomCollFromWKB()GeomFromText()GeomFromWKB()GeometryCollectionFromText()GeometryCollectionFromWKB()GeometryFromText()GeometryFromWKB()GeometryN()GeometryType()InteriorRingN()IsClosed()IsEmpty()IsSimple()LineFromText()LineFromWKB()LineStringFromText()LineStringFromWKB()MLineFromText()MLineFromWKB()MPointFromText()MPointFromWKB()MPolyFromText()MPolyFromWKB()MultiLineStringFromText()MultiLineStringFromWKB()MultiPointFromText()MultiPointFromWKB()MultiPolygonFromText()MultiPolygonFromWKB()NumGeometries()NumInteriorRings()NumPoints()PointFromText()PointFromWKB()PointN()PolyFromText()PolyFromWKB()PolygonFromText()PolygonFromWKB()SRID()StartPoint()Touches()X()Y()
    • GLength()已删除推荐 ST_Length()
  • “从WKB值创建几何值 的函数”章节中描述的函数 以前接受WKB字符串或几何参数。几何参数不再被允许并产生错误。有关从不使用几何参数迁移查询的准则,请参见该章节。

  • 解析器不再视SQL语句中的\NNULL的同义词。使用 NULL代替。

    这种变化不影响文本文件导入和导出操作与执行LOAD DATASELECT ... INTO OUTFILE,其NULL 继续以\N代表。请参见 “ LOAD DATA语句”

  • PROCEDURE ANALYSE() 语法已删除。

  • 客户端--ssl--ssl-verify-server-cert选项已被删除。使用 --ssl-mode=REQUIRED代替--ssl=1--enable-ssl。使用 --ssl-mode=DISABLED替代--ssl=0--skip-ssl--disable-ssl。使用 --ssl-mode=VERIFY_IDENTITY 代替--ssl-verify-server-cert 选项。(服务端 --ssl选项保持不变。)

    对于C API,mysql_options()MYSQL_OPT_SSL_ENFORCEMYSQL_OPT_SSL_VERIFY_SERVER_CERT选项 对应于客户端--ssl--ssl-verify-server-cert选项,也被删除。使用MYSQL_OPT_SSL_MODE选项,值SSL_MODE_REQUIREDSSL_MODE_VERIFY_IDENTITY代替。

  • --temp-pool服务选项已删除。

  • ignore_builtin_innodb系统变量已删除。

  • 服务器不再将包含特殊字符的MySQL 5.1之前的数据库名称转换为带有附加#mysql50#前缀的5.1格式。由于不再执行这些转换,因此删除了mysqlcheck--fix-db-names--fix-table-names选项, ALTER DATABASE语句UPGRADE DATA DIRECTORY NAME子句,以及Com_alter_db_upgrade状态变量。

    仅支持从一个主要版本升级到另一个主要版本(例如,从5.0升级到5.1,或从5.1升级到5.5),因此,将旧的5.0数据库名称转换为当前版本的MySQL几乎不需要。解决方法是,先将MySQL 5.0安装升级到MySQL 5.1,然后再升级到最新版本。

  • mysql_install_db程序已经从MySQL发布中删除。数据目录初始化应通过使用 --initialize--initialize-insecure 选项调用mysqld来执行 。另外,删除了mysql_install_db使用的 mysqld 选项--bootstrap,并删除 了控制mysql_install_db安装位置的 INSTALL_SCRIPTDIR CMake选项

  • 通用分区处理程序已从MySQL服务中删除。为了支持给定表的分区,用于该表的存储引擎现在必须提供其自己的(“ 本地”)分区处理程序。 --partition--skip-partition选项从MySQL服务删除,分区相关条目中的输出不再显示在SHOW PLUGINS或在 INFORMATION_SCHEMA.PLUGINS 表中。

    当前有两个MySQL存储引擎提供本机分区支持:InnoDBNDB。其中,MySQL 8.0 仅 支持InnoDB。使用任何其他存储引擎在MySQL 8.0中创建分区表的任何尝试都会失败。

    升级的后果。 不支持 使用除InnoDB(例如 MyISAM)以外的存储引擎将分区表从MySQL 5.7(或更早版本)直接升级到MySQL 8.0。处理此类表有两种选择:

    在将服务升级到MySQL 8.0之前,必须对每个分区的非InnoDB表至少执行上述两个操作之一。否则,升级后将无法使用该表。

    由于使用存储引擎在没有分区支持的情况下会导致分区表创建表的语句现在由于错误而失败(ER_CHECK_NOT_IMPLEMENTED),因此必须确保转储文件中MySQL的较早版本的任何语句(例如mysqldump编写的语句)不要指定没有本地分区处理程序的存储引擎,如MyISAM,而它希望导入到创建分区表的MySQL 8.0服务器。您可以通过执行以下任一操作来做到这一点:

    • CREATE TABLE使用STORAGE ENGINE选项以外的值的语句中删除对分区的所有引用,除了InnoDB
    • 将存储引擎指定为 InnoDB,或者默认情况下允许InnoDB 用作表的存储引擎。

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

  • 系统和状态变量信息不再保存在INFORMATION_SCHEMA。这些表被删除: GLOBAL_VARIABLESSESSION_VARIABLESGLOBAL_STATUSSESSION_STATUS。请改用相应的性能模式表。请参见 “性能模式系统变量表”“性能模式状态变量表”。另外,show_compatibility_56 系统变量也被删除。它用于过渡期间,在此期间系统和状态变量信息INFORMATION_SCHEMA表已移到Performance Schema表,并且不再需要。这些状态变量被删除: Slave_heartbeat_periodSlave_last_heartbeatSlave_received_heartbeatsSlave_retried_transactionsSlave_running。性能模式表中提供了它们提供的信息。请参阅 迁移到性能模式系统和状态变量表

  • 性能模式setup_timers表已删除,performance_timers表中的TICK行 也已删除。

  • libmysqld嵌入式服务库被删除,连同:

    • mysql_options()MYSQL_OPT_GUESS_CONNECTIONMYSQL_OPT_USE_EMBEDDED_CONNECTIONMYSQL_OPT_USE_REMOTE_CONNECTIONMYSQL_SET_CLIENT_IP 选项
    • mysql_config--libmysqld-libs--embedded-libs--embedded选项
    • CMake的 WITH_EMBEDDED_SERVERWITH_EMBEDDED_SHARED_LIBRARYINSTALL_SECURE_FILE_PRIV_EMBEDDEDDIR 选项
    • (未归档)mysql --server-arg选项
    • mysqltest --embedded-server--server-arg--server-file选项
    • mysqltest_embeddedmysql_client_test_embedded测试程序
  • mysql_plugin工具已删除。替代方法包括在服务器启动时使用--plugin-load--plugin-load-add选项或在运行时使用该INSTALL PLUGIN语句加载插件。

  • resolveip工具已删除。 可以使用nslookuphostdig代替。

  • resolve_stack_dump工具已删除。官方MySQL构建中的堆栈跟踪始终是符号化的,因此无需使用 resolve_stack_dump

  • 以下服务器错误代码未使用且已删除。专门测试这些错误中任何一个的应用程序应该更新。

    ER_BINLOG_READ_EVENT_CHECKSUM_FAILURE
    ER_BINLOG_ROW_RBR_TO_SBR
    ER_BINLOG_ROW_WRONG_TABLE_DEF
    ER_CANT_ACTIVATE_LOG
    ER_CANT_CHANGE_GTID_NEXT_IN_TRANSACTION
    ER_CANT_CREATE_FEDERATED_TABLE
    ER_CANT_CREATE_SROUTINE
    ER_CANT_DELETE_FILE
    ER_CANT_GET_WD
    ER_CANT_SET_GTID_PURGED_WHEN_GTID_MODE_IS_OFF
    ER_CANT_SET_WD
    ER_CANT_WRITE_LOCK_LOG_TABLE
    ER_CREATE_DB_WITH_READ_LOCK
    ER_CYCLIC_REFERENCE
    ER_DB_DROP_DELETE
    ER_DELAYED_NOT_SUPPORTED
    ER_DIFF_GROUPS_PROC
    ER_DISK_FULL
    ER_DROP_DB_WITH_READ_LOCK
    ER_DROP_USER
    ER_DUMP_NOT_IMPLEMENTED
    ER_ERROR_DURING_CHECKPOINT
    ER_ERROR_ON_CLOSE
    ER_EVENTS_DB_ERROR
    ER_EVENT_CANNOT_DELETE
    ER_EVENT_CANT_ALTER
    ER_EVENT_COMPILE_ERROR
    ER_EVENT_DATA_TOO_LONG
    ER_EVENT_DROP_FAILED
    ER_EVENT_MODIFY_QUEUE_ERROR
    ER_EVENT_NEITHER_M_EXPR_NOR_M_AT
    ER_EVENT_OPEN_TABLE_FAILED
    ER_EVENT_STORE_FAILED
    ER_EXEC_STMT_WITH_OPEN_CURSOR
    ER_FAILED_ROUTINE_BREAK_BINLOG
    ER_FLUSH_MASTER_BINLOG_CLOSED
    ER_FORM_NOT_FOUND
    ER_FOUND_GTID_EVENT_WHEN_GTID_MODE_IS_OFF__UNUSED
    ER_FRM_UNKNOWN_TYPE
    ER_GOT_SIGNAL
    ER_GRANT_PLUGIN_USER_EXISTS
    ER_GTID_MODE_REQUIRES_BINLOG
    ER_GTID_NEXT_IS_NOT_IN_GTID_NEXT_LIST
    ER_HASHCHK
    ER_INDEX_REBUILD
    ER_INNODB_NO_FT_USES_PARSER
    ER_LIST_OF_FIELDS_ONLY_IN_HASH_ERROR
    ER_LOAD_DATA_INVALID_COLUMN_UNUSED
    ER_LOGGING_PROHIBIT_CHANGING_OF
    ER_MALFORMED_DEFINER
    ER_MASTER_KEY_ROTATION_ERROR_BY_SE
    ER_NDB_CANT_SWITCH_BINLOG_FORMAT
    ER_NEVER_USED
    ER_NISAMCHK
    ER_NO_CONST_EXPR_IN_RANGE_OR_LIST_ERROR
    ER_NO_FILE_MAPPING
    ER_NO_GROUP_FOR_PROC
    ER_NO_RAID_COMPILED
    ER_NO_SUCH_KEY_VALUE
    ER_NO_SUCH_PARTITION__UNUSED
    ER_OBSOLETE_CANNOT_LOAD_FROM_TABLE
    ER_OBSOLETE_COL_COUNT_DOESNT_MATCH_CORRUPTED
    ER_ORDER_WITH_PROC
    ER_PARTITION_SUBPARTITION_ERROR
    ER_PARTITION_SUBPART_MIX_ERROR
    ER_PART_STATE_ERROR
    ER_PASSWD_LENGTH
    ER_QUERY_ON_MASTER
    ER_RBR_NOT_AVAILABLE
    ER_SKIPPING_LOGGED_TRANSACTION
    ER_SLAVE_CHANNEL_DELETE
    ER_SLAVE_MULTIPLE_CHANNELS_HOST_PORT
    ER_SLAVE_MUST_STOP
    ER_SLAVE_WAS_NOT_RUNNING
    ER_SLAVE_WAS_RUNNING
    ER_SP_GOTO_IN_HNDLR
    ER_SP_PROC_TABLE_CORRUPT
    ER_SQL_MODE_NO_EFFECT
    ER_SR_INVALID_CREATION_CTX
    ER_TABLE_NEEDS_UPG_PART
    ER_TOO_MUCH_AUTO_TIMESTAMP_COLS
    ER_UNEXPECTED_EOF
    ER_UNION_TABLES_IN_DIFFERENT_DIR
    ER_UNSUPPORTED_BY_REPLICATION_THREAD
    ER_UNUSED1
    ER_UNUSED2
    ER_UNUSED3
    ER_UNUSED4
    ER_UNUSED5
    ER_UNUSED6
    ER_VIEW_SELECT_DERIVED_UNUSED
    ER_WRONG_MAGIC
    ER_WSAS_FAILED
    
  • 不推荐使用INFORMATION_SCHEMA INNODB_LOCKSINNODB_LOCK_WAITS表已删除。请改用性能模式data_locksdata_lock_waits表。

    注意

    在MySQL 5.7中,INNODB_LOCKSLOCK_TABLE列和locked_table列在 sys模式 innodb_lock_waitsx$innodb_lock_waits视图中包含组合 模式/表 名称值。在MySQL 8.0中,data_locks表和 sys模式视图包含单独的模式名称和表名称列。请参见 “ innodb_lock_waits和x $ innodb_lock_waits视图”

  • InnoDB不再支持压缩的临时表。当 innodb_strict_mode启用(默认值), CREATE TEMPORARY TABLE返回错误,如果 ROW_FORMAT=COMPRESSEDKEY_BLOCK_SIZE被指定。如果禁用 innodb_strict_mode选项,则会发出警告,并使用非压缩的行格式创建临时表。

  • InnoDB 在MySQL数据目录之外创建表空间数据文件时,不再创建 .isl文件(InnoDB符号链接文件)。innodb_directories选项现在支持查找在数据目录外部创建的表空间文件。

    通过此更改,不再支持在服务器脱机时通过手动修改.isl文件来移动远程表空间 。innodb_directories选项现在支持移动远程表空间文件 。请参见“在服务器脱机时移动表空间文件”

  • 以下InnoDB文件格式变量已删除:

    • innodb_file_format
    • innodb_file_format_check
    • innodb_file_format_max
    • innodb_large_prefix

    文件格式变量对于创建与MySQL 5.1 早期版本兼容的InnoDB表是必需的 。现在,MySQL 5.1的产品生命周期已结束,不再需要这些选项。

    FILE_FORMAT列已从INNODB_TABLESINNODB_TABLESPACES信息模式表中删除。

  • 删除了支持在XA事务中支持两阶段提交 的系统变量innodb_support_xaInnoDB始终启用XA事务中的两阶段提交支持。

  • 对DTrace的支持已删除。

  • JSON_APPEND()函数已删除。使用JSON_ARRAY_APPEND() 代替。

  • 在MySQL 8.0.13中删除了 对将表分区放置在共享 InnoDB表空间中的支持。共享表空间包括 InnoDB系统表空间和常规表空间。有关在共享表空间中标识分区并将其移至每个表文件表空间的信息,请参见“为升级准备安装”

  • 支持在除了SET 语句中设置用户变量在MySQL 8.0.13中已弃用 。此功能可能会在MySQL 9.0中删除。

  • --ndb perror选项已删除。请改用ndb_perror实用程序。

  • innodb_undo_logs变量已删除。 innodb_rollback_segments 变量执行相同的功能,应替代使用。

  • Innodb_available_undo_logs状态变量已删除。每个表空间的可用回滚段数可以使用SHOW VARIABLES LIKE 'innodb_rollback_segments';

  • 从MySQL 8.0.14开始,先前弃用的 innodb_undo_tablespaces 变量不再可配置。有关更多信息,请参见“撤消表空间”

  • ALTER TABLE ... UPGRADE PARTITIONING语句的支持已删除。

  • 从MySQL 8.0.16开始,已经删除了对系统变量internal_tmp_disk_storage_engine 的支持 。现在,磁盘上的内部临时表始终使用 InnoDB存储引擎。有关更多信息,请参阅 磁盘内部临时表的存储引擎

  • DISABLE_SHARED CMake选项是无用的,并已被删除。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值