事务 (ACID) 支持
案例 1:插入到 MergeTree* 系列的一个分区,到一个表
如果插入的行被打包并作为一个单独的块插入(参见注意事项),则这是事务性的 (ACID)
- 原子性:INSERT 要么成功,要么被完全拒绝:如果向客户端发送了确认,则所有行都已插入;如果向客户端发送了错误,则没有行被插入。
- 一致性:如果没有违反表约束,则 INSERT 中的所有行都将被插入并且 INSERT 成功;如果违反了约束,则没有行被插入。
- 隔离性:并发客户端观察表的 consistent snapshot(一致性快照)——INSERT 尝试之前或成功 INSERT 之后的状态;不会看到部分状态。事务内部的客户端具有 快照隔离,而事务外部的客户端具有 读未提交 隔离级别。
- 持久性:成功的 INSERT 在回复客户端之前写入文件系统,在单个副本或多个副本上(由
insert_quorum设置控制),并且 ClickHouse 可以要求操作系统将文件系统数据同步到存储介质上(由fsync_after_insert设置控制)。 - 如果涉及物化视图,则可以使用一个语句将 INSERT 插入到多个表是可能的(来自客户端的 INSERT 到具有关联物化视图的表)。
案例 2:插入到 MergeTree* 系列的一个表的多个分区
与上述案例 1 相同,但有此细节
- 如果表有很多分区并且 INSERT 涵盖了许多分区,则每次插入到每个分区都是独立的事务
案例 3:插入到 MergeTree* 系列的一个分布式表
与上述案例 1 相同,但有此细节
- INSERT 到分布式表作为一个整体不是事务性的,而插入到每个分片是事务性的
案例 4:使用 Buffer 表
- 插入到 Buffer 表既不是原子性的,也不是隔离性的,也不是一致性的,也不是持久性的
案例 5:使用 async_insert
与上述案例 1 相同,但有此细节
- 即使启用了
async_insert并且wait_for_async_insert设置为 1(默认值),也能保证原子性,但是如果wait_for_async_insert设置为 0,则不能保证原子性。
注意事项
- 从客户端以某种数据格式插入的行在以下情况下被打包成一个单独的块
- 插入格式是基于行的(例如 CSV、TSV、Values、JSONEachRow 等),并且数据包含少于
max_insert_block_size行(默认约为 1 000 000),或者在启用并行解析的情况下(默认启用),数据包含少于min_chunk_bytes_for_parallel_parsing字节(默认 10 MB) - 插入格式是基于列的(例如 Native、Parquet、ORC 等),并且数据仅包含一个数据块
- 插入格式是基于行的(例如 CSV、TSV、Values、JSONEachRow 等),并且数据包含少于
- 插入块的大小通常可能取决于许多设置(例如:
max_block_size、max_insert_block_size、min_insert_block_size_rows、min_insert_block_size_bytes、preferred_block_size_bytes等) - 如果客户端没有从服务器收到答复,则客户端不知道事务是否成功,并且可以使用 exactly-once 插入属性重复该事务
- ClickHouse 正在内部使用 MVCC 和 快照隔离 进行并发事务
- 即使在服务器 kill/crash 的情况下,所有 ACID 属性也都是有效的
- 在典型的设置中,为了确保持久的插入,应该启用 insert_quorum 到不同的 AZ 或 fsync
- ACID 术语中的“一致性”不涵盖分布式系统的语义,请参阅 https://jepsen.io/consistency,该语义由不同的设置(select_sequential_consistency)控制
- 此说明不涵盖允许在多个表、物化视图、多个 SELECT 等上拥有完整功能的事务的新事务功能(请参阅下一节关于事务、提交和回滚的部分)
事务、提交和回滚
实验性功能。 了解更多。
ClickHouse Cloud 中不支持
除了本文档顶部描述的功能之外,ClickHouse 还具有对事务、提交和回滚功能的支持(实验性)。
要求
- 部署 ClickHouse Keeper 或 ZooKeeper 以跟踪事务
- 仅 Atomic DB(默认)
- 仅 Non-Replicated MergeTree 表引擎
- 通过在
config.d/transactions.xml中添加此设置来启用实验性事务支持
注意事项
- 这是一个实验性功能,应该会发生变化。
- 如果在事务期间发生异常,则无法提交事务。这包括所有异常,包括由拼写错误引起的
UNKNOWN_FUNCTION异常。 - 不支持嵌套事务;请完成当前事务并开始新的事务
配置
这些示例是在启用了 ClickHouse Keeper 的单个 ClickHouse 服务器节点上进行的。
启用实验性事务支持
启用 ClickHouse Keeper 的单个 ClickHouse 服务器节点的的基本配置
注意
有关部署 ClickHouse 服务器和适当数量的 ClickHouse Keeper 节点的详细信息,请参阅 部署 文档。此处显示的配置仅用于实验目的。
示例
验证是否启用了实验性事务
发出 BEGIN TRANSACTION 或 START TRANSACTION,后跟 ROLLBACK,以验证是否启用了实验性事务,以及是否启用了 ClickHouse Keeper,因为它用于跟踪事务。
提示
如果看到以下错误,请检查您的配置文件以确保 allow_experimental_transactions 设置为 1(或任何非 0 或 false 的值)。
您还可以通过发出以下命令来检查 ClickHouse Keeper
ClickHouse Keeper 应该回复 imok。
创建一个用于测试的表
提示
表的创建不是事务性的。在事务外部运行此 DDL 查询。
开始事务并插入一行
注意
您可以在事务内部查询该表,即使该行尚未提交,也可以看到该行已被插入。
回滚事务,然后再次查询该表
验证事务是否已回滚
完成事务并再次查询该表
事务内省
您可以通过查询 system.transactions 表来检查事务,但请注意,您不能从处于事务中的会话中查询该表。打开第二个 clickhouse client 会话以查询该表。
更多细节
请参阅此 元 issue 以查找更多更广泛的测试并及时了解进度。