AliSQL 中的 DuckDB 分析
AliSQL 通过 MySQL 存储引擎接口集成 DuckDB,应用仍可使用 MySQL 协议和 SQL 入口。当前 AliSQL 8.0.44-2 集成 DuckDB 1.4.4。
为什么选择 DuckDB
DuckDB 提供适合扫描、连接和聚合的列式存储与向量化执行。AliSQL 集成这些能力后,应用无需改用另一套数据库协议或查询入口。
InnoDB 仍然是事务引擎。DuckDB 用于分析表和分析副本。
集成架构
AliSQL 负责以下工作:
- 转换支持的 MySQL SQL,并映射函数;
- 转换 MySQL 与 DuckDB 的数据类型和结果;
- Native DDL 和 Copy DDL 执行;
- InnoDB 到 DuckDB 的表转换;
- 重放 Row-based Binlog,处理批量应用、GTID 与幂等恢复;
- 查询线程与复制线程的资源管理。
查询路径
MySQL Server 先解析请求,再将支持的 SQL 交给 DuckDB。AliSQL 在执行前转换语法、函数和类型,执行后将结果转换为 MySQL 可返回的格式。因此,共用 MySQL 协议并不代表完全兼容 MySQL SQL 与数据类型。
启用引擎
duckdb_mode 在服务启动后为只读:
[mysqld]
duckdb_mode=ON
duckdb_memory_limit=2147483648
duckdb_threads=0
duckdb_temp_directory=/path/to/duckdb-tmp
通过 SQL 创建或转换表:
CREATE TABLE sales (
id BIGINT PRIMARY KEY,
region VARCHAR(32),
amount DECIMAL(18,2)
) ENGINE=DuckDB;
ALTER TABLE existing_innodb_table ENGINE=DuckDB;
加载数据前,请先确认以下资源配置:
| 变量 | 默认值 | 说明 |
|---|---|---|
duckdb_mode | NONE | 只能在启动时设置;使用 ON 启用引擎 |
duckdb_require_primary_key | ON | 复制到 DuckDB 节点时要求源表具有主键;DuckDB 不会将该逻辑主键强制实现为索引 |
duckdb_memory_limit | 0 | 自动设置,通常约为物理内存的 80%;需和 InnoDB Buffer Pool 一起规划 |
duckdb_threads | 0 | 自动设置 DuckDB 工作线程总数 |
duckdb_temp_directory | 空 | 临时溢出文件的静态位置 |
duckdb_max_temp_directory_size | 0 | 自动设置,通常约为可用磁盘空间的 90% |
duckdb_max_threads_per_query | 1000000 | 单条查询可用的工作线程上限;实际值应低于线程池总数 |
自动计算的内存和临时空间不能直接作为生产配置。请设置明确的资源预算,并为 InnoDB、MySQL Server、操作系统和并发查询预留余量。
分析副本
专用 DuckDB 节点可以重放 InnoDB 主库产生的 Row-based Binlog,从而隔离分析负载与对延迟敏感的事务流量。
DuckDB 不提供 MySQL 两阶段提交接口,因此 AliSQL 提供专用的重放、提交和恢复协议。对于包含大量小事务的负载,批量应用可能提高吞吐量。
性能参考
已发布的 TPC-H SF100 参考测试使用 32 vCPU、128 GB 的 ECS 实例和 500 GB ESSD PL1 磁盘。在该特定环境中,若干已完成查询被报告为比 InnoDB 快 200 倍以上。
原始材料没有完整记录缓存状态、运行次数等复现条件。部分查询因超时或内存不足而未完成,因此这些数据只能作为特定环境下的参考,不能视为通用加速比或性能保证。
使用限制
- 将对延迟敏感的事务写入保留在 InnoDB 上。
- DuckDB 只支持 AliSQL 已实现的 MySQL SQL 语义;上线前请验证函数、类型、排序规则和 DDL。
- 为复制的分析表启用
duckdb_require_primary_key。 - DuckDB 不会在物理层强制执行 MySQL 主键和唯一索引;源数据必须保持唯一性。
- 使用 AliSQL 支持的 Row-based Binlog 复制路径,不要绕过其恢复逻辑。
duckdb_use_direct_io仍是实验功能,不建议用于生产。
