兼容性
向后兼容性
向后兼容性指的是新版本的DuckDB能够读取由旧版本DuckDB创建的存储文件的能力。版本0.10是DuckDB首次支持存储格式向后兼容的版本。DuckDB v0.10可以读取并操作由前一个DuckDB版本——DuckDB v0.9创建的文件。
对于未来的DuckDB版本,我们的目标是确保从本次发布开始,任何之后发布的DuckDB版本都能读取由先前版本创建的文件。我们希望确保文件格式完全向后兼容。这使您可以保留存储在DuckDB文件中的数据,并保证您能够读取这些文件,而无需担心文件是用哪个版本编写的,也无需在版本之间转换文件。
向前兼容性
向前兼容性指的是旧版本的DuckDB能够读取由新版本DuckDB生成的存储文件的能力。DuckDB v0.9 部分向前兼容DuckDB v0.10。某些由DuckDB v0.10创建的文件可以被DuckDB v0.9读取。
向前兼容性是在尽力而为的基础上提供的。虽然存储格式的稳定性很重要——但我们仍希望在未来对存储格式进行许多改进和创新。因此,向前兼容性有时可能会(部分)被破坏。
如何在存储格式之间移动
当你更新DuckDB并打开一个旧的数据库文件时,你可能会遇到关于不兼容存储格式的错误消息,指向此页面。 要将你的数据库迁移到新格式,你只需要旧的和新的DuckDB可执行文件。
使用较旧版本的DuckDB打开您的数据库文件并运行SQL语句EXPORT DATABASE 'tmp'
。这允许您将当前使用的数据库的整个状态保存在文件夹tmp
中。
tmp
文件夹的内容将被覆盖,因此请选择一个空的/尚未存在的位置。然后,启动较新版本的DuckDB并执行IMPORT DATABASE 'tmp'
(指向先前填充的文件夹)以加载数据库,然后可以将其保存到您指向DuckDB的文件中。
一个bash单行命令(需要根据文件名和可执行文件位置进行调整)是:
/older/version/duckdb mydata.db -c "EXPORT DATABASE 'tmp'" && /newer/duckdb mydata.new.db -c "IMPORT DATABASE 'tmp'"
在此之后,mydata.db
将保持旧格式,mydata.new.db
将包含相同的数据,但格式适用于较新的 DuckDB 版本,而文件夹 tmp
将以通用格式保存相同的数据,作为不同的文件。
查看EXPORT
文档以获取有关语法的更多详细信息。
存储头
DuckDB 文件以一个 uint64_t
开头,其中包含主头的校验和,接着是四个魔法字节 (DUCK
),然后是一个 uint64_t
中的存储版本号。
hexdump -n 20 -C mydata.db
00000000 01 d0 e2 63 9c 13 39 3e 44 55 43 4b 2b 00 00 00 |...c..9>DUCK+...|
00000010 00 00 00 00 |....|
00000014
下面是一个使用Python读取存储版本的简单示例。
import struct
pattern = struct.Struct('<8x4sQ')
with open('test/sql/storage_version/storage_version.db', 'rb') as fh:
print(pattern.unpack(fh.read(pattern.size)))
存储版本表
要查看每个给定版本的更改,请查看GitHub上的更改日志。 要查看更改每个存储版本的提交,请参阅提交日志。
存储版本 | DuckDB 版本 |
---|---|
64 | v0.9.x, v0.10.x, v1.0.0, v1.1.x |
51 | v0.8.x |
43 | v0.7.x |
39 | v0.6.x |
38 | v0.5.x |
33 | v0.3.3, v0.3.4, v0.4.0 |
31 | v0.3.2 |
27 | v0.3.1 |
25 | v0.3.0 |
21 | v0.2.9 |
18 | v0.2.8 |
17 | v0.2.7 |
15 | v0.2.6 |
13 | v0.2.5 |
11 | v0.2.4 |
6 | v0.2.3 |
4 | v0.2.2 |
1 | v0.2.1 及更早版本 |
压缩
DuckDB 使用 轻量级压缩。 请注意,压缩仅应用于持久化数据库,不应用于内存实例。
压缩算法
DuckDB支持的压缩算法包括以下几种:
- 常量编码
- 游程编码 (RLE)
- Bit Packing
- 参考框架 (FOR)
- 字典编码
- 快速静态符号表 (FSST) – VLDB 2020 论文
- 自适应无损浮点压缩 (ALP) – SIGMOD 2024 论文
- Chimp – VLDB 2022 论文
- Patas
磁盘使用情况
DuckDB格式的磁盘使用量取决于多种因素,包括数据类型和数据分布、使用的压缩方法等。 作为一个粗略的估计,将100 GB的未压缩CSV文件加载到DuckDB数据库文件中将需要25 GB的磁盘空间,而加载100 GB的Parquet文件将需要120 GB的磁盘空间。
行组
DuckDB的存储格式将数据存储在行组中,即数据的水平分区。 这个概念等同于Parquet的行组。 DuckDB中的几个特性,包括并行性和压缩,都是基于行组的。
故障排除
打开不兼容的数据库文件时的错误信息
当打开一个由不同DuckDB版本写入的数据库文件时,可能会出现以下错误信息:
Error: unable to open database "...": Serialization Error: Failed to deserialize: ...
该消息意味着数据库文件是用较新的DuckDB版本创建的,并且使用了与用于读取文件的DuckDB版本不兼容的功能。
有两种可能的解决方法:
- 将您的DuckDB版本更新到最新的稳定版本。
- 使用最新版本的DuckDB打开数据库,将其导出为标准格式(例如,Parquet),然后使用任何版本的DuckDB导入。详情请参阅
EXPORT/IMPORT DATABASE
语句。