MySQL 9.7.2:LOAD DATA 残留 NULL 状态、POW(NULL) 返回 1 等会真踩到的修复
MySQL 9.7.2(2026-07-28)里,下面这些行为修复会在生产查询或升级过程中直接表现为报错、错行或结果截断。
LOAD DATA 写入 NOT NULL 列后,同会话 INSERT 报 1263 / 1048
LOAD DATA 解析输入行时会把字段临时标记为可空。如果某一行给 NOT NULL 列提供了 NULL,LOAD DATA 在返回到同一线程之前,可能把字段的临时 NULL 状态留在表上。同一会话随后的 INSERT 会把合法非 NULL 值当成 NULL,返回 ER_BAD_NULL_ERROR:
ERROR 1263 (22004): Column set to default value; NULL supplied to NOT NULL column 'b' at row 1
ERROR 1048 (23000): Column 'b' cannot be null
(Bug #118060, #38939847)
POW() 传 NULL 指数返回 1
POW() 的指数为 NULL 时,错误地返回 1 而不是 NULL。(Bug #120779, #39641087)
NULL 传播被破坏后,POW(x, NULL) 参与的比较与聚合都会偏离预期。
IN 谓词含 DATE / TIME 常量时匹配到无关字符串
IN 谓词里包含 DATE 或 TIME 常量时,一个不在列表任何元素中的非时间字符串可能被判定为 true,把无关行带进结果集。(Bug #120787, #39649755)
AVG(ASCII(...)) 配合 SQL_BUFFER_RESULT 结果被截断
AVG() 作用于 ASCII() 等函数时,如果同时使用 SQL_BUFFER_RESULT,返回值可能被截断——小数精度计算没有为符号位预留空间。现在精度计算会考虑有符号值,255.0000 这类结果不再被截断。(Bug #120465, #39392429)
JSON 关系对偶视图更新改为先删后插
从嵌套子基表中删除行的 JSON 对偶视图更新,可能违反外键约束。更新处理现在先按反向绑定顺序执行删除,再执行插入和更新。(Bug #39566804)
从 8.x 升级数千对象时的内存持续增长
带着数千张表、视图、存储过程和事件从较早的 8.x 升级时,服务器内存占用会持续增长,造成明显的内存尖峰。该版本改进了内存管理。(Bug #117983, #37832455, #38031020)
hypergraph optimizer 的几处修复
SELECT DISTINCT ... LIMIT:基于物化的去重会先处理完所有 distinct 行再应用 limit;现在把限制传给去重环节,可以提前停止。由 SQL_BIG_RESULT 强制走的基于排序的 DISTINCT 行为不变。(Bug #36720017)- BETWEEN 常量边界:精确索引范围扫描之上会出现多余的 filter;现在识别为精确范围并移除该 filter。(Bug #37152269)
- Hash join:低 LIMIT 查询可能产生不必要的落盘 I/O;优化器现在也会考虑内存 hash join。(Bug #36684053)
- ORDER BY 中的非确定性表达式:使用带副作用的存储函数或 RAND() 这类非确定性函数时,每行可能被求值多次;现在排序前先物化行。(Bug #36578540)
- ORDER BY + 低 LIMIT + 复合索引反向范围扫描:优化器过早移除排序时可能返回错误结果。(Bug #119198)
- 索引列 IS NULL 过滤 + 同列 ORDER BY:可能做多余的 filesort;IS NULL 现在作为常量条件参与 order-by 简化。(Bug #119442)
- 唯一索引上的 FORCE INDEX + IS NULL:仍会做 index dive,现在跳过。(Bug #117791)
GROUP BY ... WITH ROLLUP:常量表达式配合空的USE INDEX FOR GROUP BY()hint 可能触发 assert;优化器现在识别常量分组不需要索引排序。(Bug #39505077)
线程池默认保留的空闲线程数从 2 增到 32
thread_pool_max_unused_threads 的默认值由 2 改为 32。(Bug #39405207)
其他需要注意的行为变更
- INSERT() 处理多字节字符时,位置超出输入字符串仍会插入字符。(Bug #113962)
- TIMESTAMPDIFF() 在带 WHERE 子句时返回意外结果。(Bug #108143)
- JSON_VALUE() 使用 RETURNING DATETIME 和 DEFAULT 时,在 DATE 上下文中可能返回无效的常量日期。(Bug #120788)
- 关键字定义修正:CUBE、EXTERNAL、QUALIFY、TABLESAMPLE 为保留字;MANUAL、PARALLEL 为非保留字。(Bug #114874)
- 复制:
SOURCE_RETRY_COUNT=0在各重连路径上统一视为无限重试;此前在后续出现瞬时连接丢失时可能停止重试。(Bug #39086875) - 打包:不再支持 Enterprise Linux 7。
- 计划移除的弃用复制系统变量:
group_replication_communication_stack、group_replication_ip_allowlist。(WL #17300)
升级时注意
- 遇到 1263 / 1048 时,确认是否由 LOAD DATA 后残留的临时 NULL 状态引起;临时规避是出现该报错后重新建立会话,正式修复在 9.7.2。
- 对象数量达数千的 8.x 实例,升级前先确认目标版本已包含上述内存修复。
- 依赖
POW(x, NULL) = 1、或依赖 IN 谓词对非时间字符串旧匹配行为的查询,需要复核结果。 - 把 CUBE、EXTERNAL、QUALIFY、TABLESAMPLE 当标识符使用的语句要加反引号。
- 复制拓扑中使用
SOURCE_RETRY_COUNT=0的实例,重试语义已统一为无限重试。 - Enterprise Linux 7 已不再支持,升级前先迁移运行平台;两个
group_replication_*变量在移除前完成替换。