作者:宋华雄
AliSQL 开源版 8.0.44-2 正式发布。
这个版本基于 MySQL 8.0.44,将 DuckDB 升级到了 v1.4.4,同时加入原生向量索引 VIDX、Native Flashback、Persist Binlog Into Redo 和 Binlog Cache Free Flush。
图 1:AliSQL 8.0.44-2 主要功能概览
这次更新有五个重点:
DuckDB 分析引擎继续增强:升级到 v1.4.4,并完善 MySQL 语法兼容、DDL、复制和资源控制,修复了一批稳定性问题。
原生向量索引 VIDX:新增
VECTOR类型和 HNSW 索引,可以直接检索 InnoDB 表中的向量数据,支持欧氏距离和余弦距离。Native Flashback:通过
AS OF TIMESTAMP读取历史数据,利用保留的 InnoDB Undo 还原指定时间点可见的行版本。Persist Binlog Into Redo:将符合条件的 Binlog Event 写入 InnoDB Redo,减少事务提交时等待磁盘同步的次数;崩溃恢复时,还可以从 Redo 补齐缺失的 Binlog 尾部。
Binlog Cache Free Flush:面向 InnoDB 大事务,避免提交时再次完整复制 Binlog Cache 文件,降低额外 I/O,减少大事务对其他事务提交的阻塞。
DuckDB:MySQL 协议下的分析引擎
AliSQL 将 DuckDB 作为分析型存储引擎直接嵌入 Server 进程。应用不需要另外连接一套分析服务,就能通过现有的 MySQL 连接使用 DuckDB 的列式执行能力。我们在一台 32 核、128 GB 内存的机器上运行了 TPC-H SF100 测试,其中 DuckDB 的多项查询比 InnoDB 快 200 倍以上。
应用侧的接入方式没有变化:客户端仍然使用 MySQL 协议,鉴权、连接管理和 SQL 解析继续由 MySQL 服务层负责。完成必要的语法兼容处理后,分析查询交给 DuckDB 执行;事务表、系统表和数据字典仍由 InnoDB 管理。
图 2:DuckDB 作为分析型存储引擎嵌入 AliSQL,应用继续使用 MySQL 协议
DuckDB 有两种常见的部署方式。在同一个 AliSQL 实例里,InnoDB 表和 DuckDB 表可以共用 MySQL 入口;需要隔离事务和分析负载时,则由 InnoDB 主库处理在线事务,DuckDB 分析节点通过 Row 格式的 Binlog 同步数据,负责扫描、聚合和 Join 等查询。
图 3:分析查询访问 DuckDB 分析节点,数据变化通过 Row Binlog 从 InnoDB 主库同步
独立部署后,分析查询使用的 CPU、内存和 I/O 不再占用主库的资源,业务侧仍然使用熟悉的 MySQL 协议。目前,这套架构已经运行在 1,000 多个 RDS MySQL 生产节点上。本次发布也合入了我们在生产中积累的优化,主要涉及复制延迟、DDL 稳定性、资源控制和重启恢复。
这次 DuckDB 部分还增加了以下能力:
SQL Normalization覆盖了更多 MySQL 语法和函数,包括跨库引用和时间表达式,并补上 Prepared Statement 的自动 reprepare。支持将包含生成列的表转换为 DuckDB,增加 Latin1 字符集支持,并修复部分数据类型的默认值处理。
用户查询和复制任务可以分别设置 DuckDB Worker 线程上限,避免数据同步抢占前台分析资源。
DuckDB 表之间执行 COPY DDL 时,可以选择
INSERT ... SELECT,不再经过 handler 逐行搬运数据,从而缩短 DDL 执行时间。提供可选的 DECIMAL 高精度计算方式,并降低复制过程的 CPU 开销。
此外,这一版本还修复了一批可能导致 mysqld crash 的问题,对复制链路也作了进一步完善。
VIDX:在 InnoDB 数据上做向量检索
这个版本加入了原生向量索引 VIDX。用户可以直接在 InnoDB 表中定义VECTOR(N)字段并创建 HNSW 索引,不必先把业务数据同步到独立的向量数据库。
图 4:一条 SQL 可以同时使用 HNSW 搜索、向量距离排序和普通字段过滤
VECTOR(N)用来保存固定维度的浮点数组,目前最高支持 16,383 维。向量和普通业务字段可以放在同一张 InnoDB 表里。创建索引后,HNSW 图会保存在 InnoDB 辅助表中,每一行记录一个图节点及其邻接关系。
查询时,HNSW 先在高层图中快速定位,再进入第 0 层扩大搜索范围。索引参数M决定每个节点维护多少条连接,vidx_hnsw_ef_search决定查询时保留多少个候选。候选越多,通常越容易获得更高的召回率,但需要计算的距离和访问的节点也会随之增加。
为了避免每次查询都从辅助表重新读取图节点,VIDX 使用了两级缓存。只读事务共享挂在TABLE_SHARE上的节点缓存;读写事务则使用会话私有缓存,先保存本事务访问和修改的节点,提交后再更新共享缓存。图数据和缓存更新都遵循 InnoDB 的事务规则。
优化器会根据代价决定是否使用向量索引,也可以通过 Index Hint 明确指定。HNSW 找到候选节点后,执行器继续完成普通字段过滤和距离排序。在支持的 CPU 上,距离计算会使用 SIMD 指令;搜索过程中还会借助 Bloom Filter 减少重复的候选检查。
下面是一条简化后的余弦距离查询:
SELECT id, content, VEC_DISTANCE_COSINE( embedding, VEC_FROMTEXT('[0.1,0.2,0.3]') ) AS distance FROM documents ORDER BY distance LIMIT 10;目前只有 InnoDB 表可以创建向量索引,并且会话隔离级别必须设置为READ COMMITTED。HNSW 建图时会使用随机和启发式算法,因此即使两个节点的数据完全相同,生成的图结构也不一定逐字节一致。
VIDX 默认关闭,启用方法、索引参数和使用限制可以查阅后文链接中的 VIDX 文档。
Native Flashback:直接读取历史一致性视图
发生误更新或误删除后,常见的处理方式是使用备份集恢复,再把 Binlog 回放到出错前的时间点。但是准备恢复环境、重建数据,往往都需要不少时间。
Native Flashback 可以直接查询保留在 InnoDB 中的历史版本,不必依赖备份恢复。后台任务会定期记录事务可见性快照,并保留相应的 Undo。快照只保存构造历史 Read View 所需的信息,具体的旧行内容仍然从 Undo 中读取。
执行AS OF TIMESTAMP查询时,AliSQL 先确定要查询的时间点,再从已有快照中找到符合时间差要求的 Read View。随后,InnoDB 按照 MVCC 规则沿 Undo 链查找当时可见的行版本,整个查询仍然走 InnoDB 的一致性读。
图 5:AliSQL 根据事务可见性快照和保留的 Undo 读取历史行版本
SELECT id, status FROM orders AS OF TIMESTAMP DATE_SUB(NOW(), INTERVAL 5 MINUTE) WHERE customer_id = 1001;查询时间和最终选中的快照时间可能存在少量偏差,参数innodb_rds_flashback_allow_gap用来设置允许的最大时间差。要保留可查询的历史版本,需要开启 Flashback 快照任务,并把 Undo Retention 设置为非零值。
Native Flashback 很适合在误操作后快速核对数据。如果需要找回数据,可以先把查询结果写入独立表,确认行数和业务约束无误后再回写。
AliSQL 的 Native Flashback 功能目前仅支持查询 InnoDB 基表,不支持临时表、视图和锁定读。需要注意的是: Undo 空间不足会缩短实际可查询的时间范围;如果 DDL 调整了相关表的主键,旧快照也可能无法读取;另外 Native Flashback 用于历史数据查询,不能替代备份、Binlog 和容灾方案。
Persist Binlog Into Redo:优化 Binlog 持久化路径
Persist Binlog Into Redo(也称 Binlog in Redo)包含两步优化:先把 Binlog Sync 移到后台,再进一步把 Binlog Write 也交给后台线程。
Binlog Sync 后台化
通常,事务提交时既要同步 InnoDB Redo,也要同步 Binlog,前台需要等待两次磁盘同步。开启 Persist Binlog Into Redo 后,符合条件的 Binlog Event 会先写入 Redo。Redo 同步完成时,数据修改和对应的 Binlog 内容都已经落盘;前台完成 Binlog Flush 后即可提交,Binlog Sync 则交给后台 Syncer Thread。
图 6:前台提交只需要等待 Redo Sync
这项优化不会取消 Binlog 文件,复制和恢复仍然照常使用 Binlog。发生崩溃时,如果 Binlog 文件尾部落后于已经落盘的 Redo,AliSQL 会先从 Redo 中补齐缺失的 Binlog,再继续恢复。这个过程与根据 Redo 恢复 InnoDB Page 的思路是相似的。
Binlog Write 后台化
在 Binlog Sync 后台化的基础上,AliSQL 进一步把 Binlog Write 也移出前台提交过程。原本串行执行的事务提交和 Binlog 写入可以并行进行,在小事务高并发场景下可以减少 Binlog 写入带来的等待。
图 7:Binlog Write 后台化
参数wait_binlog_flush决定 Commit 返回前是否等待对应内容写入 Binlog 文件。它是一个可选项:即使设置为ON,等待的也是 Binlog Write,而不是 Binlog Sync;符合条件的事务仍然依靠已经同步的 Redo 完成崩溃恢复。
并不是所有事务都会启用这项优化。只有 Redo 能同时保证数据和 Binlog 已经落盘,并且提交顺序不受影响时,AliSQL 才会使用 Binlog in Redo,其他事务仍然走普通的 Binlog Group Commit。
Binlog Cache Free Flush:减少大事务的重复写入
事务的 Binlog Cache 超过内存阈值后,会写入临时文件。按普通方式提交时,这个临时文件还要再完整复制到正式 Binlog 中。复制期间会持续持有 Binlog 锁,后续小事务只能等待;大事务足够大时,实例会在较长时间内无法完成新的写事务提交。
图 8:大事务复制临时 Cache 文件期间持续持有 Binlog 锁,后续小事务只能排队等待提交。
Free Flush 在创建 Cache 文件时就预留好 Binlog 文件头的位置。提交时只需补齐文件头和尾部,再把文件直接重命名为新的 Binlog,不必重新复制整份数据。
图 9:普通路径需要再次复制 Cache 文件;Free Flush 补齐文件头尾后直接 Rename。
AliSQL 会在提交时自动判断是否使用 Free Flush,不需要应用改变事务写法。对于只涉及 InnoDB 的大事务,如果 Binlog Cache 状态、加密设置和 Statement Cache 等条件都满足,就会直接补齐 Cache 文件并完成重命名;否则仍按原来的 Group Commit 提交。
是否使用 Free Flush 只看当前事务,与实例是否支持 DuckDB 无关。如果同一个事务还写入了 DuckDB,DuckDB 会作为额外的 2PC 参与者,当前版本仍使用普通 Group Commit。这不会影响事务提交,只是暂时用不到 Free Flush 的性能收益。后续版本会继续完善 DuckDB 事务的大事务优化。
MySQL + DuckDB 正在得到更多关注
我们开始把 DuckDB 引入 MySQL 存储引擎层时,这条路线还很少有人尝试。最近,MariaDB 和 Percona 也公布了各自的实现。
MariaDB 发布了新的 DuckDB Storage Engine,可以在同一个 MariaDB Server 中创建ENGINE=DuckDB表,探索 InnoDB 与 DuckDB 的混合使用。Percona 也展示了一个基于 MySQL 9.7 的实验性实现,同样尝试在 MySQL 进程内把分析查询交给 DuckDB。几种方案的实现细节不同,但思路很接近:保留 MySQL 已有的协议、工具和使用习惯,再用 DuckDB 承担分析查询。我们很早就开始实践这条路线,也已经将它用于规模化生产。接下来,AliSQL 会继续优化复制、DDL、资源隔离和故障恢复,也期待与 MariaDB、Percona 和 DuckDB 社区交流各自的实现经验。
试用新版本
这次发布提供 Linux x86_64 和 ARM64 预编译包,Docker 镜像也同时支持linux/amd64和linux/arm64。
docker pull songhuaxiong/alisql:8.0.44-2相关入口:
发布主页:AliSQL 8.0.44-2 Released
GitHub Release:https://github.com/alibaba/AliSQL/releases/tag/AliSQL-8.0.44-2
AliSQL 源码:https://github.com/alibaba/AliSQL
Docker 镜像:https://hub.docker.com/r/songhuaxiong/alisql/tags?name=8.0.44-2
中文发布说明:https://github.com/alibaba/AliSQL/blob/AliSQL-8.0.44-2/wiki/changes/changes-in-alisql-8.0.44.2026-06-30-zh.md
English Release Notes:https://github.com/alibaba/AliSQL/blob/AliSQL-8.0.44-2/wiki/changes/changes-in-alisql-8.0.44.2026-06-30-en.md
开源功能文档:
DuckDB 分析引擎:https://github.com/alibaba/AliSQL/blob/AliSQL-8.0.44-2/wiki/duckdb/duckdb-zh.md
原生向量索引 VIDX:https://github.com/alibaba/AliSQL/blob/AliSQL-8.0.44-2/wiki/vidx/vidx\_readme\_zh.md
Native Flashback:https://github.com/alibaba/AliSQL/blob/AliSQL-8.0.44-2/wiki/native-flashback/native-flashback-zh.md
Persist Binlog Into Redo:https://github.com/alibaba/AliSQL/blob/AliSQL-8.0.44-2/wiki/binlog-in-redo/binlog-in-redo-zh.md
Binlog Cache Free Flush:https://github.com/alibaba/AliSQL/blob/AliSQL-8.0.44-2/wiki/binlog-cache-free-flush/binlog-cache-free-flush-zh.md
技术分析:
Persist Binlog Into Redo(上篇):https://zhuanlan.zhihu.com/p/550304300
Persist Binlog Into Redo(下篇):https://zhuanlan.zhihu.com/p/569062814
阿里云 RDS MySQL 也提供了这些能力,对应的产品文档如下:
DuckDB 分析实例:DuckDB分析实例-云数据库 RDS(RDS)-阿里云帮助中心
向量存储:RDS MySQL向量存储-云数据库 RDS(RDS)-阿里云帮助中心
Native Flashback:使用Native Flashback查询和恢复因误操作丢失的数据-云数据库 RDS-阿里云-云数据库 RDS(RDS)-阿里云帮助中心
Binlog in Redo:Binlog in Redo-云数据库 RDS(RDS)-阿里云帮助中心
Binlog Cache Free Flush:大事务提交优化-云数据库 RDS(RDS)-阿里云帮助中心
RDS MySQL 与开源 AliSQL 在支持版本、参数和部署方式上并不完全相同,具体差异可以查看对应的产品文档。
欢迎试用 AliSQL 8.0.44-2。遇到问题可以直接在 GitHub 提 Issue;如果你有实际业务场景或压测结果,也欢迎和我们交流。后续版本还会继续优化 DuckDB 复制、大事务处理和 SQL 兼容性。