メインコンテンツへスキップ

ケース1: MergeTree* ファミリーの1つのテーブルの1つのパーティションへの INSERT

挿入される行が1つのブロックにまとめられて挿入される場合、これはトランザクション的 (ACID) です (注記を参照) :
  • Atomic: INSERT は全体として成功するか、全体として拒否されます。クライアントに確認が返された場合はすべての行が挿入されており、クライアントにエラーが返された場合は1行も挿入されていません。
  • Consistent: テーブルの制約に違反していない場合、INSERT 内のすべての行が挿入され、INSERT は成功します。制約に違反している場合は、1行も挿入されません。
  • Isolated: 同時実行クライアントには、テーブルの一貫した snapshot、つまり INSERT 試行前のテーブルの state か、INSERT 成功後の state のいずれかが見え、途中の部分的な state は見えません。別の トランザクション の内部にいるクライアントは スナップショット分離、トランザクション の外部にいるクライアントは read uncommitted 分離レベルになります。
  • Durable: 成功した INSERT は、クライアントに応答する前に、単一のレプリカまたは複数のレプリカ (insert_quorum setting で制御) 上の filesystem に書き込まれます。また ClickHouse は、OS に対して storage media 上の filesystem data の同期を要求できます (fsync_after_insert setting で制御) 。
  • materialized view が関係する場合、1つのステートメントで複数のテーブルに INSERT できます (クライアントからの INSERT 先は、関連する materialized view を持つテーブルです) 。

ケース2: MergeTree* ファミリーの単一テーブルの複数パーティションへの INSERT

上記のケース1と同様ですが、次の点が異なります。
  • テーブルに多数のパーティションがあり、INSERT が複数のパーティションにまたがる場合、各パーティションへの挿入はそれぞれ個別のトランザクションとして扱われます

ケース3: MergeTree* ファミリーの1つの分散テーブルへのINSERT

基本的には上記のケース1と同じですが、次の点が異なります。
  • 分散テーブルへのINSERTは全体としてはトランザクションではありませんが、各分片への挿入はトランザクションです

ケース 4: Buffer table を使用する場合

  • Buffer table への insert は、原子性、分離性、一貫性、耐久性のいずれも保証されません

ケース 5: async_insert を使用する場合

基本的には上記のケース 1 と同じですが、次の点が異なります。
  • async_insert が有効で、wait_for_async_insert が 1 (デフォルト) に設定されている場合は、アトミック性が保証されます。一方、wait_for_async_insert が 0 に設定されている場合は、アトミック性は保証されません。

注意事項

  • クライアントから特定のデータフォーマットで挿入された行は、次の場合に 1 つの ブロック に packed されます。
    • insert フォーマットが行ベース (CSV、TSV、Values、JSONEachRow など) で、データの行数が max_insert_block_size 未満 (デフォルトでは約 1 000 000) であるか、並列パースを使用する場合 (デフォルトで有効) にデータサイズが min_chunk_bytes_for_parallel_parsing バイト未満 (デフォルトでは 10 MB) である場合
    • insert フォーマットがカラムベース (Native、Parquet、ORC など) で、データに含まれる ブロック が 1 つだけである場合
  • 挿入される ブロック のサイズは、一般に多くの Settings に依存します (例: max_block_sizemax_insert_block_sizemin_insert_block_size_rowsmin_insert_block_size_bytespreferred_block_size_bytes など)
  • クライアントが server から応答を受け取れなかった場合、その トランザクション が成功したかどうかをクライアントは判断できず、exactly-once insertion の特性を利用して トランザクション を再試行できます
  • ClickHouse は、同時実行 トランザクション のために内部で MVCCスナップショット分離 を使用しています
  • すべての ACID 特性は、server の kill/crash が発生した場合でも有効です
  • 一般的な構成で durable inserts を確実にするには、異なる AZ に対する insert_quorum または fsync のいずれかを有効にする必要があります
  • ACID における “consistency” は分散システムのセマンティクスまでは対象としていません。詳しくは https://jepsen.io/consistency を参照してください。これは別の Settings (select_sequential_consistency) で制御されます
  • この説明では、複数の table、materialized view、複数の SELECT などにまたがるフル機能の トランザクション を可能にする新しい トランザクション 機能は扱っていません (次の「Transactions, Commit, and Rollback」セクションを参照してください)

トランザクション、コミット、ロールバック

このドキュメントの冒頭で説明した機能に加えて、ClickHouse はトランザクション、コミット、ロールバックを実験的にサポートしています。

要件

  • トランザクションを追跡するため、ClickHouse Keeper または ZooKeeper をデプロイします
  • Atomic DB のみ (デフォルト)
  • Non-Replicated MergeTree テーブルエンジンのみ
  • config.d/transactions.xml に次の設定を追加して、実験的なトランザクションサポートを有効にします。

注意事項

  • これは実験的な機能であり、今後変更される可能性があります。
  • トランザクション中に例外が発生した場合、そのトランザクションをコミットすることはできません。これには、タイプミスによって発生する UNKNOWN_FUNCTION 例外を含む、あらゆる例外が含まれます。
  • ネストされたトランザクションはサポートされていません。代わりに、現在のトランザクションを終了してから新しいトランザクションを開始してください

設定

以下の例では、ClickHouse Keeper を有効にした単一ノード構成の ClickHouse server を使用します。

実験的なトランザクション機能を有効にする

/etc/clickhouse-server/config.d/transactions.xml

ClickHouse Keeper を有効にした単一の ClickHouse server ノード向けの基本構成

ClickHouse server と、適切なクォーラムを満たす ClickHouse Keeper ノードのデプロイについて詳しくは、デプロイメント のドキュメントを参照してください。ここで示す構成は試験的な目的のためのものです。
/etc/clickhouse-server/config.d/config.xml

Experimental な トランザクション が enabled であることを確認する

BEGIN TRANSACTION または START TRANSACTION を実行し、その後 ROLLBACK を実行して、Experimental な トランザクション と、トランザクション の追跡に使用される ClickHouse Keeper が有効になっていることを確認します。
次のエラーが表示された場合は、設定ファイルを確認し、allow_experimental_transactions1 (または 0false 以外の値) に設定されていることを確認してください。
次のコマンドを実行して ClickHouse Keeper の状態を確認することもできます。
ClickHouse Keeper は imok を返すはずです。

テスト用のテーブルを作成

テーブルの作成はトランザクションに対応していません。このDDLクエリはトランザクションの外で実行してください。

トランザクションを開始し、行を挿入する

トランザクション内からテーブルをクエリすると、まだコミットされていないにもかかわらず、その行が挿入されていることを確認できます。

トランザクションをロールバックし、再度テーブルをクエリする

トランザクションがロールバックされていることを確認します。

トランザクションを完了し、テーブルに再度クエリを実行する

トランザクションの内部情報の確認

system.transactions テーブルをクエリするとトランザクションを確認できますが、トランザクション中のセッションからはその テーブルをクエリできない点に注意してください。そのテーブルをクエリするには、2 つ目の clickhouse client セッションを開いてください。

さらに詳しく

より広範なテスト内容を確認し、進捗の最新情報を把握するには、このmeta issueを参照してください。
最終更新日 2026年7月2日