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

> `Atomic` 引擎支持非阻塞的 `DROP TABLE` 和 `RENAME TABLE` 查询，以及原子性的 `EXCHANGE TABLES` 查询。开源 ClickHouse 默认使用 `Atomic` 数据库引擎。

# Atomic

`Atomic` 引擎支持非阻塞的 [`DROP TABLE`](#drop-detach-table) 和 [`RENAME TABLE`](#rename-table) 查询，以及原子性的 [`EXCHANGE TABLES`](#exchange-tables) 查询。开源 ClickHouse 默认使用 `Atomic` 数据库引擎。

<Note>
  在 ClickHouse Cloud 中，默认使用的是 [`Shared` 数据库引擎](/zh/products/cloud/features/infrastructure/shared-catalog#shared-database-engine)，它也支持上述操作。
</Note>

## 创建数据库

```sql theme={null}
CREATE DATABASE test [ENGINE = Atomic] [SETTINGS name = value, ...];
```

`ENGINE = Atomic` 可以省略，因为它是默认值。`SETTINGS` 子句既可以包含数据库引擎的设置 (例如 [`disk`](#metadata-disk) 或 [`max_tables`](#limiting-the-number-of-tables)) ，也可以包含普通的查询设置；每个名称都会被分派到它所属的那一类。

## 具体事项和建议

### 表 UUID

`Atomic` 数据库中的每个表都有一个持久的 [UUID](/zh/reference/data-types/uuid)，其数据存储在以下目录中：

```text theme={null}
/clickhouse_path/store/xxx/xxxyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy/
```

其中，`xxxyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy` 是该表的 UUID。

默认情况下，UUID 会自动生成。不过，用户也可以在创建表时明确指定 UUID，但不建议这样做。

例如：

```sql theme={null}
CREATE TABLE name UUID '28f1c61c-2970-457a-bffe-454156ddcfef' (n UInt64) ENGINE = ...;
```

<Note>
  你可以使用 [show\_table\_uuid\_in\_table\_create\_query\_if\_not\_nil](/zh/reference/settings/session-settings/show#show_table_uuid_in_table_create_query_if_not_nil) 设置，以便在 `SHOW CREATE` 查询中显示 UUID。
</Note>

### RENAME TABLE

[`RENAME`](/zh/reference/statements/rename) 查询不会修改 UUID，也不会移动表中的数据。这些查询会立即执行，不会等待其他正在使用该表的查询结束。

### DROP/DETACH TABLE

使用 `DROP TABLE` 时，不会删除任何数据。`Atomic` 引擎只是将该表的元数据移动到 `/clickhouse_path/metadata_dropped/`，以此将其标记为已删除，并通知后台线程。最终删除表数据前的延迟由 [`database_atomic_delay_before_drop_table_sec`](/zh/reference/settings/server-settings/settings/other#database_atomic_delay_before_drop_table_sec) 设置指定。
您可以使用 `SYNC` 修饰符来指定同步模式。为此，请使用 [`database_atomic_wait_for_drop_and_detach_synchronously`](/zh/reference/settings/session-settings/database#database_atomic_wait_for_drop_and_detach_synchronously) 设置。在这种情况下，`DROP` 会等待正在使用该表的 `SELECT`、`INSERT` 及其他查询完成。该表会在不再被使用时被移除。

### EXCHANGE TABLES/DICTIONARIES

[`EXCHANGE`](/zh/reference/statements/exchange) 查询可原子地交换表或字典。例如，可替代下面这种非原子操作：

```sql title="Non-atomic" theme={null}
RENAME TABLE new_table TO tmp, old_table TO new_table, tmp TO old_table;
```

你也可以使用 Atomic 数据库：

```sql title="Atomic" theme={null}
EXCHANGE TABLES new_table AND old_table;
```

### 原子数据库中的 ReplicatedMergeTree

对于 [`ReplicatedMergeTree`](/zh/reference/engines/table-engines/mergetree-family/replication) 表，建议不要指定 ZooKeeper 中的路径和副本名称这两个引擎参数。在这种情况下，将使用配置参数 [`default_replica_path`](/zh/reference/settings/server-settings/settings/default-replica#default_replica_path) 和 [`default_replica_name`](/zh/reference/settings/server-settings/settings/default-replica#default_replica_name)。如果想显式指定引擎参数，建议使用 `{uuid}` 宏。这样可以确保在 ZooKeeper 中为每个表自动生成唯一的路径。

### 元数据磁盘

当在 `SETTINGS` 中指定 `disk` 时，该磁盘将用于存储表的元数据文件。
它可以指定服务器配置中已定义的磁盘，也可以通过 `disk` 函数内联定义，方式与单个表相同：

```sql theme={null}
CREATE DATABASE db SETTINGS disk = 'db_disk';
CREATE DATABASE db SETTINGS disk = disk(type = 'local', path = '/var/lib/clickhouse-disks/db_disk');
```

若未指定，则默认使用 `database_disk.disk` 中定义的磁盘。

相同的 `SETTINGS` 子句同样适用于 `ATTACH DATABASE`：元数据文件位于其他磁盘上的数据库，正是通过这种方式挂载到
服务器的。此时，`Atomic` 要求显式指定数据库的 `UUID`：

```sql theme={null}
ATTACH DATABASE db UUID '28f1c61c-2970-457a-bffe-454156ddcfef'
SETTINGS disk = disk(type = 'local', path = '/var/lib/clickhouse-disks/db_disk');
```

### 限制表的数量

`max_tables` 设置用于限制数据库中可包含的表数量，`0` (默认值) 表示不限制。所有类表对象都会计入该限制：普通表、视图、materialized view，以及通过 `CREATE DICTIONARY` 创建的字典。达到上限后，`CREATE TABLE`、`CREATE DICTIONARY` 和 `ATTACH TABLE` 会抛出 `TOO_MANY_TABLES` 异常。

```sql theme={null}
CREATE DATABASE db ENGINE = Atomic SETTINGS max_tables = 100;
```

对于已存在的 数据库，可以使用 `ALTER DATABASE` 修改该限制：

```sql theme={null}
ALTER DATABASE db MODIFY SETTING max_tables = 200;
```

将限制值调低至当前表数量以下不会删除任何表，只会阻止创建新表，直到表数量再次低于限制值。

`CREATE OR REPLACE TABLE` 会先以临时名称创建替换表，然后再将其替换到位。因此，当数据库中的表数量恰好达到 `max_tables` 时，替换表会因 `TOO_MANY_TABLES` 而失败，即使最终表数量不会增加。使用 `RENAME TABLE` 或 `RENAME DICTIONARY` 将对象移入数据库同样受此限制约束。

未指定 `TO` 子句的 materialized view 会创建一个隐藏的内部表，该表会作为独立表计入限制。

该限制会在操作开始前进行检查，因此只能尽力保证：并发查询可能会使数据库中的表数量略微超出限制。

该设置适用于将表保存在内存中、将元数据保存在本地 `.sql` 文件中的磁盘型数据库引擎：`Atomic` 和 `Ordinary`。`Replicated` 引擎不支持此设置。

## 另请参见

* [system.databases](/zh/reference/system-tables/databases) 系统表
