跳至主要内容

操作分区和数据块

可以使用以下操作来操作分区

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

请注意

  • 数据不会从 table1table2 中删除。
  • table1 可以是临时表。

要使查询成功运行,必须满足以下条件

  • 两个表必须具有相同的结构。
  • 两个表必须具有相同的 partition key、相同的 order by key 和相同的 primary key。
  • 两个表必须具有相同的索引和投影。
  • 两个表必须具有相同的存储策略。

REPLACE PARTITION

ALTER TABLE table2 [ON CLUSTER cluster] REPLACE PARTITION partition_expr FROM table1

此查询将数据分区从 table1 复制到 table2 并替换 table2 中现有的分区。此操作是原子的。

请注意

  • 数据不会从 table1 中删除。
  • table1 可以是临时表。

要使查询成功运行,必须满足以下条件

  • 两个表必须具有相同的结构。
  • 两个表必须具有相同的 partition key、相同的 order by key 和相同的 primary key。
  • 两个表必须具有相同的索引和投影。
  • 两个表必须具有相同的存储策略。

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 中删除数据。

要使查询成功运行,必须满足以下条件

  • 两个表必须具有相同的结构。
  • 两个表必须具有相同的 partition key、相同的 order by key 和相同的 primary key。
  • 两个表必须具有相同的索引和投影。
  • 两个表必须具有相同的存储策略。
  • 两个表必须属于相同的引擎系列(复制或非复制)。

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

要从备份还原数据,请执行以下操作

  1. 如果表不存在,则创建它。要查看查询,请使用.sql文件(将其中的ATTACH替换为CREATE)。
  2. 将备份内部data/database/table/目录中的数据复制到/var/lib/clickhouse/data/database/table/detached/目录。
  3. 运行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'

从另一台服务器下载分区。此查询仅适用于复制表。

该查询执行以下操作

  1. 从指定的shard下载分区/数据块。在“path-in-zookeeper”中,您必须指定ZooKeeper中shard的路径。
  2. 然后,查询将下载的数据放入table_name表的detached目录中。使用ATTACH PARTITION|PART查询将数据添加到表中。

例如

  1. FETCH PARTITION
ALTER TABLE users FETCH PARTITION 201902 FROM '/clickhouse/tables/01-01/visits';
ALTER TABLE users ATTACH PARTITION 201902;
  1. 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 PARTDROP DETACHED PART查询中,要指定数据块的名称,请使用字符串文字,其值为system.detached_parts表的name列中的值。例如,ALTER TABLE visits ATTACH PART '201901_1_1_0'

指定分区时是否使用引号取决于分区表达式的类型。例如,对于String类型,您必须用引号(')括起来指定其名称。对于DateInt*类型,不需要使用引号。

上述所有规则也适用于OPTIMIZE查询。如果需要在优化非分区表时指定唯一的分区,请设置表达式PARTITION tuple()。例如

OPTIMIZE TABLE table_not_partitioned PARTITION tuple() FINAL;

IN PARTITION指定ALTER TABLE查询导致的UPDATEDELETE表达式应用到的分区。新数据块仅从指定的分区创建。这样,IN PARTITION有助于减少表被划分为多个分区时的负载,而您只需要逐点更新数据。

ALTER ... PARTITION查询的示例在测试00502_custom_partitioning_local00502_custom_partitioning_replicated_zookeeper中演示。