トランザクション (ACID) のサポート
ケース 1: MergeTree* ファミリーの1つのテーブルの1つのパーティションへのINSERT
挿入された行がパックされて単一のブロックとして挿入される場合、これはトランザクション (ACID) として扱われます(注を参照):
- 原子性: INSERTは全体として成功するか拒否されます: クライアントに確認が送信される場合は、すべての行が挿入されており、エラーがクライアントに送信されると、行は挿入されません。
- 一貫性: テーブル制約が違反されない場合、INSERTのすべての行は挿入され、INSERTは成功します。制約が違反された場合、行は挿入されません。
- 分離性: 同時クライアントはテーブルの一貫したスナップショットを観察します – INSERTの試行前のテーブルの状態、または成功したINSERTの後の状態; 部分的な状態は表示されません。他のトランザクション内のクライアントは スナップショット分離 を持ち、トランザクション外のクライアントは コミットされていない読み取り の分離レベルを持ちます。
- 耐久性: 成功したINSERTはクライアントに応答する前にファイルシステムに書き込まれ、単一のレプリカまたは複数のレプリカ(
insert_quorum
設定で制御される)になります。また、ClickHouseはOSにストレージメディアのファイルシステムデータを同期するように依頼できます(fsync_after_insert
設定で制御される)。 - マテリアライズドビューが関与する場合、1つのステートメントで複数のテーブルへのINSERTが可能です(クライアントからのINSERTは関連するマテリアライズドビューを持つテーブルに対して行われます)。
ケース 2: MergeTree* ファミリーの1つのテーブルへの複数のパーティションへのINSERT
上記のケース1と同様ですが、この詳細があります:
- テーブルに多くのパーティションがあり、INSERTが多くのパーティションをカバーする場合、すべてのパーティションへの挿入はそれぞれトランザクション的になります。
ケース 3: MergeTree* ファミリーの1つの分散テーブルへのINSERT
上記のケース1と同様ですが、この詳細があります:
- 分散テーブルへのINSERTは全体としてトランザクション的ではありませんが、各シャードへの挿入はトランザクション的です。
ケース 4: バッファテーブルの使用
- バッファテーブルへの挿入は、原子性も分離性も一貫性も耐久性もありません。
ケース 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
バイト(デフォルトで10MB)未満である場合 - 挿入フォーマットが列ベース(Native、Parquet、ORCなど)であり、データが1ブロックのデータのみである場合
- 挿入フォーマットが行ベース(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
など)。 - クライアントがサーバーから応答を受け取らなかった場合、トランザクションが成功したかどうかわからず、トランザクションを繰り返すことができます。これは正確に1回のみの挿入プロパティを使用します。
- ClickHouseは、同時トランザクションのために内部で MVCC と スナップショット分離 を使用しています。
- すべてのACIDプロパティは、サーバーの強制終了やクラッシュのケースでも有効です。
- 一般的なセットアップでは、耐久性のある挿入を確保するために異なるAZへの
insert_quorum
またはfsync
のいずれかを有効にする必要があります。 - ACID用語の「一貫性」は分散システムのセマンティクスをカバーしないため、異なる設定(select_sequential_consistency)によって制御される https://jepsen.io/consistency を参照してください。
- この説明では、複数のテーブル、マテリアライズドビュー、複数のSELECT に対してフル機能のトランザクションを提供する新しいトランザクション機能はカバーされていません(トランザクション、コミット、およびロールバックに関する次のセクションを参照してください)。
トランザクション、コミット、およびロールバック
このドキュメントの冒頭で説明された機能に加えて、ClickHouseにはトランザクション、コミット、およびロールバック機能の実験的なサポートがあります。
要件
- トランザクションを追跡するために ClickHouse Keeper または ZooKeeper をデプロイします。
- 原子DB のみ (デフォルト)
- 非レプリケートの 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
セッションを開いてそのテーブルをクエリしてください。
詳細情報
この メタ問題 を参照して、より広範なテストを見つけ、進捗状況を把握してください。