情况 1:向 MergeTree* 家族中某个表的单个分区执行 INSERT
- 原子性:一次 INSERT 要么整体成功,要么整体被拒绝:如果向客户端发送了确认,则所有行都已插入;如果向客户端返回了错误,则不会插入任何行。
- 一致性:如果未违反表约束,则一次 INSERT 中的所有行都会被插入,并且 INSERT 成功;如果违反了约束,则不会插入任何行。
- 隔离性:并发客户端观察到的是表的一致性快照——要么是发起 INSERT 之前的表状态,要么是 INSERT 成功之后的表状态;不会看到中间的部分状态。处于另一个事务中的客户端具有快照隔离,而事务外的客户端具有读未提交隔离级别。
- 持久性:成功的 INSERT 会在响应客户端之前写入文件系统,可写入单个副本或多个副本 (由
insert_quorum设置控制) ,并且 ClickHouse 可以要求操作系统将文件系统中的数据同步到存储介质 (由fsync_after_insert设置控制) 。 - 如果涉及 materialized view,则可以通过一条语句向多个表执行 INSERT (即客户端向一个具有关联 materialized view 的表执行 INSERT) 。
情况 2:向 MergeTree* 家族的同一张表中的多个分区执行 INSERT
- 如果表有很多分区,且 INSERT 涉及多个分区,那么向每个分区的插入都会各自作为一个事务处理
情况 3:向一个 MergeTree* 家族的分布式表执行 INSERT
- 对 Distributed 表执行 INSERT 整体上不具备事务性,而对每个分片的插入则是事务性的
案例 4:使用 Buffer 表
- 向 Buffer 表插入数据既不具备原子性,也不具备隔离性、一致性和持久性
情况 5:使用 async_insert
- 即使启用了
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 和快照隔离来支持并发事务
- 即使在服务器被终止或崩溃的情况下,所有 ACID 属性依然成立
- 在典型部署中,应启用跨不同 AZ 的 insert_quorum 或 fsync,以确保插入的持久性
- ACID 中的“一致性”并不涵盖分布式系统语义,参见 https://jepsen.io/consistency;这由不同的设置 (select_sequential_consistency) 控制
- 本说明未涵盖一项新的事务功能,该功能支持跨多个表、materialized view 以及多个 SELECT 的全功能事务等。 (请参见下一节“Transactions, Commit, and Rollback”)
事务、提交与回滚
要求
- 部署 ClickHouse Keeper 或 ZooKeeper 以跟踪事务
- 仅限 Atomic DB (默认)
- 仅限非复制表 MergeTree 表引擎
- 在
config.d/transactions.xml中添加以下设置,以启用 Experimental 事务支持:
说明
- 这是一项 Experimental 功能,后续可能会有所变动。
- 如果在事务期间发生异常,则无法提交该事务。这包括所有异常,也包括因拼写错误导致的
UNKNOWN_FUNCTION异常。 - 不支持嵌套事务;请先完成当前事务,再开始新事务
配置
启用 Experimental 事务支持
/etc/clickhouse-server/config.d/transactions.xml
启用 ClickHouse Keeper 的单个 ClickHouse server 节点基本配置
有关部署 ClickHouse server 以及满足法定人数要求的 ClickHouse Keeper 节点的详细信息,请参阅部署文档。此处展示的配置仅供实验之用。
/etc/clickhouse-server/config.d/config.xml
示例
验证是否已启用 Experimental 事务
BEGIN TRANSACTION 或 START TRANSACTION,然后再执行 ROLLBACK,以确认 Experimental 事务已启用,并且 ClickHouse Keeper 也已启用,因为它用于跟踪事务。
创建一个测试用表
开启事务并插入一行
你可以在事务中查询该表,并看到该行已插入,尽管事务尚未提交。
回滚事务,并再次查询表
完成事务并再次查询该表
事务内部信息
system.transactions 表来查看事务,但请注意,处于事务中的会话无法查询该
表。请打开第二个 clickhouse client 会话来查询该表。