> ## Documentation Index
> Fetch the complete documentation index at: https://private-7c7dfe99-trino-dialect.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

> ALTER 文档

# ALTER

大多数 `ALTER TABLE` 查询都会修改表设置或数据：

| 修饰符                                                                     |
| ----------------------------------------------------------------------- |
| [COLUMN](/zh/reference/statements/alter/column)                         |
| [PARTITION](/zh/reference/statements/alter/partition)                   |
| [DELETE](/zh/reference/statements/alter/delete)                         |
| [UPDATE](/zh/reference/statements/alter/update)                         |
| [ORDER BY](/zh/reference/statements/alter/order-by)                     |
| [SAMPLE BY](/zh/reference/statements/alter/sample-by)                   |
| [INDEX](/zh/reference/statements/alter/skipping-index)                  |
| [PROJECTION](/zh/reference/statements/alter/projection)                 |
| [CONSTRAINT](/zh/reference/statements/alter/constraint)                 |
| [TTL](/zh/reference/statements/alter/ttl)                               |
| [STATISTICS](/zh/reference/statements/alter/statistics)                 |
| [SETTING](/zh/reference/statements/alter/setting)                       |
| [APPLY DELETED MASK](/zh/reference/statements/alter/apply-deleted-mask) |
| [APPLY PATCHES](/zh/reference/statements/alter/apply-patches)           |

<Note>
  大多数 `ALTER TABLE` 查询仅适用于 [\*MergeTree](/zh/reference/engines/table-engines/mergetree-family/index)、[Merge](/zh/reference/engines/table-engines/special/merge) 和 [Distributed](/zh/reference/engines/table-engines/special/distributed) 表。
</Note>

这些 `ALTER` 语句用于操作视图：

| 语句                                                                  | 描述                                                                |
| ------------------------------------------------------------------- | ----------------------------------------------------------------- |
| [ALTER TABLE ... MODIFY QUERY](/zh/reference/statements/alter/view) | 修改 [materialized view](/zh/reference/statements/create/view) 的结构。 |

这些 `ALTER` 语句用于修改与基于角色的访问控制相关的实体：

| 语句                                                                  |
| ------------------------------------------------------------------- |
| [USER](/zh/reference/statements/alter/user)                         |
| [ROLE](/zh/reference/statements/alter/role)                         |
| [QUOTA](/zh/reference/statements/alter/quota)                       |
| [ROW POLICY](/zh/reference/statements/alter/row-policy)             |
| [MASKING POLICY](/zh/reference/statements/alter/masking-policy)     |
| [SETTINGS PROFILE](/zh/reference/statements/alter/settings-profile) |

| 语句                                                                                   | 描述                                                                                           |
| ------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------- |
| [ALTER TABLE ... MODIFY COMMENT](/zh/reference/statements/alter/comment)             | 为表添加、修改或删除注释，无论之前是否设置过。                                                                      |
| [ALTER DATABASE ... MODIFY COMMENT](/zh/reference/statements/alter/database-comment) | 为数据库添加、修改或删除注释，无论之前是否设置过。                                                                    |
| [ALTER NAMED COLLECTION](/zh/reference/statements/alter/named-collection)            | 修改 [Named Collections](/zh/concepts/features/configuration/server-config/named-collections)。 |

<div id="mutations">
  ## 变更
</div>

用于修改表数据的 `ALTER` 查询，是通过一种称为“变更”的机制实现的，最典型的就是 [ALTER TABLE ... DELETE](/zh/reference/statements/alter/delete) 和 [ALTER TABLE ... UPDATE](/zh/reference/statements/alter/update)。它们是异步后台进程，类似于 [MergeTree](/zh/reference/engines/table-engines/mergetree-family/index) 表中的合并，用于生成新的“mutated”版本的 parts。

对于 `*MergeTree` 表，变更是通过**重写整个数据分区片段**来执行的。
它不具备原子性——变更后的 parts 一旦准备就绪，就会立即替换原来的 parts；而在变更执行期间开始的 `SELECT` 查询，既会看到已经变更过的 parts 中的数据，也会看到尚未变更的 parts 中的数据。

变更按照创建顺序完全有序，并按该顺序应用到每个 part。变更与 `INSERT INTO` 查询之间也存在部分顺序关系：在变更提交之前插入到表中的数据会被变更，而在此之后插入的数据则不会被变更。请注意，变更不会以任何方式阻塞插入。

变更查询在变更条目添加完成后会立即返回 (对于复制表，会添加到 ZooKeeper；对于非复制表，则会添加到文件系统) 。变更本身会使用系统 profile 设置异步执行。要跟踪变更的进度，可以使用 [`system.mutations`](/zh/reference/system-tables/mutations) 表。成功提交的变更即使在 ClickHouse 服务器重启后也会继续执行。变更一旦提交，就无法回滚；但如果由于某种原因卡住了，可以使用 [`KILL MUTATION`](/zh/reference/statements/kill#kill-mutation) 查询将其取消。

已完成变更的条目不会立即删除 (保留条目的数量由存储引擎参数 `finished_mutations_to_keep` 决定) 。较早的变更条目会被删除。

<div id="synchronicity-of-alter-queries">
  ## `ALTER` 查询的同步性
</div>

对于非复制表，所有 `ALTER` 查询都会同步执行。对于复制表，查询只会将相应操作的指令添加到 `ZooKeeper` 中，而这些操作本身会尽快执行。不过，查询也可以等待，直到所有副本都完成这些操作。

对于会创建变更的 `ALTER` 查询 (例如但不限于 `UPDATE`、`DELETE`、`MATERIALIZE INDEX`、`MATERIALIZE PROJECTION`、`MATERIALIZE COLUMN`、`APPLY DELETED MASK`、`APPLY PATCHES`、`CLEAR STATISTIC`、`MATERIALIZE STATISTIC`) ，其同步方式由 [mutations\_sync](/zh/reference/settings/session-settings/mutations#mutations_sync) 设置决定。

对于其他仅修改元数据的 `ALTER` 查询，可以使用 [alter\_sync](/zh/reference/settings/session-settings/alter#alter_sync) 设置来配置等待行为。

你可以使用 [replication\_wait\_for\_inactive\_replica\_timeout](/zh/reference/settings/session-settings/other#replication_wait_for_inactive_replica_timeout) 设置，指定等待非活动副本执行完所有 `ALTER` 查询的时长 (以秒为单位) 。

<Note>
  对于所有 `ALTER` 查询，如果 `alter_sync = 2`，且某些副本处于非活动状态的时间超过 `replication_wait_for_inactive_replica_timeout` 设置中指定的时长，则会抛出 `UNFINISHED` 异常。
</Note>

<div id="concurrent-alter-assignment-on-one-table">
  ### 单张表上的并发 `ALTER` 分配
</div>

在复制表上，短时间内连续对同一张表提交多条独立的 `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` 覆盖的重试路径) 。

避免此竞争条件的方法：

* 在语法允许的情况下，将独立的元数据操作合并为**单条**包含多个子句的 `ALTER` (例如多个 `ADD INDEX` 子句) 。
* 将 `ALTER` 语句串行执行；遇到代码 517 时重试，直到副本应用了此前的 `ALTER`。
* 对于会产生变更的 `ALTER`，请在提交下一条语句前，通过已文档化的可观测项 (如 [`mutations_sync`](/zh/reference/settings/session-settings/mutations#mutations_sync) 或 [`system.mutations`](/zh/reference/system-tables/mutations) 中的 `is_done`) 等待此前的变更完成。

<div id="combining-materialize-index-clauses">
  ### 合并 `MATERIALIZE INDEX` 子句
</div>

一条 `ALTER` 语句中可以包含多个 `MATERIALIZE INDEX` 子句。代码库中已覆盖的场景是：在一条语句中，将多个 `ADD INDEX` 子句与针对同一批新索引的 `MATERIALIZE INDEX` 一并使用 (参见 `tests/queries/0_stateless/02911_add_index_and_materialize_index.sql`) 。这种组合的 `ADD INDEX` + `MATERIALIZE INDEX` 形式同时包含 `AlterCommand` 片段和 `MutationCommand` 片段，因此 **`DatabaseReplicated` 会拒绝该语句**，并返回 `QUERY_IS_PROHIBITED` (`InterpreterAlterQuery::validateReplicatedDatabaseSegments`) 。`02911` 示例适用于普通 (非 `DatabaseReplicated`) 数据库；对于 `DatabaseReplicated`，请将元数据变更和物化变更拆分为不同的语句。

在当前实现中，准备变更时，每个 `MATERIALIZE INDEX` 子句都会根据表元数据快照进行解析。因此，针对已有索引、仅包含物化操作的多子句形式也会遵循相同的准备路径 (仅包含变更操作，因此仍位于同一个片段内) 。这种确切形式尚未有专门的无状态测试覆盖；在具备此类测试覆盖前，应将其视为当前实现行为，而非单独保证的契约。

如果需要按顺序应用变更，仍可在每条语句中执行一个 `MATERIALIZE INDEX`，并通过 [`mutations_sync`](/zh/reference/settings/session-settings/mutations#mutations_sync) 等待。

<div id="related-content">
  ## 相关内容
</div>

* 博客：[ClickHouse 中更新与删除的处理方式](https://clickhouse.com/blog/handling-updates-and-deletes-in-clickhouse)
