MySQL 8.0中添加的功能
以下功能已添加到MySQL 8.0:

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

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

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

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

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

  • mysql现在系统数据库中的授权表是InnoDB (事务性)表。以前,这些是 MyISAM(非事务性)表。授权表存储引擎的更改是account-management 对帐单行为的伴随更改的基础。以前,account-management 对帐单(例如 CREATE USER或 DROP USER),命名多个用户可以对某些用户成功,而对其他用户则失败。现在,每个语句都是事务性的,并且对于所有指定的用户要么都成功,或者回滚,如果发生任何错误,则无效。如果成功,则将语句写入二进制日志;如果失败,则不写入语句。在这种情况下,将发生回滚并且不进行任何更改。有关更多信息,请参见第13.1.1节“原子数据定义语句支持”。
  • 一个新的caching_sha2_password 身份验证插件可用。像sha256_password插件一样 , caching_sha2_password实现SHA-256密码哈希,但使用缓存来解决连接时的延迟问题。它还支持更多的连接协议,针对OpenSSL进行链接,不需要针对基于RSA密钥对的密码交换功能。
    caching_sha2_password和 sha256_password认证插件提供比 mysql_native_password插件更安全的密码加密,并且 caching_sha2_password提供了比sha256_password更好的性能。由于caching_sha2_password的这些优越的安全性和性能特征 ,它现在是首选的身份验证插件,并且也是默认的身份验证插件,而不是 mysql_native_password。
  • MySQL现在支持角色,这些角色被称为权限集合。可以创建和删除角色。角色可以具有授予和撤销的权限。可以向用户帐户授予角色或从用户帐户撤消角色。可以从授予该帐户的角色中选择该帐户的活动适用角色,并且可以在该帐户的会话期间进行更改。
  • MySQL现在合并了用户帐户类别的概念,根据系统用户和普通用户是否具有SYSTEM_USER特权来区分它们 。
  • 以前,除了某些模式之外,不可能授予全局适用的特权。现在,如果系统变量partial_revokes启用了 ,则可以这样做。
  • GRANT语句有一个子句,用于指定有关用于语句执行的特权上下文的其他信息。尽管此语法在SQL级别上可见,但其主要目的是通过使这些出现限制在二进制日志中,从而在由部分吊销施加的授予者特权限制的所有节点之间实现统一复制。
  • MySQL现在维护有关密码历史记录的信息,从而可以限制重复使用以前的密码。DBA可能要求在一定数量的密码更改或一段时间内,不要从以前的密码中选择新密码。可以在全局范围内以及每个帐户基础上建立密码重用策略。
    现在可以要求通过指定要替换的当前密码来验证更改帐户密码的尝试。这使DBA可以防止用户在不证明他们知道当前密码的情况下更改密码。可以在全局范围内以及每个帐户基础上建立密码验证策略。
    现在允许帐户具有双重密码,这使得在复杂的多服务器系统中无缝执行阶段性密码更改而无需停机。
    这些新功能使DBA可以更全面地控制密码管理。
  • 如果使用OpenSSL进行编译,并且在运行时可以使用OpenSSL库和FIPS对象模块,MySQL将支持FIPS模式。FIPS模式对加密操作施加了条件,例如对可接受的加密算法的限制或对更长密钥长度的要求。
  • 服务器现在可以在运行时重新配置服务器用于新连接的SSL上下文。此功能可能很有用,例如可避免重新启动一直运行已久的MySQL服务器(其SSL证书已过期)。
  • 如果服务器和客户端均使用OpenSSL 1.1.1或更高版本进行编译,则OpenSSL 1.1.1支持TLS v1.3协议进行加密连接,而MySQL 8.0.16和更高版本也支持TLS v1.3。
  • MySQL现在将授权给命名管道上的客户端的访问控制设置为在Windows上成功通信所需的最小权限。较新的MySQL客户端软件无需任何其他配置即可打开命名管道连接。如果不能立即升级旧的客户端软件, 则可以使用新的 系统变量named_pipe_full_access_group为Windows组授予打开命名管道连接所需的权限。完全访问组的成员资格应受到限制且是临时的。

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

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

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

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

  • 重新启动服务器不再取消 AUTO_INCREMENT = Ntable选项的作用。如果将自动递增计数器初始化为特定值,或者将自动递增计数器值更改为较大的值,则新值将在服务器重新启动后保留。
  • 在ROLLBACK 操作之后立即重新启动服务器 不再导致重用分配给回滚事务的自动增量值。
  • 如果将AUTO_INCREMENT 列值修改为大于当前最大自动增量值的值(UPDATE例如,在一个 操作中),则将保留新值,并且后续 INSERT操作将从较大的新值开始分配自动增量值。
  • 有关更多信息,请参见 第15.6.1.4节“ InnoDB中的AUTO_INCREMENT处理”和 InnoDB AUTO_INCREMENT计数器初始化。

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

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

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

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

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

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

7、InnoDB支持 NOWAIT和SKIP 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 UPDATE和 FOR SHARE支持 NOWAIT,SKIP LOCKED和选项。请参见第13.2.10节“ SELECT语法”。

8、ADD PARTITION,DROP PARTITION,COALESCE PARTITION,REORGANIZE PARTITION,和REBUILD PARTITION ALTER TABLE选项由本地分区 API的支持,可能与 ALGORITHM={COPY|INPLACE}和 LOCK语句 一起使用。

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

9、InnoDB存储引擎使用MySQL数据字典,而不是其自己的特定于存储引擎的数据字典。有关数据字典的信息,请参见 第14章,MySQL数据字典。

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

10、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};
    显示了表空间的状态列被添加到 INFORMATION_SCHEMA.INNODB_TABLESPACES 表中。撤消表空间必须处于 empty状态才能被删除。

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

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

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

现在 innodb_max_dirty_pages_pct_lwm 默认值为10。先前的默认值0禁用缓冲池预刷新。当缓冲池中的脏页百分比超过10%时启用预刷新。启用预冲洗可提高性能一致性。

将 innodb_max_dirty_pages_pct 默认值从75到90。增加 InnoDB尝试从缓冲池刷新数据,使脏页的百分比不超过这个值。增加的默认值允许缓冲池中脏页的百分比更高。

11、现在默认 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。

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

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

innodb_buffer_pool_size

innodb_log_file_size

innodb_flush_method

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

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

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

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

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

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

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

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

17、实现了以下重做日志优化:

用户线程现在可以并发写入日志缓冲区,而无需同步写入。

用户线程现在可以按轻松的顺序将脏页添加到刷新列表中。

现在,专用的日志线程负责将日志缓冲区写入系统缓冲区,将系统缓冲区刷新到磁盘,通知用户线程有关已写入和已刷新的重做,保持松弛的刷新列表顺序所需的滞后时间,以及写入检查点。

添加了系统变量,以配置等待刷新重做的用户线程使用旋转延迟:

innodb_log_wait_for_flush_spin_hwm:定义最大平均日志刷新时间,超过该时间后,用户线程将在等待刷新重做时不再旋转。

innodb_log_spin_cpu_abs_lwm:定义最小CPU使用量,在该最小使用量之下,用户线程在等待刷新重做时不再旋转。

innodb_log_spin_cpu_pct_hwm:定义最大CPU使用量,在该最大CPU使用量之上,用户线程在等待刷新重做时不再旋转。

的 innodb_log_buffer_size 变量是现在动态的,服务器运行时其允许调整大小日志缓冲区的。

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

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

19、从MySQL 8.0.12开始,ALGORITHM=INSTANT 以下ALTER TABLE操作受支持 :

添加一列。此功能也称为 “ 即时ADD COLUMN ”。有限制条件。请参见 第15.12.1节“在线DDL操作”。

添加或删除虚拟列。

添加或删除列默认值。

修改ENUM或 SET列的定义 。

更改索引类型。

重命名表。

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

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

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

21、从MySQL 8.0.13开始,静态InnoDB 数据加密功能支持常规表空间。以前,只能加密每表文件表空间。为了支持一般的表空间的加密,CREATE TABLESPACE以及ALTER TABLESPACE语法扩展到包括 ENCRYPTION条款。

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

在stage/innodb/alter tablespace (encryption)加入绩效模式阶段仪器允许普通表空间加密操作的监控。

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

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

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

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

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

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

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

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

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

28、从MySQL 8.0.16开始,静态InnoDB 数据加密功能支持对mysql系统表空间的加密。该 mysql系统表空间包含 mysql系统数据库和MySQL数据字典表。有关更多信息,请参见 第15.13节“ InnoDB静态数据加密”。

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

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

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

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

32、增加了对有效采样 InnoDB数据的支持,以生成直方图统计数据。请参见 直方图统计分析。

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

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

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

这是-> 对MySQL 5.7中引入的列路径运算符的改进 ; col->>"$.path"等同于 JSON_UNQUOTE(col->"$.path")。内联路径运算符可以用来随时随地可以使用 JSON_UNQUOTE(JSON_EXTRACT()),如 SELECT列清单, WHERE和HAVING 条款,并ORDER BY和 GROUP BY条款。有关更多信息,请参见运算符的描述以及JSON Path Syntax。

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

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

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

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

现在,JSON使用来对查询中的值进行 排序时ORDER BY,每个值现在都由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。

有关更多信息和示例,请参见 第12.17.8节“ 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版本中删除。

有关更多信息和示例,请参见 第12.17.4节“修改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数据的表达式,是应用于源的JSON路径以及 列定义的列表。这里显示一个示例: JSON_TABLE(expr, path COLUMNS column_list) [AS] alias)exprpathcolumn_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')。有关更多信息,请参见 第12.17.6节“ JSON表函数”。

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

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

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

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

  • MySQL现在支持创建索引表达式值而不是列值的功能索引键部分。功能性关键部分支持对无法通过其他方式索引的值(例如JSON值)进行索引 。有关详细信息,请参见第13.1.15节“ 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

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

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

有关更多信息,请参见第8.2.1.14节“恒定折叠优化”。

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

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

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

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

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

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

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

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

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

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

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

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

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

MySQL复制现在支持使用紧凑的二进制格式对JSON文档的部分更新进行二进制日志记录,从而在记录完整的JSON文档时节省了日志空间。当使用基于语句的日志记录时,这种紧凑的日志记录会自动完成,并且可以通过将新的binlog_row_value_options系统变量设置为来启用 PARTIAL_JSON。有关更多信息,请参见JSON值的部分更新以及的描述 binlog_row_value_options。

连接管理。 MySQL服务器现在允许专门为管理连接配置TCP / IP端口。这提供了用于普通连接的网络接口上允许的单个管理连接的替代方法,即使 max_connections 已经建立连接也是如此。请参见 第8.12.4.1节“ MySQL如何处理客户端连接”。

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

组态。 在整个MySQL中,主机名的最大允许长度已从以前的60个字符增加到255个ASCII字符。例如,这适用于数据字典中与主机名相关的列, mysql系统架构,性能架构INFORMATION_SCHEMA和 sys;陈述的 MASTER_HOST价值 CHANGE MASTER TO;语句输出中的Host列 SHOW PROCESSLIST;帐户名称中的主机名(例如帐户管理对帐单和 DEFINER属性);以及与主机名相关的命令选项和系统变量。

注意事项:

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

插件。 以前,MySQL插件可以用C或C ++编写。插件使用的MySQL头文件现在包含C ++代码,这意味着插件必须用C ++而不是C编写。

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

转换其他目标类型。 功能CAST()和 CONVERT()现在支持转换到类型 DOUBLE, FLOAT和 REAL。在MySQL 8.0.17中添加。请参见第12.10节“广播函数和运算符”。

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 不支持 外部资源和关键字。

支持正则表达式模式;无效模式将被静默忽略。

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

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

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

JSON_OVERLAPS()比较两个 JSON文档。如果它们包含任何共同的键值对或数组元素,则该函数返回TRUE(1); 否则返回FALSE(0)。如果两个值都是标量,则该函数将执行一个简单的相等性测试。如果一个参数是JSON数组,另一个参数是标量,则将标量视为数组元素。因此,可 JSON_OVERLAPS()作为的补充JSON_CONTAINS()。

MEMBER OF()测试第一个操作数(标量或JSON文档)是否是作为第二个操作数传递的JSON数组的成员,如果是则返回TRUE(1),否则返回FALSE(0)。不执行操作数的类型转换。

CAST(path AS type ARRAY)允许通过将在JSON文档中找到的JSON数组json_path转换为SQL数组来创建功能索引 。类型说明符仅限于由已经支持的那些CAST(),以除外 BINARY(不支持)。CAST()(和 ARRAY关键字)的这种用法 仅受支持 InnoDB,并且仅用于创建多值索引。

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

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

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

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

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

有关更多信息,请参见第5.6.7节“克隆插件”和第18.4.3.1节“克隆分布式恢复”。

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

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=TREE或查看何时将哈希联接优化用于特定查询 EXPLAIN ANALYZE。

可以使用optimizer_switch系统变量的hash_join标记(on默认情况下)以及 HASH_JOIN和 NO_HASH_JOIN优化程序提示来控制哈希联接的使用 。

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

有关更多信息和示例,请参见 第8.2.1.4节“哈希联接优化”。

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

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

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

现在这样的隐式转换的时间类型之间执行(DATE, DATETIME, TIMESTAMP, TIME)和数字类型(SMALLINT, TINYINT, MEDIUMINT, INT/ INTEGER, BIGINT; DECIMAL/ NUMERIC; FLOAT, DOUBLE, REAL, BIT),只要他们正在使用任何标准的数字比较运算符(相比=, >=, >, <, <=, <>/ !=,要么 <=>)。在这种情况下,任何尚未为a的值 DOUBLE都将强制转换为1。现在还执行强制转换注入,以比较DATE或 TIME值与 DATETIME值,其中,必要时将参数强制转换 为 DATETIME。

因此能够看到通过查看的输出时石膏注入到一个给定的查询EXPLAIN ANALYZE,EXPLAIN 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> 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)

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