MySQL 创新版9.1.0 于2024年10月15日正式发布。我们一起看看 9.1 版本都有哪些变化呢?关于 MySQL 的迭代版本可以参考:技术译文 | 一文了解 MySQL 全新版本模型
原子DDL 能力增强
-
当 CREATE DATABASE 在创建数据库目录之后但在实际提交操作之前失败时,数据字典没有数据库存在的记录,但数据库目录仍然存在于文件系统中,因此需要手动清理。
-
当由于文件系统错误或意外关闭而无法成功删除作为 DROP DATABASE 一部分的数据库目录时,包含 DROP DATABASE 的事务并不总是回滚;在这种情况下,需要人工干预来纠正问题。
9.1 版本中,只要受影响的数据库中的所有表都使用支持原子数据定义语句的存储引擎(例如 InnoDB),那么create database,drop database 是完全原子的。
详细的信息请查看 https://dev.mysql.com/doc/refman/9.1/en/atomic-ddl.html
审核日志注释
审计日志将名称不以字母数字字符(如"$foo")开头的用户视为无效用户,尽管 MySQL 服务器允许创建此类用户。
SQL 函数和运算符说明
当同时使用 DISTINCT 时,在某些情况下,对于相同的值,SUM() 会产生不同的结果。例如:
mysql> SELECT SUM(b'1100'), SUM(DISTINCT b'1100');
+--------------+-----------------------+
| sum(b'1100') | sum(DISTINCT b'1100') |
+--------------+-----------------------+
| 12 | 9 |
+--------------+-----------------------+
原因是,在使用 DISTINCT 时,使用临时表来保存值,以便最终仅将唯一值返回给用户。在设置 DISTINCT 时创建此类表时,我们没有考虑数据类型和长度已经确定,而是重新计算它们。现在我们使用已经确定的数据类型和长度。(Bug #115476, Bug #36796197)
SQL语法:
SELECT test. dat . A FROM (SELECT 1 as A) as Dt
使用如下格式 db_name.tbl_name
标识派生表中的列。尽管这种行为与SQL标准矛盾,但该参照也在表达式中被错误地接受了。现在不允许使用这样的列引用。
在此版本中增加了对 IF NOT EXISTS
子句与CREATE VIEW
语句一起使用的支持。IF NOT EXISTS
的作用如下:
如果语句中指定的视图不存在,视图像往常一样被创建。如果视图已经存在,则语句将显示成功,但不会更改视图定义,并且产生一个警告,如下所示:
mysql> CREATE VIEW v1 AS SELECT c1, c3 FROM t1;
Query OK, 0 rows affected (0.01 sec)
mysql> CREATE VIEW v1 AS SELECT c2 FROM t1;
ERROR 1050 (42S01): Table 'v1' already exists
mysql> CREATE VIEW IF NOT EXISTS v1 AS SELECT c2 FROM t1;
Query OK, 0 rows affected, 1 warning (0.01 sec)
mysql> SHOW WARNINGS;
+-------+------+---------------------------+
| Level | Code | Message|
+-------+------+---------------------------+
| Note | 1050 | Table 'v1' already exists |
+-------+------+---------------------------+
1 row in set (0.00 sec)
mysql> SHOW CREATE VIEW v1\G
*************************** 1. row ***************************
View: v1
Create View: CREATE ALGORITHM=UNDEFINED DEFINER=`vuser`@`loca
lhost` SQL
SECURITY DEFINER VIEW `v1` AS select `t1`.`c1` AS `c1`,`t1`.`c3` AS `c
3` from `t1`
character_set_client: utf8mb4
collation_connection: utf8mb4_0900_ai_ci
1 row in set (0.00 sec)
IF NOT EXISTS
与 OR REPLACE
不兼容,并且这两个从句不能同时使用 CREATE VIEW
语句。尝试这样做会导致语句将以语法错误被拒绝。
触发器优化
性能:以前,对于具有一个或多个触发器的表,每次访问该表时,都会完全解析触发器并将其加载到内存中。这通常会导致意外的高资源使用率和/或涉及/或复杂触发器且未更改数据的方案中不合理的长执行时间。它还导致只读副本上不必要的资源使用。
我们通过将触发器的解析和加载分为两个独立的阶段来解决这个问题:在第一阶段,我们只读取触发器元数据,因为该元数据可以存储一次并在同一触发器的不同实例之间共享。触发器的实际解析和执行在第二阶段完成,该阶段仅对修改 table 数据的操作执行;这样可以节省资源,因为我们不再解析和缓存在执行 SELECT 语句等时不使用的触发器。
话说 ,目前在 MySQL 中使用触发器的用户还多吗?业务逻辑放到数据库中会带来哪些好处和坏处呢?
向量数据类型
STRING_TO_VECTOR()
函数现在允许在 VECTOR 参数的字符串表示形式中使用尾随空格。解析器现在会修剪数字之后、方括号之前、方括号之后或这些值的任意组合中的空白字符。下面显示了以前不支持但现在允许的值的一些示例:
"[1 ,2]" "[1 ,2]"
"[1,2 ]" "[1,2 ]"
" [1,2]" " [1,2]"
"[1,2] " "[1,2] "
添加或更改的功能
-
现在,在逻辑处理器少于 32 个的系统上,
innodb_log_writer_threads
的默认值为 OFF。(WL #16396) -
对于捆绑了 OpenSSL 库的平台,链接的 OpenSSL 库 for MySQL Server 已更新到版本 3.0.15。
-
用于跟踪二进制日志事务依赖关系的数据结构已从 Tree 更改为 ankerl::unordered_dense::map,它使用的空间减少了大约 60%,因此应该有助于提高依赖关系跟踪性能。(错误 #37008442)
-
组复制:在以下情况下添加了新的 INFO 级别日志记录消息:
当操作在所有节点上开始时
当在等待操作完成时阻止发送消息时
当收到消息并且内部消息计数器递减时 -
为 mysql 客户端添加了 --system-command 选项,用于启用或禁用系统客户端命令。默认情况下,此选项处于禁用状态,这意味着 system 命令将被拒绝并显示错误。要启用它,请使用 --system-command=ON。(错误 #36377685、WL #16482)
-
此版本实现了以下两个状态变量,用于跟踪从内存中到磁盘的内部临时表转换:
TempTable_count_hit_max_ram
计算由于达到 TempTable 存储引擎的temptable_max_ram
限制而导致的内存到磁盘表转换的次数。这只是一个全局状态变量。Count_hit_tmp_table_size
计算由于达到 TempTable 存储引擎的tmp_table_size
限制或使用 MEMORY 存储引擎达到较小的值tmp_table_size
和max_heap_table_size
而导致的内存到磁盘转换的次数。这既是全局变量,也是会话状态变量。 -
最大
TOTAL_ROW_VERSION
S 值从 64 更改为 255。通过使用INSTANT ALGORITHM
执行ADD COLUMN
和DROP COLUMN
操作,该值将递增。(WL #16369)
鸡肋的 INSTANT DDL 有福了,虽然不多。9.1 版本之前,INSTANT使用64次就会报错,现在增加了使用次数。
关于该限制的文章介绍请参考 :64次更改极限!MySQL DBA如何巧妙规避即时DDL操作的陷阱?
使用 INSTANT DDL 的朋友也请关注BUG: 使用 INSTANT 算法删除列后执行 DELETE 或 UPDATE 语句时,MySQL 服务器可能会意外停止。(错误 #36723117)
-
MySQL 的 OpenTelemetry 日志记录使您能够将遥测日志从 MySQL 服务器导出到 OpenTelemetry 后端进行分析。此功能通过以下方式实现:
遥测日志记录组件:(仅限 MySQL Enterprise Edition 和 MySQL HeatWave)从服务器收集检测的日志事件,将其格式化为 OpenTelemetry 的 OTLP 格式,并将日志导出到外部进程。此进程可以是 OpenTelemetry 收集器或任何其他与 OpenTelemtry 兼容的后端。如果要导出到多个后端,则必须使用 OpenTelemetry 收集器。
遥测日志记录接口:(MySQL Community Server、Enterprise Edition 和 MySQL HeatWave)一个 API,使您能够定义和集成自己的 OpenTelemetry Logging 组件。通过此接口,可以发现可用的日志记录检测、启用记录器、生成记录并提取关联的跟踪上下文。该接口不提供日志记录。您必须使用 MySQL 企业版、MySQL HeatWave 或开发自己的组件来提供日志记录。
EXPLAIN 相关
-
为了输出的一致性,当
explain_json_format_version=2
时,在EXPLAIN FORMAT=JSON
lookup_condition
显示的条件中,在 = 符号前后添加了空格,以及使用EXPLAIN FORMAT=TREE
时为操作显示的空格。 -
EXPLAIN FORMAT=TREE
的输出现在包含有关使用的 semijoin 策略的信息(如果有)。 -
当
explain_json_format_version
设置为 2 时,每当 MRR 用于 MRR 和索引范围扫描访问路径时,向 EXPLAIN FORMAT=JSON 输出添加了multi_range_read:true
。此外,(Multi-Range Read) 现在显示在EXPLAIN FORMAT=TREE
输出的 operation 字段中,用于使用 MRR 进行索引范围扫描。(错误 #36614948) -
现在可以在服务器启动时使用 performance-schema-meter 参数从命令行或配置文件启用或禁用遥测仪表。
总体看下来,除了 INSTANT DDL 支持次数的改善,其他值得关注的点不是很多,大家可以查看原文地址,关注更细节的东西,比如bug。