操作分区和分片
以下是可用于分区的操作
- DETACH PARTITION|PART — 将分区或分片移动到
detached
目录并遗忘它。 - DROP PARTITION|PART — 删除分区或分片。
- DROP DETACHED PARTITION|PART - 从
detached
中删除分区或分片的所有分片。 - FORGET PARTITION — 如果分区为空,则从 ZooKeeper 中删除分区元数据。
- ATTACH PARTITION|PART — 将
detached
目录中的分区或分片添加到表。 - ATTACH PARTITION FROM — 将数据分区从一个表复制到另一个表并添加。
- REPLACE PARTITION — 将数据分区从一个表复制到另一个表并替换。
- MOVE PARTITION TO TABLE — 将数据分区从一个表移动到另一个表。
- CLEAR COLUMN IN PARTITION — 重置分区中指定列的值。
- CLEAR INDEX IN PARTITION — 重置分区中指定的二级索引。
- FREEZE PARTITION — 创建分区的备份。
- UNFREEZE PARTITION — 删除分区的备份。
- FETCH PARTITION|PART — 从另一台服务器下载分片或分区。
- MOVE PARTITION|PART — 将分区/数据分片移动到另一个磁盘或卷。
- UPDATE IN PARTITION — 根据条件更新分区内的数据。
- DELETE IN PARTITION — 根据条件删除分区内的数据。
DETACH PARTITION|PART
ALTER TABLE table_name [ON CLUSTER cluster] DETACH PARTITION|PART partition_expr
将指定分区的所有数据移动到 detached
目录。服务器会忘记分离的数据分区,就好像它不存在一样。在您执行 ATTACH 查询之前,服务器不会知道这些数据。
示例
ALTER TABLE mt DETACH PARTITION '2020-11-21';
ALTER TABLE mt DETACH PART 'all_2_2_0';
阅读 如何设置分区表达式 部分中关于设置分区表达式的内容。
查询执行后,您可以对 detached
目录中的数据执行任何操作 — 从文件系统中删除它,或者只是保留它。
此查询是复制的 – 它将数据移动到所有副本上的 detached
目录。 请注意,您只能在领导者副本上执行此查询。 要找出副本是否为领导者,请对 system.replicas 表执行 SELECT
查询。 或者,更简单的方法是在所有副本上执行 DETACH
查询 - 除了领导者副本之外,所有副本都会抛出异常(因为允许多个领导者)。
DROP PARTITION|PART
ALTER TABLE table_name [ON CLUSTER cluster] DROP PARTITION|PART partition_expr
从表中删除指定的分区。 此查询将分区标记为非活动状态,并在大约 10 分钟后完全删除数据。
阅读 如何设置分区表达式 部分中关于设置分区表达式的内容。
该查询是复制的 – 它会删除所有副本上的数据。
示例
ALTER TABLE mt DROP PARTITION '2020-11-21';
ALTER TABLE mt DROP PART 'all_4_4_0';
DROP DETACHED PARTITION|PART
ALTER TABLE table_name [ON CLUSTER cluster] DROP DETACHED PARTITION|PART ALL|partition_expr
从 detached
中删除指定的分片或指定分区的所有分片。 阅读 如何设置分区表达式 部分中关于设置分区表达式的更多信息。
FORGET PARTITION
ALTER TABLE table_name FORGET PARTITION partition_expr
从 ZooKeeper 中删除关于空分区的所有元数据。 如果分区不为空或未知,查询将失败。 确保仅对永远不会再次使用的分区执行此操作。
阅读 如何设置分区表达式 部分中关于设置分区表达式的内容。
示例
ALTER TABLE mt FORGET PARTITION '20201121';
ATTACH PARTITION|PART
ALTER TABLE table_name [ON CLUSTER cluster] ATTACH PARTITION|PART partition_expr
从 detached
目录向表中添加数据。 可以为整个分区或单独的分片添加数据。 示例
ALTER TABLE visits ATTACH PARTITION 201901;
ALTER TABLE visits ATTACH PART 201901_2_2_0;
阅读 如何设置分区表达式 部分中关于设置分区表达式的更多信息。
此查询是复制的。 副本启动器检查 detached
目录中是否存在数据。 如果数据存在,则查询检查其完整性。 如果一切正确,则查询将数据添加到表中。
如果非启动器副本收到 attach 命令,并在其自身的 detached
文件夹中找到具有正确校验和的分片,它将附加数据,而无需从其他副本中获取它。 如果没有具有正确校验和的分片,则数据将从任何具有该分片的副本下载。
您可以将数据放入一个副本上的 detached
目录中,并使用 ALTER ... ATTACH
查询将其添加到所有副本上的表中。
ATTACH PARTITION FROM
ALTER TABLE table2 [ON CLUSTER cluster] ATTACH PARTITION partition_expr FROM table1
此查询将数据分区从 table1
复制到 table2
。
请注意
- 数据既不会从
table1
也不会从table2
中删除。 table1
可以是临时表。
要使查询成功运行,必须满足以下条件
- 两个表必须具有相同的结构。
- 两个表必须具有相同的分区键、相同的排序键和相同的主键。
- 两个表必须具有相同的存储策略。
- 目标表必须包含源表中的所有索引和投影。 如果在目标表中启用了
enforce_index_structure_match_on_partition_manipulation
设置,则索引和投影必须相同。 否则,目标表可以具有源表的索引和投影的超集。
REPLACE PARTITION
ALTER TABLE table2 [ON CLUSTER cluster] REPLACE PARTITION partition_expr FROM table1
此查询将数据分区从 table1
复制到 table2
,并替换 table2
中的现有分区。 该操作是原子性的。
请注意
- 数据不会从
table1
中删除。 table1
可以是临时表。
要使查询成功运行,必须满足以下条件
- 两个表必须具有相同的结构。
- 两个表必须具有相同的分区键、相同的排序键和相同的主键。
- 两个表必须具有相同的存储策略。
- 目标表必须包含源表中的所有索引和投影。 如果在目标表中启用了
enforce_index_structure_match_on_partition_manipulation
设置,则索引和投影必须相同。 否则,目标表可以具有源表的索引和投影的超集。
MOVE PARTITION TO TABLE
ALTER TABLE table_source [ON CLUSTER cluster] MOVE PARTITION partition_expr TO TABLE table_dest
此查询将数据分区从 table_source
移动到 table_dest
,并从 table_source
中删除数据。
要使查询成功运行,必须满足以下条件
- 两个表必须具有相同的结构。
- 两个表必须具有相同的分区键、相同的排序键和相同的主键。
- 两个表必须具有相同的存储策略。
- 两个表必须是相同的引擎系列(复制或非复制)。
- 目标表必须包含源表中的所有索引和投影。 如果在目标表中启用了
enforce_index_structure_match_on_partition_manipulation
设置,则索引和投影必须相同。 否则,目标表可以具有源表的索引和投影的超集。
CLEAR COLUMN IN PARTITION
ALTER TABLE table_name [ON CLUSTER cluster] CLEAR COLUMN column_name IN PARTITION partition_expr
重置分区中指定列的所有值。 如果在创建表时确定了 DEFAULT
子句,则此查询会将列值设置为指定的默认值。
示例
ALTER TABLE visits CLEAR COLUMN hour in PARTITION 201902
FREEZE PARTITION
ALTER TABLE table_name [ON CLUSTER cluster] FREEZE [PARTITION partition_expr] [WITH NAME 'backup_name']
此查询创建指定分区的本地备份。 如果省略 PARTITION
子句,则查询会立即创建所有分区的备份。
整个备份过程在不停止服务器的情况下执行。
请注意,对于旧式表,您可以指定分区名称的前缀(例如,2019
) - 然后查询会为所有相应的分区创建备份。 阅读 如何设置分区表达式 部分中关于设置分区表达式的内容。
在执行时,为了数据快照,查询会创建到表数据的硬链接。 硬链接放置在 /var/lib/clickhouse/shadow/N/...
目录中,其中
/var/lib/clickhouse/
是在配置中指定的工作 ClickHouse 目录。N
是备份的增量编号。- 如果指定了
WITH NAME
参数,则使用'backup_name'
参数的值代替增量编号。
如果您使用 一组磁盘用于表中的数据存储,则 shadow/N
目录会出现在每个磁盘上,存储与 PARTITION
表达式匹配的数据分片。
备份内部创建的目录结构与 /var/lib/clickhouse/
内部的结构相同。 查询对所有文件执行 chmod
,禁止写入它们。
创建备份后,您可以将数据从 /var/lib/clickhouse/shadow/
复制到远程服务器,然后从本地服务器删除它。 请注意,ALTER t FREEZE PARTITION
查询未复制。 它仅在本地服务器上创建本地备份。
查询几乎立即创建备份(但首先它会等待当前对相应表的查询完成运行)。
ALTER TABLE t FREEZE PARTITION
仅复制数据,而不是表元数据。 要备份表元数据,请复制文件 /var/lib/clickhouse/metadata/database/table.sql
要从备份还原数据,请执行以下操作
- 如果表不存在,则创建表。 要查看查询,请使用 .sql 文件(将其中的
ATTACH
替换为CREATE
)。 - 将数据从备份中的
data/database/table/
目录复制到/var/lib/clickhouse/data/database/table/detached/
目录。 - 运行
ALTER TABLE t ATTACH PARTITION
查询以将数据添加到表。
从备份还原不需要停止服务器。
有关备份和还原数据的更多信息,请参阅 数据备份 部分。
UNFREEZE PARTITION
ALTER TABLE table_name [ON CLUSTER cluster] UNFREEZE [PARTITION 'part_expr'] WITH NAME 'backup_name'
从磁盘中删除具有指定名称的 freezed
分区。 如果省略 PARTITION
子句,则查询会立即删除所有分区的备份。
CLEAR INDEX IN PARTITION
ALTER TABLE table_name [ON CLUSTER cluster] CLEAR INDEX index_name IN PARTITION partition_expr
该查询的工作方式类似于 CLEAR COLUMN
,但它重置索引而不是列数据。
FETCH PARTITION|PART
ALTER TABLE table_name [ON CLUSTER cluster] FETCH PARTITION|PART partition_expr FROM 'path-in-zookeeper'
从另一台服务器下载分区。 此查询仅适用于复制表。
该查询执行以下操作
- 从指定的分片下载分区|分片。 在 ‘path-in-zookeeper’ 中,您必须指定 ZooKeeper 中分片的路径。
- 然后,查询将下载的数据放入
table_name
表的detached
目录中。 使用 ATTACH PARTITION|PART 查询将数据添加到表。
例如
- FETCH PARTITION
ALTER TABLE users FETCH PARTITION 201902 FROM '/clickhouse/tables/01-01/visits';
ALTER TABLE users ATTACH PARTITION 201902;
- FETCH PART
ALTER TABLE users FETCH PART 201901_2_2_0 FROM '/clickhouse/tables/01-01/visits';
ALTER TABLE users ATTACH PART 201901_2_2_0;
请注意
ALTER ... FETCH PARTITION|PART
查询未复制。 它仅将分片或分区放置在本地服务器上的detached
目录中。ALTER TABLE ... ATTACH
查询是复制的。 它将数据添加到所有副本。 数据从detached
目录添加到其中一个副本,并从相邻副本添加到其他副本。
在下载之前,系统会检查分区是否存在以及表结构是否匹配。 最合适的副本会自动从健康的副本中选择。
尽管查询称为 ALTER TABLE
,但它不会更改表结构,也不会立即更改表中可用的数据。
MOVE PARTITION|PART
将分区或数据分片移动到 MergeTree
引擎表的另一个卷或磁盘。 请参阅 使用多个块设备进行数据存储。
ALTER TABLE table_name [ON CLUSTER cluster] MOVE PARTITION|PART partition_expr TO DISK|VOLUME 'disk_name'
ALTER TABLE t MOVE
查询
- 未复制,因为不同的副本可能具有不同的存储策略。
- 如果未配置指定的磁盘或卷,则返回错误。 如果无法应用存储策略中指定的数据移动条件,则查询也会返回错误。
- 在要移动的数据已被后台进程、并发
ALTER TABLE t MOVE
查询或作为后台数据合并的结果移动的情况下,可能会返回错误。 在这种情况下,用户不应执行任何其他操作。
示例
ALTER TABLE hits MOVE PART '20190301_14343_16206_438' TO VOLUME 'slow'
ALTER TABLE hits MOVE PARTITION '2019-09-01' TO DISK 'fast_ssd'
UPDATE IN PARTITION
操作指定分区中与指定过滤表达式匹配的数据。 实现为 mutation。
语法
ALTER TABLE [db.]table [ON CLUSTER cluster] UPDATE column1 = expr1 [, ...] [IN PARTITION partition_expr] WHERE filter_expr
示例
-- using partition name
ALTER TABLE mt UPDATE x = x + 1 IN PARTITION 2 WHERE p = 2;
-- using partition id
ALTER TABLE mt UPDATE x = x + 1 IN PARTITION ID '2' WHERE p = 2;
另请参阅
DELETE IN PARTITION
删除指定分区中与指定过滤表达式匹配的数据。 实现为 mutation。
语法
ALTER TABLE [db.]table [ON CLUSTER cluster] DELETE [IN PARTITION partition_expr] WHERE filter_expr
示例
-- using partition name
ALTER TABLE mt DELETE IN PARTITION 2 WHERE p = 2;
-- using partition id
ALTER TABLE mt DELETE IN PARTITION ID '2' WHERE p = 2;
另请参阅
如何设置分区表达式
您可以通过以下不同方式在 ALTER ... PARTITION
查询中指定分区表达式
- 作为
system.parts
表的partition
列中的值。 例如,ALTER TABLE visits DETACH PARTITION 201901
。 - 使用关键字
ALL
。 它只能与 DROP/DETACH/ATTACH/ATTACH FROM 一起使用。 例如,ALTER TABLE visits ATTACH PARTITION ALL
。 - 作为与表分区键元组匹配(在类型中)的表达式或常量元组。 如果是单元素分区键,则表达式应包装在
tuple (...)
函数中。 例如,ALTER TABLE visits DETACH PARTITION tuple(toYYYYMM(toDate('2019-01-25')))
。 - 使用分区 ID。 分区 ID 是分区的字符串标识符(如果可能,则为人类可读),用作文件系统和 ZooKeeper 中分区的名称。 分区 ID 必须在
PARTITION ID
子句中以单引号指定。 例如,ALTER TABLE visits DETACH PARTITION ID '201901'
。 - 在 ALTER ATTACH PART 和 DROP DETACHED PART 查询中,要指定分片的名称,请使用字符串文字,其值来自 system.detached_parts 表的
name
列。 例如,ALTER TABLE visits ATTACH PART '201901_1_1_0'
。
指定分区时是否使用引号取决于分区表达式的类型。 例如,对于 String
类型,您必须用引号 ('
) 指定其名称。 对于 Date
和 Int*
类型,则不需要引号。
以上所有规则也适用于 OPTIMIZE 查询。 如果您需要在优化非分区表时仅指定分区,请设置表达式 PARTITION tuple()
。 例如
OPTIMIZE TABLE table_not_partitioned PARTITION tuple() FINAL;
IN PARTITION
指定应用 UPDATE 或 DELETE 表达式的分区,作为 ALTER TABLE
查询的结果。 仅从指定分区创建新分片。 通过这种方式,当表分为多个分区时,IN PARTITION
有助于减少负载,而您只需要逐点更新数据。
ALTER ... PARTITION
查询的示例在测试 00502_custom_partitioning_local
和 00502_custom_partitioning_replicated_zookeeper
中进行了演示。