⌘+k ctrl+k
1.4 (LTS)
搜索快捷键 cmd + k | ctrl + k
并发

处理并发性

DuckDB 有两个可配置的并发选项:

  1. 单个进程可以同时对数据库进行读写操作。
  2. 多个进程可以同时从数据库读取数据,但不能有进程进行写入(access_mode = 'READ_ONLY')。

当使用选项 1 时,DuckDB 通过结合 MVCC(多版本并发控制) 和乐观并发控制(参见 单进程内的并发性),支持单个写入进程内的多个写入线程。采用这种并发模型的原因在于,允许在 RAM 中缓存数据以加速分析型查询,而不是在每次查询时都在磁盘之间来回读取。它还允许缓存函数指针、数据库目录及其他项,从而使同一连接上的后续查询速度更快。

DuckDB 针对批量操作进行了优化,因此执行大量小事务并不是其主要设计目标。

单进程内的并发性

DuckDB 根据以下规则支持单进程内的并发。只要没有写入冲突,多个并发写入就会成功。追加(Append)操作永远不会冲突,即使是在同一个表上。多个线程也可以同时更新不同的表,或者更新同一张表的不同子集。当两个线程同时尝试编辑(更新或删除)同一行时,乐观并发控制就会发挥作用。在这种情况下,第二个尝试编辑的线程将因冲突错误而失败。

从多个进程写入 DuckDB

DuckDB 不自动支持从多个进程写入,这也不是其主要设计目标(参见 处理并发性)。

如果必须由多个进程向同一个文件写入数据,可以采用几种设计模式,但需要在应用程序逻辑中实现。例如,每个进程可以获取一个跨进程互斥锁,然后以读/写模式打开数据库,并在查询完成后关闭它。除了使用互斥锁之外,每个进程也可以在另一个进程已连接到数据库时重试连接(务必在查询完成后关闭连接)。另一种选择是在 MySQL、PostgreSQL 或 SQLite 数据库上进行多进程事务处理,并使用 DuckDB 的 MySQLPostgreSQLSQLite 扩展来定期对这些数据执行分析查询。

其他方案包括将数据写入 Parquet 文件并利用 DuckDB 读取多个 Parquet 文件 的能力,采用类似方法处理 CSV 文件,或者创建一个 Web 服务器来接收请求并管理 DuckDB 的读写操作。

乐观并发控制

DuckDB 使用 乐观并发控制,这种方法通常被认为最适合读密集型的分析型数据库系统,因为它能加快读取查询的处理速度。因此,任何同时修改相同行的事务都会导致事务冲突错误。

Transaction conflict: cannot update a table that has been altered!

提示:遇到事务冲突时,一种常见的解决方法是重新运行该事务。

© 2025 DuckDB 基金会,阿姆斯特丹,荷兰
行为准则 商标使用指南