Skip to main content
ほとんどの ALTER TABLE クエリでは、テーブル設定またはデータを変更します。
ほとんどの ALTER TABLE クエリは、*MergeTreeMerge、および Distributed テーブルでのみサポートされています。
以下の ALTER ステートメントはビューを操作します。 以下の ALTER ステートメントは、ロールベースのアクセス制御に関連するエンティティを変更します。

ミューテーション

テーブルデータの操作を目的とする ALTER クエリは、「ミューテーション」と呼ばれる仕組みによって実装されています。代表的なものとして、ALTER TABLE … DELETEALTER TABLE … UPDATE があります。これらは、MergeTree テーブルにおけるマージと同様、新しい「変更後」のパーツを生成する非同期のバックグラウンド処理です。 *MergeTree テーブルでは、ミューテーションはデータパーツ全体を書き換えることで実行されます。 アトミック性はありません。パーツは準備ができ次第、変更後のパーツに置き換えられるため、ミューテーションの実行中に開始された SELECT クエリでは、すでに変更済みのパーツのデータと、まだ変更されていないパーツのデータの両方が見えることがあります。 ミューテーションは作成順に完全に順序付けられ、その順序で各パーツに適用されます。また、INSERT INTO クエリに対しては部分的な順序関係もあります。ミューテーションの送信前にテーブルへ挿入されたデータは変更対象になりますが、その後に挿入されたデータは変更されません。なお、ミューテーションが insert をブロックすることはありません。 ミューテーションのクエリは、ミューテーションエントリが追加されるとすぐに返ります (レプリケートテーブルの場合は ZooKeeper に、非レプリケートテーブルの場合は filesystem に追加されます) 。ミューテーション自体は、システムの profile 設定を使用して非同期に実行されます。ミューテーションの進行状況を追跡するには、system.mutations テーブルを使用できます。正常に送信されたミューテーションは、ClickHouse server が再起動しても実行が継続されます。いったん送信されたミューテーションをロールバックする方法はありませんが、何らかの理由で停止している場合は、KILL MUTATION クエリでキャンセルできます。 完了したミューテーションのエントリはすぐには削除されません (保持するエントリ数は、ストレージエンジンのパラメータ finished_mutations_to_keep で決まります) 。古いミューテーションエントリは削除されます。

ALTERクエリの同期

非レプリケートテーブルでは、すべての ALTER クエリが同期的に実行されます。レプリケートテーブルでは、クエリは対応する操作の指示を ZooKeeper に追加するだけで、操作自体はできるだけ早く実行されます。ただし、クエリはそれらの操作がすべてのレプリカで完了するまで待機できます。 ミューテーションを作成する ALTER クエリ (例: UPDATEDELETEMATERIALIZE INDEXMATERIALIZE PROJECTIONMATERIALIZE COLUMNAPPLY DELETED MASKAPPLY PATCHESCLEAR STATISTICMATERIALIZE STATISTIC など) については、同期性は mutations_sync 設定によって決まります。 メタデータのみを変更するその他の ALTER クエリについては、alter_sync 設定を使用して待機方法を設定できます。 非アクティブなレプリカがすべての ALTER クエリを実行するまで、どれだけ長く (秒単位で) 待機するかは、replication_wait_for_inactive_replica_timeout 設定で指定できます。
すべての ALTER クエリについて、alter_sync = 2 であり、かつ一部のレプリカが replication_wait_for_inactive_replica_timeout 設定で指定された時間を超えて非アクティブな場合は、UNFINISHED 例外がスローされます。

1 つのテーブルに対する ALTER の同時割り当て

レプリケートテーブルでは、同じテーブルに対して複数の個別の ALTER ステートメントを短時間に連続して送信すると、CANNOT_ASSIGN_ALTER (コード 517) で失敗することがあります。レプリケートパスでは、レプリカが以前の ALTER の一部をまだ適用していない場合にこのエラーが発生します (メタデータバージョンが共通メタデータより遅れている状態です。サーバーは、レプリカについて「still not applied some of previous alters」または「Probably too many alters executing concurrently」と表示することがあります) 。以前の ALTER がすでに割り当てられた後でも、この状態が続くことがあります。これは メタデータ ALTER とミューテーションの一般的な同時実行状態 であり、ミューテーションのみを行うステートメントに限定されません。通常の同時メタデータ変更 (ADD / DROP / MODIFY など) でも、同じ再試行可能なコードが発生する場合があります (例として、tests/queries/0_stateless/03518_alter_logical_race.sh で対象となっている再試行パスを参照してください) 。 競合を回避する方法:
  • 文法で許可される場合は、独立したメタデータ操作を 1 つの 複数句 ALTER にまとめます (たとえば、複数の ADD INDEX 句) 。
  • ALTER ステートメントを直列化し、以前の ALTER がレプリカに適用されるまで、コード 517 が発生した場合は再試行します。
  • ミューテーションを生成する ALTER では、次の ALTER を送信する前に、mutations_syncsystem.mutationsis_done など、ドキュメント化された確認手段を使用して、以前のミューテーションが完了するのを待ちます。

MATERIALIZE INDEX 句の組み合わせ

1 つの ALTER に複数の MATERIALIZE INDEX 句を含めることができます。ツリー内でテスト対象となっているのは、複数の ADD INDEX 句と、それらの新しい索引に対する MATERIALIZE INDEX を 1 つのステートメントにまとめるケースです (tests/queries/0_stateless/02911_add_index_and_materialize_index.sql を参照) 。この ADD INDEX + MATERIALIZE INDEX をまとめた形式では、AlterCommand セグメントと MutationCommand セグメントが混在するため、DatabaseReplicated では QUERY_IS_PROHIBITED により拒否されます (InterpreterAlterQuery::validateReplicatedDatabaseSegments) 。通常の (非 DatabaseReplicated) データベースでは、02911 の例は有効です。DatabaseReplicated では、メタデータの変更とマテリアライズのミューテーションを別々のステートメントに分けてください。 現在の実装では、各 MATERIALIZE INDEX 句はミューテーションの準備時にテーブルのメタデータスナップショットに対して解決されます。そのため、既存の索引に対するマテリアライズのみの複数句形式も同じ準備パスをたどります (ミューテーションのみであるため、1 つのセグメント内に収まります) 。この正確な形式は、まだ専用のステートレステストでカバーされていません。そのようなテストが追加されるまでは、個別に保証された契約ではなく、現在の実装上の動作として扱ってください。 ミューテーションを順序どおりに適用する必要がある場合は、引き続きステートメントごとに 1 つの MATERIALIZE INDEX を実行し、mutations_sync で完了を待機できます。
最終更新日 2026年8月14日