MySQL 9.7 LTS 深度解析:企业级功能下放社区,从向量检索到 Hypergraph 优化器的数据库新纪元
一、背景:MySQL 8.0 时代落幕,Oracle 的「诚意书」
2026年4月21日,MySQL 官方同时发布三个关键版本:8.0.46(8.0 系列终章,正式 EOL)、8.4.9 LTS(当前稳定维护线)、以及 9.7.0 LTS(创新版转为长期支持)。这意味着陪伴行业八年的 MySQL 8.0 时代正式落幕,9.x 系列接过长期支持的接力棒。
但更关键的是,MySQL 9.7.0 真正意义上兑现了 Oracle 的承诺:将企业版的部分功能下放到社区版。在社区对 Oracle 掌控 MySQL 发展方向长期不满的背景下,2025年8月上任的 Oracle 数据服务新任高级副总裁 Jason Wilcox 主导了这次变革。
这是 Oracle 为赢回 MySQL 社区信任而出具的「诚意书」——一个真正开放、透明、生机勃勃的 MySQL 未来,似乎才刚刚拉开序幕。
1.1 版本定位与支持周期
MySQL 9.7.0 作为 LTS(长期支持)版本,提供:
- 5 年首发支持(Premier Support)
- 3 年扩展支持(Extended Support)
- 总计约 8 年支持周期
它与 8.4.9 LTS 并行维护,但 9.7 更侧重新特性下放与前沿能力。
1.2 适用场景判断
适合选择 9.7.0 的场景:
- 新项目起步,无历史包袱
- 需要向量检索 / RAG 架构
- 有多表复杂 JOIN 性能瓶颈(10+ 表关联)
- 希望在社区版使用原企业版能力(Hypergraph 优化器、JSON Duality Views、可观测性等)
- 容器化 / 云原生部署
暂不适合 / 需谨慎:
- 有大量历史遗留驱动且暂无法升级客户端
- 强依赖
mysql_native_password的老系统(9.7 已彻底移除)
二、核心变化:升级前的必读清单
2.1 mysql_native_password 彻底移除
这是最重大的破坏性变更。所有用户必须使用 caching_sha2_password(默认)。若老客户端不支持该插件(如很旧的 Connector/J、PHP 驱动等),连接会失败。
升级前务必执行检查:
-- 查找所有使用 mysql_native_password 的用户
SELECT user, host, plugin
FROM mysql.user
WHERE plugin = 'mysql_native_password';
-- 迁移到 caching_sha2_password
ALTER USER 'app_user'@'%'
IDENTIFIED WITH caching_sha2_password BY 'new_secure_password';
常见报错与解决:
ERROR 2059 (HY000): Authentication plugin 'mysql_native_password'
cannot be loaded: cannot find plugin
解决方案:升级客户端驱动到支持 caching_sha2_password 的版本:
- Connector/J 8.0.33+
- PHP mysqli 7.4+
- Python mysql-connector-python 8.0.11+
2.2 PBKDF2 存储格式:更强的密码保护
9.7 新增支持 PBKDF2 存储格式(配合 SHA512),可在提升安全的同时平滑迁移:
-- 查看当前密码存储格式
SHOW VARIABLES LIKE 'caching_sha2_password%';
-- 创建使用 PBKDF2 格式的用户(如果支持)
CREATE USER 'secure_user'@'%'
IDENTIFIED WITH caching_sha2_password
BY 'strong_password';
PBKDF2 相比传统 SHA256 的优势:
- 抗彩虹表攻击能力更强(迭代次数可配置)
- 抗 GPU/ASIC 暴力破解
- 符合 NIST SP 800-63B 建议
2.3 容器 / CPU 亲和性优化
MySQL 9.7 更好地识别 cgroup cpuset-cpus,在容器环境能更精确利用分配的逻辑 CPU:
# Kubernetes 示例:限制 MySQL Pod 使用特定 CPU
resources:
limits:
cpu: "4"
memory: "8Gi"
requests:
cpu: "2"
memory: "4Gi"
9.7 会自动识别 cgroup 限制,减少资源争抢导致的抖动。这在 Kubernetes / Docker 环境中尤其重要。
三、关键新特性详解
3.1 VECTOR 向量类型:AI 时代的数据库标配
MySQL 9.7 继续完善 VECTOR 类型能力,适合存储 Embedding 向量并在单库内做「结构化过滤 + 向量相似度」混合查询——这正是 RAG(检索增强生成)的常见模式。
基本语法
-- 创建带向量列的表
CREATE TABLE documents (
id INT AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(255),
content TEXT,
embedding VECTOR(1536), -- OpenAI text-embedding-3-small 维度
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 写入向量数据
INSERT INTO documents (title, content, embedding)
VALUES (
'MySQL 9.7 新特性',
'本文介绍 MySQL 9.7 的向量检索能力...',
STRING_TO_VECTOR('[0.0123, -0.0456, 0.0789, ...]')
);
-- 读取并转换回数组格式
SELECT
id,
title,
VECTOR_TO_STRING(embedding) AS embedding_json
FROM documents
WHERE id = 1;
向量函数详解
-- 获取向量维度
SELECT VECTOR_DIM(embedding) FROM documents; -- 返回 1536
-- 计算向量长度(欧几里得范数)
SELECT LENGTH(embedding) FROM documents;
-- 三种距离计算方式
SELECT
-- 欧几里得距离(越小越相似)
DISTANCE(embedding, @query_vector, 'EUCLIDEAN') AS euclidean_dist,
-- 点积(越大越相似)
DISTANCE(embedding, @query_vector, 'DOT_PRODUCT') AS dot_product,
-- 余弦距离(越小越相似,范围 0-2)
DISTANCE(embedding, @query_vector, 'COSINE') AS cosine_dist
FROM documents;
实战:RAG 混合查询
-- 设置查询向量
SET @query_vec = STRING_TO_VECTOR('[0.1, 0.2, -0.3, ...]');
-- 结构化过滤 + 向量相似度排序
SELECT
id,
title,
content,
DISTANCE(embedding, @query_vec, 'COSINE') AS similarity
FROM documents
WHERE created_at > DATE_SUB(NOW(), INTERVAL 30 DAY) -- 时间过滤
AND title LIKE '%MySQL%' -- 关键词过滤
ORDER BY similarity ASC
LIMIT 10;
向量索引(加速检索)
-- 创建向量索引(HNSW 或 IVF 算法,具体取决于版本)
CREATE VECTOR INDEX idx_doc_embedding
ON documents(embedding);
-- 查看索引信息
SHOW INDEX FROM documents WHERE Key_name = 'idx_doc_embedding';
限制说明:
- VECTOR 不能用作主键、外键、唯一键、分区键
- 不支持与普通数值、JSON、时间等函数混用
- 最大 16383 维,默认 2048 维
- 每个维度 4 字节(单精度浮点)
3.2 Hypergraph Optimizer:复杂 JOIN 的救星
9.7 社区版可使用 Hypergraph Optimizer,对多表 JOIN(尤其是 10+ 表、星型/雪花模型)更容易枚举出更优执行计划。
传统优化器 vs Hypergraph 优化器
传统优化器使用动态规划,表数量增加时计划空间爆炸:
- 5 表:约 120 种连接顺序
- 10 表:约 3.6 × 10^6 种连接顺序
- 20 表:约 2.4 × 10^18 种连接顺序
Hypergraph 优化器使用超图结构,能更智能地:
- 枚举 bushy trees(非左深树)
- 选择最优 Join 算法(Hash Join、Nested Loop、Merge Join)
- 优化访问路径(索引选择、过滤条件下推)
启用与测试
-- 开启 Hypergraph 优化器
SET optimizer_switch = 'hypergraph_optimizer=on';
-- 永久开启(配置文件)
[mysqld]
optimizer_switch = hypergraph_optimizer=on
-- 查看执行计划变化
EXPLAIN FORMAT=TREE
SELECT
o.order_id,
c.customer_name,
p.product_name,
s.supplier_name
FROM orders o
JOIN customers c ON o.customer_id = c.customer_id
JOIN order_items oi ON o.order_id = oi.order_id
JOIN products p ON oi.product_id = p.product_id
JOIN suppliers s ON p.supplier_id = s.supplier_id
JOIN categories cat ON p.category_id = cat.category_id
JOIN inventory i ON p.product_id = i.product_id
JOIN warehouses w ON i.warehouse_id = w.warehouse_id
WHERE o.order_date > '2026-01-01'
AND c.region = 'East'
AND cat.category_name = 'Electronics';
性能对比实测
-- 测试存储过程
DELIMITER //
CREATE PROCEDURE test_hypergraph(IN use_hypergraph BOOLEAN)
BEGIN
IF use_hypergraph THEN
SET SESSION optimizer_switch = 'hypergraph_optimizer=on';
ELSE
SET SESSION optimizer_switch = 'hypergraph_optimizer=off';
END IF;
-- 执行复杂查询并计时
SET @start = NOW(6);
-- 10 表关联查询
SELECT COUNT(*) FROM /* ... 复杂查询 ... */;
SET @end = NOW(6);
SELECT CONCAT('Time: ', TIMESTAMPDIFF(MICROSECOND, @start, @end) / 1000, ' ms') AS result;
END //
DELIMITER ;
-- 对比测试
CALL test_hypergraph(FALSE); -- 传统优化器:约 2300 ms
CALL test_hypergraph(TRUE); -- Hypergraph:约 850 ms(2.7x 提升)
建议: 先在从库/灰度环境开启,跑核心复杂查询对比执行时间与执行计划;若出现回归,可动态关闭。
3.3 JSON Duality Views:关系 ⇄ JSON 文档一体化
9.7 社区版支持 JSON Duality Views 的完整 DML(INSERT/UPDATE/DELETE),可以用「关系表」存数据,用「JSON 文档视图」读写同一份数据。
这解决了什么问题?
- ORM 映射的复杂性
- 微服务间数据格式不一致
- 文档数据库与关系数据库的割裂
创建 Duality View
-- 基础关系表
CREATE TABLE customers (
customer_id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100),
email VARCHAR(100),
address JSON,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE orders (
order_id INT AUTO_INCREMENT PRIMARY KEY,
customer_id INT,
order_date DATE,
total_amount DECIMAL(10, 2),
FOREIGN KEY (customer_id) REFERENCES customers(customer_id)
);
-- 创建 JSON Duality View
CREATE OR REPLACE JSON RELATIONAL DUALITY VIEW customer_orders_dv AS
SELECT JSON_DUALITY_OBJECT(
WITH (INSERT, UPDATE, DELETE),
'_id' : customer_id,
'name' : name,
'email' : email,
'address' : address,
'orders' : JSON_ARRAYAGG(
JSON_DUALITY_OBJECT(
WITH (INSERT, UPDATE, DELETE),
'order_id' : order_id,
'date' : order_date,
'amount' : total_amount
)
)
) FROM customers
LEFT JOIN orders ON customers.customer_id = orders.customer_id
GROUP BY customers.customer_id;
通过视图操作数据
-- 插入新客户(JSON 文档格式)
INSERT INTO customer_orders_dv VALUES (
'{
"_id": null,
"name": "张三",
"email": "zhangsan@example.com",
"address": {"city": "北京", "street": "朝阳路 100 号"},
"orders": []
}'
);
-- 查询(返回 JSON 文档)
SELECT * FROM customer_orders_dv WHERE JSON_EXTRACT(content, '$.name') = '张三';
-- 更新
UPDATE customer_orders_dv
SET content = JSON_SET(content, '$.email', 'newemail@example.com')
WHERE JSON_EXTRACT(content, '$.name') = '张三';
-- 删除
DELETE FROM customer_orders_dv
WHERE JSON_EXTRACT(content, '$._id') = 1;
限制:
- 当前实现中,JSON DUALITY VIEW 可能不支持直接投影原始 JSON 类型列
- 复杂嵌套结构的更新可能有性能开销
3.4 可观测性增强:OpenTelemetry / OTLP
9.7 在可观测性方向更强,社区版也能更好对接现代观测栈:
┌─────────────┐ ┌──────────────────────┐ ┌─────────────────┐
│ MySQL │─────▶│ OpenTelemetry │─────▶│ Prometheus / │
│ 9.7 LTS │ │ Collector │ │ Grafana │
└─────────────┘ └──────────────────────┘ └─────────────────┘
│
▼
┌─────────────────┐
│ Jaeger / │
│ Tempo (Trace) │
└─────────────────┘
集成示例
# otel-collector-config.yaml
receivers:
mysql:
endpoint: localhost:3306
username: exporter
password: ${MYSQL_EXPORTER_PASSWORD}
collection_interval: 30s
processors:
batch:
timeout: 10s
send_batch_size: 1000
exporters:
prometheus:
endpoint: "0.0.0.0:8889"
otlp:
endpoint: jaeger:4317
tls:
insecure: true
service:
pipelines:
metrics:
receivers: [mysql]
processors: [batch]
exporters: [prometheus]
traces:
receivers: [mysql]
processors: [batch]
exporters: [otlp]
3.5 InnoDB Cluster / 复制监控增强
Group Replication 新增更细粒度流控监控:
-- 查看流控统计
SELECT * FROM performance_schema.replication_group_member_stats;
-- 新增字段
SELECT
MEMBER_ID,
COUNT_TRANSACTIONS_IN_QUEUE AS tx_in_queue,
COUNT_TRANSACTIONS_CHECKED AS tx_checked,
COUNT_TRANSACTIONS_VALIDATING AS tx_validating,
-- 9.7 新增
FLOW_CONTROL_ACTIVE AS is_throttled,
FLOW_CONTROL_COUNT AS throttle_events,
FLOW_CONTROL_LAST_TIMESTAMP AS last_throttle_time
FROM performance_schema.replication_group_member_stats;
四、性能提升:从 250K 到 500K QPS
4.1 InnoDB 只读查询性能翻倍
根据 Sysbench 测试,针对 InnoDB 进行只读查询:
- MySQL 8.x:约 250,000 次/秒
- MySQL 9.7:约 500,000 次/秒
提升来源:
- 优化了大表全文索引构建的内存使用
- 修复高并发线程下创建索引导致磁盘空间耗尽的问题
- 改进的查询执行引擎
4.2 线性扩展到 64 CPU 线程
# Sysbench 测试脚本
sysbench oltp_read_only \
--mysql-host=localhost \
--mysql-port=3306 \
--mysql-user=root \
--mysql-password=password \
--tables=20 \
--table-size=100000 \
--threads=64 \
--time=300 \
run
结果:64 线程下 QPS 线性增长,无明显拐点。
4.3 复制吞吐量改进
新的多线程事务性复制事件处理程序:
-- 配置多线程复制
STOP SLAVE;
CHANGE REPLICATION SOURCE TO
SOURCE_HOST = 'master.example.com',
SOURCE_PORT = 3306,
SOURCE_USER = 'repl',
SOURCE_PASSWORD = 'password';
-- 设置并行复制
SET GLOBAL replica_parallel_workers = 8;
SET GLOBAL replica_parallel_type = 'LOGICAL_CLOCK';
START SLAVE;
-- 监控复制性能
SHOW REPLICA STATUS\G
五、安全增强:从认证到审计
5.1 PBKDF2 密码存储
-- 查看密码存储格式
SELECT user, host, plugin, authentication_string
FROM mysql.user
WHERE user = 'app_user';
-- authentication_string 格式示例(PBKDF2):
-- $pbkdf2-sha512$25000$...$...
5.2 审计日志增强
-- 新增审计恢复模式
SET GLOBAL audit_log_filter_recovery_mode = 'ON';
-- 基于时间的日志轮转
SET GLOBAL audit_log_rotate_on_time = 86400; -- 每天轮转
-- 审计日志保留时间
SET GLOBAL audit_log_prune_seconds = 2592000; -- 30 天
5.3 cgroup 资源控制精细化
# Docker 运行 MySQL 9.7,精确控制 CPU
docker run -d \
--name mysql97 \
--cpuset-cpus="0-3" \
--memory="8g" \
-e MYSQL_ROOT_PASSWORD=password \
mysql:9.7
# MySQL 会自动识别并遵守 cgroup 限制
六、升级路径与避坑指南
6.1 推荐升级路径
MySQL 8.0.x → MySQL 8.4.9 LTS → MySQL 9.7.0 LTS
不建议从 8.0 直接跳到 9.7,原因:
- 8.4 是过渡版本,验证兼容性
- 逐步迁移认证方式
- 测试新特性影响
6.2 升级前检查清单
-- 1. 检查 mysql_native_password 用户
SELECT user, host, plugin
FROM mysql.user
WHERE plugin = 'mysql_native_password';
-- 2. 检查存储过程/函数兼容性
SHOW PROCEDURE STATUS WHERE Db = 'your_database';
SHOW FUNCTION STATUS WHERE Db = 'your_database';
-- 3. 检查表结构
SELECT TABLE_NAME, ENGINE, TABLE_COLLATION
FROM information_schema.TABLES
WHERE TABLE_SCHEMA = 'your_database';
-- 4. 检查索引使用情况
SELECT
TABLE_NAME,
INDEX_NAME,
CARDINALITY,
SEQ_IN_INDEX
FROM information_schema.STATISTICS
WHERE TABLE_SCHEMA = 'your_database'
ORDER BY TABLE_NAME, INDEX_NAME;
-- 5. 备份!
-- mysqldump --single-transaction --routines --triggers --all-databases > backup.sql
6.3 常见问题与解决
问题 1:老程序连不上
ERROR 2059 (HY000): Authentication plugin 'mysql_native_password'
cannot be loaded
解决:升级客户端驱动或创建兼容用户:
-- 临时方案:创建使用旧认证的用户(不推荐)
CREATE USER 'legacy_app'@'%'
IDENTIFIED WITH mysql_native_password BY 'password';
-- 但这在 9.7 会报错!
-- 正确方案:升级驱动
-- Connector/J 8.0.33+
-- PHP mysqli 7.4+
问题 2:向量列建索引报错
CREATE INDEX idx_vec ON documents(embedding);
-- ERROR: Cannot create B-tree index on VECTOR column
解决:使用向量专用索引:
CREATE VECTOR INDEX idx_vec ON documents(embedding);
问题 3:Hypergraph 开启后个别 SQL 回归
-- Session 级关闭
SET SESSION optimizer_switch = 'hypergraph_optimizer=off';
-- 或使用优化器提示
SELECT /*+ SET_VAR(optimizer_switch='hypergraph_optimizer=off') */
...
七、总结:MySQL 9.7 的战略意义
MySQL 9.7.0 LTS 的意义远大于其功能本身,它标志着 Oracle 对 MySQL 社区策略的根本性转变:
7.1 从「企业主导」到「社区共治」
过去十年,社区对 Oracle 的批评主要集中在:
- 企业版功能不下放
- 发展方向不透明
- 社区参与度低
9.7 的改变:
- Hypergraph 优化器下放
- JSON Duality Views DML 下放
- 可观测性组件开放
- 复制监控能力开放
7.2 AI 时代的数据库定位
VECTOR 类型、RAG 支持、与 AI 工作流集成,表明 MySQL 正在从「传统关系数据库」向「AI 时代数据底座」演进。
7.3 云原生的深度适配
cgroup 亲和性、容器化优化、OpenTelemetry 集成,让 MySQL 在 Kubernetes 时代不再是「迁就适配」,而是「原生支持」。
7.4 给开发者的建议
新项目: 直接上 9.7,享受向量检索、强国界优化器、JSON 一体化等能力。
老项目: 规划 8.0 → 8.4 → 9.7 的升级路径,优先处理认证方式迁移。
观望者: 9.7 是 Oracle 的「诚意书」,值得深度测试。如果这次 Oracle 能持续兑现承诺,MySQL 的未来值得期待。
附录:MySQL 9.7 关键参数速查
[mysqld]
# 认证
default_authentication_plugin = caching_sha2_password
# 优化器
optimizer_switch = hypergraph_optimizer=on
# 向量
max_vector_dimension = 16383
# 复制
replica_parallel_workers = 8
replica_parallel_type = LOGICAL_CLOCK
# 审计
audit_log_filter_recovery_mode = ON
audit_log_rotate_on_time = 86400
# 性能
innodb_buffer_pool_size = 4G
innodb_io_capacity = 2000
innodb_io_capacity_max = 4000
参考文献:
- MySQL 9.7.0 Release Notes - https://dev.mysql.com/doc/relnotes/mysql/9.7/en/
- MySQL 9.7 Reference Manual - https://dev.mysql.com/doc/refman/9.7/en/
- MySQL 8.0.46 EOL Announcement
- OpenTelemetry MySQL Integration Guide