Introduction to VPS and Web Technology Development

1.3 MySQL 8.0的新特性-1

自由vps mysql8手册

本节总结了MySQL 8.0中添加、弃用和删除的内容。附带的部分列出了MySQL服务器选项和变量,已经在MySQL 8.0中添加,弃用,或删除;参见1.4节,“服务器和状态变量和选项在MySQL 8.0中添加,弃用,或删除”。

MySQL 8.0中新增的特性

MySQL 8.0中已弃用的特性

MySQL 8.0中删除的特性

MySQL 8.0中新增的特性

以下特性已经添加到MySQL 8.0:

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

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

升级过程。以前,MySQL安装新版本后,MySQL服务器自动升级在下次启动时,数据字典表之后,DBA将调用mysql_upgrade手动升级MySQL系统表的模式,以及对象等其他模式的系统模式和用户模式。

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

安全和帐户管理。这些增强功能是为了提高安全性和增强DBA在帐户管理方面的灵活性:

mysql系统数据库中的grant表现在是InnoDB(事务)表。以前,这些是MyISAM(非事务性)表。grant表存储引擎的更改导致了对帐户管理语句的行为的相应更改。以前,指定多个用户的帐户管理语句(例如CREATE USER或DROP USER)可能对某些用户成功,而对其他用户失败。现在,每条语句都是事务性的,对于所有已命名的用户,要么成功,要么回滚,如果发生任何错误,则不会产生任何影响。如果语句执行成功,而如果执行失败,则不写入二进制日志;在这种情况下,将发生回滚,并且不进行任何更改。有关更多信息,请参见13.1.1节“原子数据定义语句支持”。

一个新的caching_sha2_password身份验证插件可用。与sha256_password插件一样,caching_sha2_password实现了SHA-256密码散列,但使用缓存解决连接时的延迟问题。它还支持更多的传输协议,并且不需要针对OpenSSL进行链接以实现基于RSA密钥对的密码交换功能。参见6.4.1.2节,“缓存SHA-2可插拔认证”。

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

MySQL现在支持角色,角色是命名的特权集合。角色可以创建和删除。角色可以拥有授予和撤消的权限。角色可以授予和撤消用户帐户。帐户的活动适用角色可以从授予该帐户的角色中选择,并且可以在会话期间为该帐户更改。更多信息,请参见6.2.10节“使用角色”。

MySQL现在合并了用户帐户类别的概念,根据是否拥有SYSTEM_USER特权区分系统用户和普通用户。参见第6.2.11节“帐户类别”。

在以前,不可能授予全局应用的权限(除了某些模式)。如果启用了partial_revokes系统变量,这现在是可能的。参见第6.2.12节“使用部分撤销的特权限制”。


GRANT语句有一个AS user [WITH ROLE]子句,用于指定执行语句时使用的特权上下文的附加信息。这个语法在SQL级别上是可见的,尽管它的主要目的是通过使这些限制出现在二进制日志中,从而支持跨所有节点对部分撤销施加的授予者特权限制进行统一复制。参见第13.7.1.6节“授予声明”。

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

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

帐户现在被允许使用双密码,这使得分阶段的密码更改可以在复杂的多服务器系统中无缝执行,而不需要停机。

MySQL现在允许管理员配置用户帐户,这样由于错误的密码导致过多的连续登录失败导致临时帐户锁定。所需的失败次数和锁定时间可以对每个帐户进行配置。

这些新功能为dba提供了对密码管理的更全面的控制。更多信息请参见6.2.15“密码管理”。

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

服务器用于新连接的TLS上下文现在在运行时可以重新配置。这个功能可能是有用的,例如,避免重新启动MySQL服务器,已经运行了很长时间,其SSL证书已经过期。请参阅服务器端运行时配置和监视加密连接。

OpenSSL 1.1.1支持TLS v1.3协议用于加密连接,MySQL 8.0.16和更高版本也支持TLS v1.3,如果服务器和客户端都使用OpenSSL 1.1.1或更高版本编译。参见章节6.3.2“加密连接TLS协议和密码”。

MySQL现在将在指定管道上授予客户端的访问控制设置为在Windows上成功通信所需的最低限度。新的MySQL客户端软件可以打开命名管道连接,而不需要任何额外的配置。如果旧的客户端软件不能立即升级,可以使用新的named_pipe_full_access_group系统变量为Windows组提供打开命名管道连接所需的权限。全面进入小组的成员资格应该是有限制的和临时的。



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

表加密管理。表加密现在可以通过定义和强制加密默认值来进行全局管理。default_table_encryption变量为新创建的模式和一般表空间定义了一个加密默认值。在创建模式时,也可以使用default encryption子句定义模式的默认加密。默认情况下,表继承创建它的模式或通用表空间的加密。通过启用table_encryption_privilege_check变量来强制执行加密默认值。当创建或修改一个schema或通用表空间时,其加密设置与default_table_encryption设置不同,或者创建或修改一个表时,其加密设置与默认的schema加密设置不同,就会发生权限检查。当启用table_encryption_privilege_check时,TABLE_ENCRYPTION_ADMIN权限允许重写默认的加密设置。有关更多信息,请参见为模式和常规表空间定义加密默认值。

InnoDB增强。InnoDB增加了以下功能:

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

服务器重启不再取消AUTO_INCREMENT = N表选项的效果。如果将自动递增计数器初始化为一个特定的值,或者将自动递增计数器的值更改为一个更大的值,那么新值将在服务器重新启动时保持不变。

回滚操作之后立即重启服务器不再会导致分配给回滚事务的自动递增值的重用。

如果将AUTO_INCREMENT列的值修改为大于当前最大自动增量值的值(例如,在更新操作中),则新值将保持不变,后续的插入操作将从新的更大的值开始分配自动增量值。

更多信息,请参阅15.6.1.6节,“InnoDB中的AUTO_INCREMENT处理”,以及InnoDB的AUTO_INCREMENT计数器初始化。

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

InnoDB memcached插件支持多个get操作(在单个memcached查询中获取多个键值对)和范围查询。参见第15.20.4节“InnoDB memcached多get和Range查询支持”。

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

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


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

InnoDB表空间加密特性支持对重做日志和撤销日志数据进行加密。请参见重做日志加密和撤销日志加密。

InnoDB支持NOWAIT和SKIP LOCKED选项SELECT…分享和选择…用于更新锁定读语句。如果被请求的行被另一个事务锁定,NOWAIT语句将立即返回。SKIP LOCKED从结果集中移除锁定的行。参见lock Read Concurrency with NOWAIT和SKIP LOCKED。

选择……FOR SHARE替换SELECT…在共享模式下锁定,但是在共享模式下锁定仍然可以向后兼容。表述是等价的。但是,对于更新和共享支持NOWAIT、SKIP LOCKED和tbl_name选项。参见13.2.10节“选择语句”。

对指定表应用锁定查询。

本地分区就地api支持ADD PARTITION, DROP PARTITION, COALESCE PARTITION, REORGANIZE PARTITION, and REBUILD PARTITION ALTER TABLE选项,可以与ALGORITHM={COPY|INPLACE}和LOCK子句一起使用。

DROP PARTITION with ALGORITHM=INPLACE删除存储在该分区中的数据并删除该分区。但是,DROP PARTITION with ALGORITHM=COPY或old_alter_table=ON会重新构建分区表,并尝试将数据从被删除的分区移动到另一个兼容分区…价值观的定义。删除无法移动到其他分区的数据。

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

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

MySQL 8.0中引入了以下undo表空间的修改:

缺省情况下,撤销日志现在驻留在MySQL实例初始化时创建的两个撤销表空间中。系统表空间中不再创建Undo日志。

在MySQL 8.0.14版本中,可以使用CREATE undo TABLESPACE语法在运行时选择的位置创建额外的undo表空间。



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

InnoDB表空间加密特性支持对重做日志和撤销日志数据进行加密。请参见重做日志加密和撤销日志加密。

InnoDB支持NOWAIT和SKIP LOCKED选项SELECT…分享和选择…用于更新锁定读语句。如果被请求的行被另一个事务锁定,NOWAIT语句将立即返回。SKIP LOCKED从结果集中移除锁定的行。参见lock Read Concurrency with NOWAIT和SKIP LOCKED。

选择……FOR SHARE替换SELECT…在共享模式下锁定,但是在共享模式下锁定仍然可以向后兼容。表述是等价的。但是,对于更新和共享支持NOWAIT、SKIP LOCKED和tbl_name选项。参见13.2.10节“选择语句”。

对指定表应用锁定查询。

本地分区就地api支持ADD PARTITION, DROP PARTITION, COALESCE PARTITION, REORGANIZE PARTITION, and REBUILD PARTITION ALTER TABLE选项,可以与ALGORITHM={COPY|INPLACE}和LOCK子句一起使用。

DROP PARTITION with ALGORITHM=INPLACE删除存储在该分区中的数据并删除该分区。创建UNDO表空间

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

删除表空间

可以使用ALTER UNDO TABLESPACE语法将UNDO表空间标记为active或inactive。

ALTER TABLESPACE tablespace_name SET {ACTIVE|INACTIVE};

在INFORMATION_SCHEMA中添加了一个显示表空间状态的STATE列。INNODB_TABLESPACES表。撤销表空间在被删除之前必须处于空状态。

innodb_undo_log_truncate变量默认是启用的。

innodb_rollback_segments变量定义了每个undo表空间的回滚段的数量。以前,innodb_rollback_segments指定了MySQL实例的回滚段的总数。此更改增加了可用于并发事务的回滚段的数量。更多的回滚段会增加并发事务为撤消日志使用单独回滚段的可能性,从而减少资源争用。价值观的定义。删除无法移动到其他分区的数据。

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

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

MySQL 8.0中引入了以下undo表空间的修改:

缺省情况下,撤销日志现在驻留在MySQL实例初始化时创建的两个撤销表空间中。系统表空间中不再创建Undo日志。

在MySQL 8.0.14版本中,可以使用CREATE undo TABLESPACE语法在运行时选择的位置创建额外的undo表空间。



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

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语句的执行顺序不敏感。更多信息,请参阅InnoDB AUTO_INCREMENT Lock Modes。

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

ALTER tablespace…支持普通表空间的重命名重命名语法。

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

通过innodb_buffer_pool_size

innodb_log_file_size

innodb_flush_method

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

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

与MySQL绑定的zlib库版本从1.2.3版本提升到1.2.11版本。MySQL在zlib库的帮助下实现压缩。

如果你使用的是InnoDB压缩表,请参考2.11.4“MySQL 8.0的变更”来了解相关的升级提示。

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

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



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

当服务器处于离线状态时,可以使用innodb_directories选项将表空间文件移动或恢复到新的位置。更多信息,请参见15.6.3.6节“在服务器离线时移动表空间文件”。

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

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

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

现在,一个专门的日志线程负责将日志缓冲区写入系统缓冲区,将系统缓冲区刷新到磁盘,通知用户线程重写和刷新,维护放松刷新列表顺序所需的延迟,以及写检查点。

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

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

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

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

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

更多信息,参见8.5.4“优化InnoDB重做日志”。

从MySQL 8.0.12开始,对大对象(LOB)数据的小更新支持undo日志记录,这可以提高大小为100字节或更小的LOB更新的性能。以前,LOB更新的大小至少是一个LOB页面,这对于可能只修改几个字节的更新来说不是最优的。这个增强建立在MySQL 8.0.4中添加的对LOB数据部分更新的支持之上。

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

添加一个列。该特性也称为“即时添加列”。限制适用。参见15.12.1节“在线DDL操作”。

添加或删除虚拟列。

添加或删除列默认值。

修改ENUM或SET列的定义。

更改索引类型。

重命名表。

支持ALGORITHM=INSTANT的操作只修改数据字典中的元数据。没有对表进行元数据锁,表数据不受影响,这使得操作是即时的。如果未显式指定,则支持它的操作默认使用ALGORITHM=INSTANT。如果指定了ALGORITHM=INSTANT但不支持,则操作立即失败并出现错误。

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

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



从MySQL 8.0.13开始,InnoDB的静态数据加密特性支持通用表空间。以前,只能加密每个表文件的表空间。为了支持一般表空间的加密,对CREATE TABLESPACE和ALTER TABLESPACE语法进行了扩展,包括了一个encryption子句。

INFORMATION_SCHEMA。INNODB_TABLESPACES表现在包含一个加密列,用于指示表空间是否被加密。

添加了stage/innodb/alter tablespace (encryption) Performance Schema stage工具,以允许监视一般的tablespace加密操作。

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

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

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

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

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

在MySQL 8.0.14版本中,InnoDB支持并行聚集索引读取,这可以提高检查表的性能。此特性不适用于二级索引扫描。innodb_parallel_read_threads会话变量必须设置为大于1的值,才能发生并行聚集索引读取。缺省值为4。用于执行并行聚集索引读取的实际线程数由innodb_parallel_read_threads设置或要扫描的索引子树的数量决定,以较小的数为基准。

在8.0.14版本中,当innodb_dedicated_server变量被启用时,日志文件的大小和数量将根据自动配置的缓冲池大小来配置。之前,日志文件大小是根据服务器上检测到的内存量来配置的,没有自动配置日志文件的数量。

在8.0.14中,CREATE TABLESPACE语句的ADD DATAFILE子句是可选的,它允许没有FILE权限的用户创建表空间。不带ADD DATAFILE子句的CREATE TABLESPACE语句会隐式地创建具有唯一文件名的表空间数据文件。

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

在MySQL 8.0.16版本中,InnoDB的静态数据加密特性支持MySQL系统表空间的加密。mysql system表空间包括mysql system数据库和mysql数据字典表。更多信息,参见15.13节“InnoDB数据静态加密”。

在MySQL 8.0.16中引入了innodb_spin_wait_pause_multiplier变量,它可以更好地控制当线程等待获取互斥锁或rw-lock时发生的自旋锁轮询延迟的持续时间。延迟可以更精细地调整,以考虑不同处理器架构上暂停指令持续时间的差异。更多信息,请参见15.8.8节“配置旋转锁定轮询”。


在MySQL 8.0.17版本中,InnoDB对大数据集的并行读线程性能得到了提高,这是通过更好地利用读线程,减少了在并行扫描过程中发生的预取活动,并支持并行扫描分区。

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

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

MySQL 8.0.19支持为了生成直方图统计数据而对InnoDB数据进行有效的采样。见直方图统计分析。

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

innodb_doublewrite_dir

定义doublewrite缓冲区文件目录。

innodb_doublewrite_files

定义双写文件的数量。

innodb_doublewrite_pages

为批写定义每个线程的最大doublewrite页数。

innodb_doublewrite_batch_size

定义要在批处理中写入的doublewrite页数。

更多信息,参见15.6.4节,“Doublewrite Buffer”。

争用感知事务调度(CATS)算法,它对等待锁的事务进行优先级排序,在MySQL 8.0.20中得到了改进。事务调度权重计算现在完全由单独的线程执行,这提高了计算性能和准确性。

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

在INFORMATION_SCHEMA中添加了TRX_SCHEDULE_WEIGHT列。INNODB_TRX表,允许查询由CATS算法分配的事务调度权值。

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


在MySQL 8.0.17版本中,InnoDB对大数据集的并行读线程性能得到了提高,这是通过更好地利用读线程,减少了在并行扫描过程中发生的预取活动,并支持并行扫描分区。

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

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

MySQL 8.0.19支持为了生成直方图统计数据而对InnoDB数据进行有效的采样。见直方图统计分析。

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

innodb_doublewrite_dir

定义doublewrite缓冲区文件目录。

innodb_doublewrite_files

定义双写文件的数量。

innodb_doublewrite_pages

为批写定义每个线程的最大doublewrite页数。

innodb_doublewrite_batch_size

定义要在批处理中写入的doublewrite页数。

更多信息,参见15.6.4节,“Doublewrite Buffer”。

争用感知事务调度(CATS)算法,它对等待锁的事务进行优先级排序,在MySQL 8.0.20中得到了改进。事务调度权重计算现在完全由单独的线程执行,这提高了计算性能和准确性。

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

在INFORMATION_SCHEMA中添加了TRX_SCHEDULE_WEIGHT列。INNODB_TRX表,允许查询由CATS算法分配的事务调度权值。

lock_rec_release_attempts

试图释放记录锁的次数。

lock_rec_grant_attempts

尝试授予记录锁的次数。

lock_schedule_refreshes

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

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

MySQL 8.0.21,提高并发操作,需要访问锁队列表和行资源,锁定系统互斥(lock_sys - >互斥)取代了分片门闩,和锁队列被分为表和页面锁队列碎片,每个碎片保护专用互斥。以前,单锁系统互斥锁保护所有锁队列,这是高并发系统上的争用点。新的分片实现允许对锁队列进行更细粒度的访问。

锁系统互斥锁(lock_sys->互斥锁)被以下分片锁存器所取代:

一种全局锁存器(lock_sys->latch .global_latch),由64个读写锁对象(rw_lock_t)组成。对单个锁队列的访问需要共享的全局latch和锁队列分片上的latch。需要访问所有锁队列的操作采用独占式全局锁存器,该锁存器锁住所有表锁和页锁队列碎片。

Table shard latch (lock_sys->latches.table_shards.mutexes),实现为一个包含512个互斥锁的数组,每个互斥锁专用于512个表锁队列碎片中的一个。

Page shard latch (lock_sys->latches.page_shards.mutexes),实现为512个互斥锁的数组,每个互斥锁专用于512个页面锁队列碎片中的一个。

性能模式wait/sync /mutex/innodb/lock_mutex用于监控单锁系统的互斥锁被用于监控新的全局、表分片和页分片锁存的工具所取代:

等待/同步/ sxlock / innodb / lock_sys_global_rw_lock

等待/同步/ / innodb / lock_sys_table_mutex互斥

等待/同步/ / innodb / lock_sys_page_mutex互斥

在MySQL 8.0.21版本中,使用data directory子句在数据目录之外创建的表和表分区数据文件仅限于InnoDB已知的目录。此更改允许数据库管理员控制表空间数据文件的创建位置,并确保在恢复过程中可以找到数据文件。

一般表空间和每个表文件的表空间数据文件(。ibd文件)不能再在undo表空间目录(innodb_undo_directory)中创建


已知目录是指datadir、innodb_data_home_dir和innodb_directories变量定义的目录。

截断位于文件-表-表表表空间中的InnoDB表将删除现有的表空间并创建一个新的表空间。在MySQL 8.0.21版本中,InnoDB会在默认位置创建新的表空间,如果当前表空间目录未知,则会在错误日志中写入警告。要让TRUNCATE TABLE在当前位置创建表空间,需要在运行TRUNCATE TABLE之前将目录添加到innodb_directories设置中。

在MySQL 8.0.21版本中,可以使用ALTER INSTANCE {ENABLE|DISABLE} INNODB REDO_LOG语法来启用和禁用重做日志。这个功能用于将数据加载到新的MySQL实例中。禁用重做日志有助于通过避免重做日志写来加速数据加载。

新的INNODB_REDO_LOG_ENABLE权限允许启用和禁用重做日志。

新的Innodb_redo_log_enabled状态变量允许监控重做日志记录状态。

请参见禁用重做日志记录。

在启动时,InnoDB会根据存储在数据字典中的表空间文件路径来验证已知表空间文件的路径,以防表空间文件被移动到不同的位置。MySQL 8.0.21中引入了新的innodb_validate_tablespace_paths变量,允许禁用表空间路径验证。这个特性适用于不移动表空间文件的环境。禁用表空间路径验证可以提高具有大量表空间文件的系统的启动时间。

更多信息,请参见15.6.3.7节“禁用表空间路径验证”。

从MySQL 8.0.21开始,在支持原子DDL的存储引擎上,CREATE TABLE…当使用基于行的复制时,SELECT语句被记录为二进制日志中的一个事务。以前,它被记录为两个事务,一个用于创建表,另一个用于插入数据。通过这个更改,创建表…SELECT语句现在对于基于行的复制是安全的,并且允许与基于gtid的复制一起使用。有关更多信息,请参见13.1.1节“原子数据定义语句支持”。

在繁忙的系统上截断undo表空间可能会影响性能,因为相关的刷新操作将旧的undo表空间页从缓冲池中删除,并将新undo表空间的初始页刷新到磁盘。为了解决这个问题,MySQL 8.0.21删除了刷新操作。

旧的撤销表空间页在最近使用最少时被被动释放,或者在下一个完整检查点被删除。在截断操作期间,新的undo表空间的初始页现在被重做日志,而不是刷新到磁盘,这也提高了undo表空间截断操作的持久性。

为了防止过多的undo表空间截断操作导致的潜在问题,现在检查点之间相同的undo表空间上的截断操作被限制为64。如果超过了限制,撤消表空间仍然可以设为非活动状态,但是在下一个检查点之后才会截断它。

删除了与已失效的undo truncate刷新操作相关的INNODB_METRICS计数器。删除的计数器包括:undo_truncate_sweep_count、undo_truncate_sweep_usec、undo_truncate_flush_count和undo_truncate_flush_usec。


从MySQL 8.0.22开始,新的innodb_extend_and_initialize变量允许在Linux上配置InnoDB如何分配文件表空间和通用表空间。默认情况下,当一个操作需要在表空间中添加额外的空间时,InnoDB会将页面分配给表空间,并物理地向这些页面写入null。如果频繁分配新页面,此行为会影响性能。在Linux系统上,可以禁用innodb_extend_and_initialize,以避免在新分配的表空间页上物理地写空。当禁用innodb_extend_and_initialize时,使用posix_fallocate()调用分配空间,这些调用保留空间,而不需要物理地写空。

posix_fallocate()操作不是原子操作,这使得在为表空间文件分配空间和更新文件元数据之间可能发生失败。这种失败可能会使新分配的页面处于未初始化状态,导致InnoDB试图访问这些页面时出现失败。为了防止这种情况发生,InnoDB在分配新的表空间页之前会写重做日志记录。如果页面分配操作中断,在恢复期间将从重做日志记录中重播该操作。

从MySQL 8.0.23开始,InnoDB支持对属于加密表空间的doublewrite文件页进行加密。这些页面使用相关表空间的加密密钥进行加密。更多信息,参见15.13节“InnoDB数据静态加密”。

MySQL 8.0.23中引入的temptable_max_mmap变量定义了TempTable存储引擎在开始将内部临时表数据存储在磁盘上之前,允许从内存映射(MMAP)文件分配的最大内存量。设置为0禁用从MMAP文件分配。更多信息,参见8.4.4,“MySQL内部临时表的使用”。

字符集的支持。默认字符集已从latin1更改为utf8mb4。utf8mb4字符集有几个新的排序规则,包括utf8mb4_ja_0900_as_cs,这是MySQL中Unicode的第一个特定于日语的排序规则。要了解更多信息,请参见第10.10.1节“Unicode字符集”。


JSON的增强。以下是对MySQL JSON功能的增强或添加:

添加了->>(内联路径)操作符,这相当于对JSON_EXTRACT()的结果调用JSON_UNQUOTE()。

这是在MySQL 5.7中引入的列路径操作符>的改进;col - > > " $。path"等价于JSON_UNQUOTE(col->"$.path")。内联路径操作符可以在任何可以使用JSON_UNQUOTE(JSON_EXTRACT())的地方使用,比如SELECT列列表、WHERE和HAVING子句、ORDER BY和GROUP BY子句。有关更多信息,请参阅运算符的描述以及JSON路径语法。

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

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

这个函数还可以处理可以解析为JSON值的字符串。

更多详细信息和示例,请参见12.18.8节“JSON实用函数”。

当使用ORDER BY在查询中对JSON值排序时,每个值现在都由sort键的可变长度部分表示,而不是固定大小为1K的部分。在许多情况下,这可以减少过度使用。例如,标量整型或甚至是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()返回0。如果它的(非NULL)参数不能被解析为有效的JSON文档,那么这两个函数都会产生一个错误,如果参数为NULL,则为NULL。

更多信息和示例,请参见12.18.8节“JSON实用函数”。

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

在MySQL 8.0.2中增加了对XPath表达式中$[1到5]等范围的支持。在这个版本中还增加了对last关键字和相对寻址的支持,例如$[last]总是选择数组中最后一个(编号最高的)元素,而$[last-1]则选择倒数第二个元素。last和使用它的表达式也可以包含在范围定义中。例如,$[last-2 to last-1]返回数组中的最后两个元素。有关附加信息和示例,请参阅搜索和修改JSON值。

添加了一个JSON合并函数,以符合RFC 7396。JSON_MERGE_PATCH(),当用于2个JSON对象时,将它们合并为一个JSON对象,该JSON对象的成员是以下集合的一个联合:

第一个对象的每个成员在第二个对象中没有具有相同键的成员。

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

每个成员都有一个键,该键存在于两个对象中,并且其在第二个对象中的值不是JSON null字面量。

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

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

实现了“最后一个重复键获胜”的重复键规范化,与RFC 7159和大多数JavaScript解析器一致。这种行为的一个例子在这里显示,只有最右边的成员有键x被保留:

mysql >选择JSON_OBJECT(“x”、“32”、“y”,“(真、假)”,

结果为> 'x', '"abc"', 'x', '100');

+------------------------------------+

|结果 |

+------------------------------------+

{"x": "100", "y": "[true, false]"} |

+------------------------------------+

1 row in set (0.00 sec)

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

mysql> CREATE TABLE t1 (c1 JSON);

mysql >插入t1值(“{“x”:17,“x”:“红色”,“x”:[3、5、7]}”);

mysql> SELECT c1 FROM t1;

+------------------+

| c1 |

+------------------+

| {"x": [3,5,7]} |

+------------------+

这与以前的MySQL版本是不兼容的,在以前的版本中,在这种情况下使用的是“第一个重复密钥获胜”算法。



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

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

该函数的语法为JSON_TABLE(expr,路径列column_list) [AS] alias),其中expr是返回JSON数据的表达式,path是应用于源的JSON路径,column_list是列定义的列表。下面是一个例子:

mysql > SELECT *

- >

- > JSON_TABLE (

-> '[{" ”:3,“b”:“0”},{“a”:“3”、“b”:“1”},{“b”,“a”:2:1},{“a”:0},{b:[1, 2]}]”,

-> "$[*]" 列(

->序数rowid,

->

-> xa INT存在路径“$ a”,

-> xb INT存在路径"$.b",

->

-> sa VARCHAR(100) PATH "$ a",

-> sb VARCHAR(100)路径“$.b”,

->

-> ja JSON路径"$ a",

-> jb JSON路径"$.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.18.6节“JSON表函数”。

数据类型的支持。MySQL现在支持在数据类型规范中使用表达式作为默认值。这包括使用表达式作为BLOB、文本、几何和JSON数据类型的默认值,这些数据类型以前根本不能被分配默认值。请参见11.6“数据类型默认值”章节。

优化器。这些优化器增强是添加的:

MySQL现在支持不可见索引。不可见的索引根本不会被优化器使用,但在其他方面是正常维护的。默认情况下索引是可见的。不可见索引可以测试删除索引对查询性能的影响,而不需要进行破坏性的更改(如果最终需要该索引,则必须撤消该更改)。见8.3.12节“不可见索引”。

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

MySQL现在支持创建函数式索引键部分,索引表达式值而不是列值。功能键部分支持对无法索引的值(如JSON值)进行索引。具体操作请参见13.1.15 CREATE INDEX语句。

在MySQL 8.0.14及以后的版本中,常量文字表达式产生的条件在准备过程中被删除,而不是在以后的优化过程中删除。删除流程中早期的条件,可以简化具有外部连接条件的查询的连接,例如下面这个:


mysql>创建表test (id INT, col JSON);

mysql >插入测试值(“{“val”:真}”),(2,'{“val”:假}');

以前,当在SQL布尔上下文中比较时,服务器试图将提取的true或false值转换为SQL布尔值,如下面的查询所示:

mysql> SELECT id, col, col->"$。val" FROM test WHERE col->"$。val”是正确的;

+------+---------------+--------------+

| 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”是正确的;

+------+----------------+--------------+

| id | col | col->"$。val”|

+------+----------------+--------------+

| 1 | {"val": true} | true |

| 2 | {"val": false} | false |

+------+----------------+--------------+

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

mysql> SELECT id, col, col->"$。val”测试

-> WHERE JSON_VALUE(col, "$。val"返回UNSIGNED)为真;

+------+---------------+--------------+

| id | col | col->"$。val”|

+------+---------------+--------------+

| 1 | {"val": true} | true |

+------+---------------+--------------+


同样从MySQL 8.0.21开始,服务器提供了警告,在SQL布尔上下文中计算JSON值会隐式地比较JSON整数0;如果这不是您想要的,请考虑将JSON转换为SQL数字类型,并在SQL布尔上下文中以这种方式比较提取的值时返回JSON_VALUE。

在MySQL 8.0.17及以后的版本中,WHERE条件包含NOT In(子查询)或NOT EXISTS(子查询)会在内部转换为反连接。(antijoin返回表中没有匹配连接条件的行的所有行。)这样就删除了子查询,这可能导致更快的查询执行,因为子查询的表现在是在顶层处理的。

这类似于外部连接的现有is NULL(不存在)优化;请参阅解释额外信息。

从MySQL 8.0.21开始,单表UPDATE或DELETE语句现在在很多情况下都可以使用半连接转换或子查询物化。这适用于下列表格的陈述:

  • UPDATE t1 SET t1.a=value WHERE t1.a IN (SELECT t2.a FROM t2)

  • DELETE FROM t1 WHERE t1.a IN (SELECT t2.a FROM t2)


对于满足以下条件的单表更新或删除,可以这样做:

UPDATE或DELETE语句使用具有[NOT] IN或[NOT] EXISTS谓词的子查询。

该语句没有ORDER BY子句,也没有LIMIT子句。

(UPDATE和DELETE的多表版本不支持ORDER BY或LIMIT。)

目标表不支持先读后写删除(仅与NDB表相关)。

基于子查询中包含的任何提示和optimizer_switch的值,允许半连接或子查询物化。

当半连接优化用于合格的单表删除或更新时,这在优化器跟踪中可见:对于多表语句,跟踪中有一个join_optimization对象,而对于单表语句则没有。在EXPLAIN FORMAT=TREE或EXPLAIN ANALYZE的输出中也可以看到转换;单表语句显示<不可由迭代器执行器>执行,而多表语句报告完整的计划。

从MySQL 8.0.21开始,使用InnoDB表的多表更新语句支持半一致读,因为事务隔离级别比可重复读弱。


改进了散列连接性能。MySQL 8.0.23重新实现了用于哈希连接的哈希表,从而提高了哈希连接的性能。该工作包括修复了一个问题(Bug #31516149, Bug #99933),即分配给连接缓冲区(join_buffer_size)的内存只有大约2/3实际上可以被哈希连接使用。

新的哈希表通常比旧的哈希表更快,并且用于对齐、键/值,以及在有许多相等键的情况下使用的内存更少。此外,当哈希表的大小增加时,服务器现在可以释放旧内存。

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

从MySQL 8.0.19开始,递归公共表表达式(CTE)的递归选择部分支持LIMIT子句。也支持带偏移量的限制。有关更多信息,请参见递归公共表表达式。


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

横向派生表。派生表现在可以在其前面加上LATERAL关键字,以指定允许它引用(依赖于)前面表在同一FROM子句中的列。横向派生表使某些SQL操作成为可能,这些操作不能用非横向派生表完成,或者需要低效率的替代方法。参见第13.2.11.9节“横向派生表”。

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

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


内部临时表。TempTable存储引擎取代内存存储引擎作为内存内部临时表的默认引擎。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的backup和UNLOCK实例语法。使用这些语句需要BACKUP_ADMIN权限。

复制。以下是对MySQL复制的增强:

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

连接管理。MySQL服务器现在允许专门为管理连接配置TCP/IP端口。这提供了一种替代单一管理连接的方法,这种方法在用于普通连接的网络接口上被允许,即使已经建立了max_connections连接。参见5.1.12.1节“连接接口”。

MySQL现在对压缩的使用提供了更多的控制


MySQL现在对压缩的使用提供了更多的控制,以最小化通过连接发送到服务器的字节数。以前,给定的连接要么未压缩,要么使用zlib压缩算法。现在,也可以使用zstd算法,并为zstd连接选择压缩级别。允许的压缩算法可以在服务器端配置,也可以在客户机程序和参与源/副本复制或组复制的服务器的连接发起端配置。更多信息,请参见4.2.8节“连接压缩控制”。

配置。MySQL中主机名的最大允许长度已经从之前的60个字符限制提高到255个ASCII字符。例如,这适用于数据字典中与主机名相关的列,mysql system schema, Performance schema, INFORMATION_SCHEMA和sys schema;更改MASTER TO语句的MASTER_HOST值;SHOW PROCESSLIST语句输出中的Host列;帐户名中的主机名(例如在帐户管理语句和定义器属性中使用);以及与主机名相关的命令选项和系统变量。

警告:

允许的主机名长度的增加会影响在主机名列上有索引的表。例如,索引主机名的mysql系统模式中的表现在有一个显式的ROW_FORMAT属性DYNAMIC,以容纳更长的索引值。

一些以文件名为值的配置设置可能基于服务器主机名构建。允许的值受底层操作系统的限制,它可能不允许文件名长到包含255个字符的主机名。这将影响general_log_file、log_error、pid_file、relay_log和slow_query_log_file系统变量和相应的选项。如果基于主机名的值对于操作系统来说太长,则必须提供显式的短值。

虽然服务器现在支持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异步接口。

强制类型转换的其他目标类型。函数CAST()和CONVERT()现在支持DOUBLE、FLOAT和REAL类型的转换。在MySQL 8.0.17中增加。参见第12.11节“强制转换函数和操作符”。

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。

支持所需的属性。

不支持外部资源和$ref关键字。

支持正则表达式模式;无效的模式会被无声地忽略。

更多信息和示例,请参阅12.18.7节“JSON模式验证函数”。

多值索引。从MySQL 8.0.17开始,InnoDB支持创建一个多值索引,这是一个定义在JSON列上的二级索引,它存储了一个值数组,可以为一条数据记录创建多个索引记录。这样的索引使用关键部分定义,如CAST(data->'$)。zipcode'作为无符号数组)。MySQL优化器在合适的查询中自动使用多值索引,可以在EXPLAIN的输出中查看。

作为这项工作的一部分,MySQL添加了一个新的函数JSON_OVERLAPS()和一个新的()操作符成员来处理JSON文档,另外用一个新的ARRAY关键字扩展了CAST()函数,如下所示:


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

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

强制转换(表达式为类型数组)通过将JSON文档中位于json_path的JSON数组强制转换为SQL数组,允许创建函数索引。类型说明符仅限于CAST()已经支持的类型,除了BINARY(不支持)。这种CAST()(和ARRAY关键字)的用法只在InnoDB中支持,并且只在创建多值索引时支持。

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

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

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

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

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



更多信息,请参阅5.6.7节“克隆插件”和18.4.3.2节“分布式恢复克隆”。

散列连接优化。从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查看何时将散列连接优化用于特定查询。(在MySQL 8.0.20及以后的版本中,你也可以使用EXPLAIN,省略FORMAT=TREE。)

散列连接可用的内存量受join_buffer_size值的限制。需要超过这个内存的散列连接在磁盘上执行;磁盘上哈希连接可以使用的磁盘文件数量受到open_files_limit的限制。

从MySQL 8.0.19开始,MySQL 8.0.18中引入的hash_join优化器开关不再被支持(hash_join=on仍然作为optimizer_switch值的一部分出现,但是设置它不再有任何影响)。也不再支持HASH_JOIN和NO_HASH_JOIN优化器提示。switch和hint现在都已弃用;希望在未来的MySQL版本中删除它们。在MySQL 8.0.18及以后版本中,可以使用NO_BNL优化器开关禁用哈希连接。

在MySQL 8.0.20及以后版本中,块嵌套循环不再在MySQL服务器中使用,即使查询中不包含等距连接条件,散列连接也会在之前使用块嵌套循环时使用。这适用于内部非等距连接、半连接、反连接、左外连接和右外连接。仍然支持optimizer_switch系统变量的block_nested_loop标志以及BNL和NO_BNL优化器提示,但今后只支持哈希连接的控制使用。此外,内部连接和外部连接(包括半连接和反连接)现在都可以使用批处理键访问(BKA), BKA以增量方式分配连接缓冲区内存,以便单个查询不必消耗它们实际上不需要解析的大量资源。从MySQL 8.0.18开始,只支持用于内部连接的BKA。

MySQL 8.0.20还用迭代器执行器替换了以前版本MySQL中使用的执行器。这项工作包括替换旧的索引子查询引擎管理查询表单的值在(从表中选择列…)的查询没有优化semijoins,以及查询物化在相同的形式,以前依靠旧的遗嘱执行人。

要了解更多信息和示例,请参见8.2.1.4节“哈希连接优化”。请参见批处理密钥访问联接。

解释分析语句。在MySQL 8.0.18中实现了EXPLAIN语句的一种新形式EXPLAIN ANALYZE,它为处理查询时使用的每个迭代器提供了关于以树格式执行SELECT语句的扩展信息,并使得比较查询的估计成本和实际成本成为可能。这些信息包括启动成本、总成本、迭代器返回的行数以及执行的循环数。

在MySQL 8.0.21及以后版本中,该语句还支持FORMAT=TREE说明符。TREE是唯一支持的格式。

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

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


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

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

这样的隐式类型转换现在在时态类型(DATE, DATETIME, TIMESTAMP, TIME)和数值类型(SMALLINT, TINYINT, MEDIUMINT, INT/INTEGER, BIGINT;十进制/数字;浮点数、双、真实的;当使用任何标准的数值比较运算符(=,>=,>,<,<=,<>/!)=、< = >)。在这种情况下,任何不是DOUBLE类型的值都被强制转换为一个。现在还会执行强制转换注入,以比较日期或时间值和DATETIME值,其中参数在必要时被强制转换为DATETIME。

从MySQL 8.0.21开始,当比较字符串类型与其他类型时,也会执行这种类型转换。强制转换的字符串类型包括CHAR、VARCHAR、BINARY、VARBINARY、BLOB、TEXT、ENUM和SET。当将字符串类型的值与数值类型或年份进行比较时,字符串强制转换为DOUBLE;如果另一个实参的类型不是FLOAT、DOUBLE或REAL,它也会被强制转换为DOUBLE。当比较字符串类型与DATETIME或TIMESTAMP值时,字符串被转换为DATETIME;当比较字符串类型与DATE类型时,字符串被转换为DATE类型。

通过查看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> 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 ANALYZE获取信息。

这样的类型转换也可以通过执行EXPLAIN [FORMAT=TRADITIONAL]来查看,在这种情况下,在执行EXPLAIN语句之后还需要发出SHOW警告。

时区支持TIMESTAMP和DATETIME。从MySQL 8.0.19开始,服务器接受插入datetime(时间戳和datetime)值的时区偏移。此偏移量使用与设置time_zone系统变量时使用的格式相同的格式,除了当偏移量的小时部分小于10时需要前导零,并且不允许使用'-00:00'。包含时区偏移量的datetime字符串示例为:'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值时不显示时区偏移量。

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

作为这项工作的一部分,用于设置time_zone系统变量的值现在也被限制为范围-14:00到+14:00(包括在内)。(在加载MySQL时区表的情况下,仍然可以为time_zone赋值,例如'EST', 'Posix/Australia/Brisbane',和'Europe/Stockholm';参见填充时区表)。

更多的信息和例子,请参阅5.1.15节“MySQL服务器时区支持”,以及11.2.2节“日期,日期时间和时间戳类型”。

用于JSON模式检查约束失败的精确信息。当使用JSON_SCHEMA_VALID()指定检查约束时,MySQL 8.0.19及以后版本提供了有关此类约束失败原因的精确信息。

有关示例和更多信息,请参阅JSON_SCHEMA_VALID()和检查约束。参见章节13.1.20.6,“检查约束”。

带有ON重复键更新的行和列别名。从MySQL 8.0.19开始,可以使用别名引用要插入的行,也可以引用它的列。在8.0.18及更高版本中,MySQL将强制转换操作注入到查询项树的表达式和条件中,其中参数的数据类型和预期的数据类型不匹配。这对查询结果或执行速度没有影响,但使执行的查询等同于符合SQL标准,同时保持与以前版本MySQL的向后兼容性。

这样的隐式类型转换现在在时态类型(DATE, DATETIME, TIMESTAMP, TIME)和数值类型(SMALLINT, TINYINT, MEDIUMINT, INT/INTEGER, BIGINT;十进制/数字;浮点数、双、真实的;当使用任何标准的数值比较运算符(=,>=,>,<,<=,<>/!)=、< = >)。在这种情况下,任何不是DOUBLE类型的值都被强制转换为一个。现在还会执行强制转换注入,以比较日期或时间值和DATETIME值,其中参数在必要时被强制转换为DATETIME。

从MySQL 8.0.21开始,当比较字符串类型与其他类型时,也会执行这种类型转换。强制转换的字符串类型包括CHAR、VARCHAR、BINARY、VARBINARY、BLOB、TEXT、ENUM和SET。当将字符串类型的值与数值类型或年份进行比较时,字符串强制转换为DOUBLE;如果另一个实参的类型不是FLOAT、DOUBLE或REAL,它也会被强制转换为DOUBLE。当比较字符串类型与DATETIME或TIMESTAMP值时,字符串被转换为DATETIME;当比较字符串类型与DATE类型时,字符串被转换为DATE类型。

通过查看EXPLAIN ANALYZE、EXPLAIN FORMAT=JSON或如下所示的EXPLAIN FORMAT=TREE的输出,可以看到什么时候强制转换被注入到给定的查询中:

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;

有关更多信息和示例,请参见13.2.6.2节,“INSERT…”ON DUPLICATE KEY UPDATE Statement "。

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

TABLE语句的格式为TABLE table_name,相当于SELECT * FROM table_name。它支持ORDER BY和LIMIT子句(后者具有可选的偏移量),但不允许选择单个表列。TABLE可以在任何使用SELECT语句的地方使用;这包括join, union, INSERT…选择,替换,创建表…选择语句和子查询。例如:

TABLE t1 UNION TABLE t2等价于SELECT * FROM t1 UNION SELECT * FROM t2

CREATE TABLE t2相当于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可以用于向INSERT、REPLACE或SELECT语句提供一个表值,它由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表的value构造函数中进行选择,就像选择表一样,记住在这样做时必须提供一个表别名,并像使用其他选项一样使用这个select;这包括连接、联合和子查询。

有关表和值的更多信息,以及它们的使用示例,请参阅本文档的以下部分:

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 INDEX和IGNORE INDEX,我们计划在未来的MySQL版本中弃用它们,然后从MySQL中删除它们。它们没有实现一个完全等价的USE INDEX;相反,您可以使用一个或多个NO_INDEX、NO_JOIN_INDEX、NO_GROUP_INDEX或NO_ORDER_INDEX来达到相同的效果。

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

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


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


    还可以指定ON EMPTY、ON ERROR或both子句,类似于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()的描述。

    使用chatGPT寻求答案
    标签: 暂无标签

    免责声明:

    本站提供的资源,都来自网络,版权争议与本站无关,所有内容及软件的文章仅限用于学习和研究目的。不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负,我们不保证内容的长久可用性,通过使用本站内容随之而来的风险与本站无关,您必须在下载后的24个小时之内,从您的电脑/手机中彻底删除上述内容。如果您喜欢该程序,请支持正版软件,购买注册,得到更好的正版服务。侵删请致信E-mail:master@freevpsweb.com

    同类推荐
    评论列表