查询语言系列—数据分区

目前 `ALTER` 语句仅支持 `*MergeTree` 表, `Merge` 和 `Distributed`。 此查询有一些变种版本。

列操作

更新表结构。

```sql

ALTER TABLE [db].name [ON CLUSTER cluster] ADD|DROP|MODIFY COLUMN ...

```

在查询中, 指定一个或多个逗号分隔动作的列表。

每一个动作都是在一个列上的操作。

如下的动作支持:

```sql

ADD COLUMN name [type] [default_expr] [AFTER name_after]

```

添加一个新的列到特定名称、类型和 `default_expr`的表中 (查询章节 "默认表达式")。 如果你指定了 `AFTER name_after` (另一个列的名称), 列被添加到指定字段之后。 否则, 列被添加到表的末尾。 注意目前没有方法可以添加列到表的开头。 一系列动作时候, 'name_after' 是一个列的名称, 此列被添加到之前的动作上。

添加一个新列即可改变列的结构, 在执行动作之前。 在ALTER之后, 此数据并没有出现在磁盘上。 当从表中读取数据时, 如果数据丢失, 它使用默认值填充 (如果有1,执行默认表达式, 或者使用0或空字符串)。 对于一个字段, 当从表中读取数据时, 如果数据为空, 它使用默认值填充 (如果有1,执行默认表达式, 或者使用0或空字符串)。 在合并数据块后, 字段出现在磁盘上,(请查看 MergeTree)。

此方法允许我们完成 ALTER 查询, 不需要增加旧数据的数据量。

```sql

DROP COLUMN name

```

删除带有名称'name'的列。

删除文件系统中的数据。 此语句删除整个文件, 查询立即完成。

```sql

MODIFY COLUMN name [type] [default_expr]

```

更新 'name' 字段的类型为 'type' 同时默认的表达式为 'default_expr'。 当更新类型时值被转换,如果'toType'函数被使用时。

如果仅有默认的表达式被改变, 此查询并不做任何复杂的操作, 并且查询立即完成。

更新字段类型是一个稍微复杂的动作 – 它更新带有数据的文件内容。 对于大表, 它可能需要比较长的时间。

有下面几个处理阶段:

- 准备带有更新数据的临时(新)文件。

- 重命名旧文件。

- 重命名临时(新)文件到旧名称。

- 删除旧文件。

仅有第一阶段花费时间。 如果在这个阶段出现故障, 数据将不会被更新。

如果在连续阶段的某个环节出现故障,数据得进行手工恢复。例如,如果旧的文件从文件系统删除,但是新文件中的数据还没有写入到磁盘中,数据会丢失。

目前不支持对数组和嵌套数据结构中的列类型进行更新。

`ALTER` 查询可以创建和删除嵌套数据结构中单独的元素 (列), 但是并不是整个数据结构。 为了添加一个嵌套数据结构,你需要添加带有名称如`name.nested_name` 的列和类型`Array(T)`。 一个嵌套数据结构等价于带有逗号之前有相同前缀的多个数组列。

目前不支持使用主键或样本键删除列 (列在 `ENGINE` 表达式中)。 对于包含在主键中的字段,更新类型仅可能发生在不导致数据更新的情况下 (例如, 添加相应的值到 Enum 类型中或者更新一个`DateTime`类型到 `UInt32`)。

如果 `ALTER` 查询不足以进行表更新操作,你能够创建一个新表,使用 `INSERT SELECT`语句拷贝数据到这个表,然后使用`RENAME`查询切换表和删除旧表。

`ALTER` 查询为表阻塞所有的读和写操作。换句话说,如果一个长的 `SELECT` 在 `ALTER` 查询时运行, `ALTER` 查询将等待它结束。与此同时,当`ALTER`正在运行时, 对于相同的表所有新的查询将等待。

对于本身不保存数据的表(例如 `Merge` 和 `Distributed`), `ALTER` 更改表结构,同时不更改下级表的结构。例如,当在 `Distributed` 表中运行ALTER, 你也需要在所有远程服务器的表上运行 `ALTER`。

对于更改列的 `ALTER` 查询是复制的。 此工具方法保存在ZooKeeper中, 然后每个复制节点执行他们。 所有的 `ALTER` 查询按照相同的顺序运行。 在其他复制节点,此查询等待合适的动作执行完成。 然而,在一个复制表中,更改列的查询能够被中断,同时所有的动作将异步执行。


## 操作表分区和数据分片

它仅在MergeTree的引擎上发挥作用. 具体操作如下所示:

DETACH PARTITION – 移动分区到 'detached' 目录.

DROP PARTITION – 删除一个分区.

ATTACH PART|PARTITION – 从卸载的目录中添加一个新的数据分片或分区到表中

FREEZE PARTITION – 创建一个分区的备份.

FETCH PARTITION – 从另一个服务器上下载一个分区.

查询的每个类型都单独覆盖.

表中的一个分区是一个单月份的数据. 通过表引擎指定的日期键的值来进行决定。 每个月的数据单独保存为了简化数据的操作.

表中的分片是单独分区的一部分数据, 通过主键来筛选数据.

你能够使用 system.parts 表来查看表分区或分片的具体信息:

SELECT * FROM system.parts WHERE active

active – 仅计数实际活跃的分片. 不活跃的分片, 例如, 保留的源数据分片在合并之后变成了更大的部分 – 这些分片大概在合并后10分钟内被删除。

查看数据分片和数据分区的另外一个方法是到数据目录中查看. 数据目录: /var/lib/clickhouse/data/database/table/, 其中 /var/lib/clickhouse/ 是到clickhouse数据的一个路径, 'database' 是数据库名称,  'table' 是表名. 例如:

$ ls -l /var/lib/clickhouse/data/test/visits/total48drwxrwxrwx2clickhouse clickhouse20480May502:58 20140317_20140323_2_2_0drwxrwxrwx2clickhouse clickhouse20480May502:58 20140317_20140323_4_4_0drwxrwxrwx2clickhouse clickhouse4096May502:55 detached-rw-rw-rw-1clickhouse clickhouse2May502:58 increment.txt

其中, 20140317_20140323_2_2_0 和 20140317_20140323_4_4_0 是数据分片的目录.

让我们看下第一个分片的名称 : 20140317_20140323_2_2_0.

20140317 是数据块中数据的最小日期

20140323 是数据块中数据的最大日期

2 是数据块的最小号码

2 是数据块的最大号码

0 是数据块的层级 (合并树的深度).

每个数据分片都和一个分区相互关联,包含了一个月的数据. 201403 是一个分区的名称. A 一个分区是一个单月数据的分片集合.

在生产环境中正在运行的服务器上,你不能手动更新文件系统的数据分片集合, 因为修改后服务器会找不到数据分片. 对于非同步表, 当服务器停机时,你可以做这个操作, 但是不建议这么操作. 对于同步表, 数据分片集合在任何情况下都不能修改.

卸载目录包含了服务器未使用的数据分片 - 使用 ALTER ... DETACH 语句来从表中卸载. 损坏的数据分片也 移动到此目录, 而不是删除它们. 你能够在任意时间添加、删除或修改'卸载'目录中的数据 – 当执行了 ALTER TABLE ... ATTACH 后 服务器才知道具体的数据分区信息.

ALTER TABLE [db.] table DETACH PARTITION 'name'

移动分区中所有的数据 到'卸载'目录. 分区名称通过 YYYYMM 格式来指定.

在查询执行后,你能够对'卸载'目录中的数据进行任意操作  — 从文件系统中删除它, 或者保留它作为归档.

查询是复制的 – 数据可将被移动到 '卸载' 目录,然后留在目录中. 查询仅能够发送给一个领导者(leader)副本. 为了找到哪个是领导者, 可执行 SELECT语句查询 'system.replicas' 系统表. 另外, 为了更方便查询所有的副本, 当发生错误时,所有副本都将抛出异常.

ALTER TABLE [db.] table DROP PARTITION 'name'

这个与 DETACH 操作相同. 从表中删除数据. 数据分片被标记为'不活跃' , 大约10分钟能够完全删除完毕. 查询是复制的 – 数据将在所有副本节点上删除.

ALTER TABLE [db.] table ATTACH PARTITION | PART 'name'

添加数据到'卸载'目录的表

为整个数据分区或单独的数据分片添加数据是需求的. 对于一个数据分片, 指定数据分区的全名.

查询是复制的. 每个副本检查是否 有数据在 '卸载' 目录.  如果有数据, 它将检查完整性, 验证数据是否匹配, 然后验证是否每个步骤是否都是正确的. 如果不正确, 它将从查询请求副本或者另外的副本中下载数据, 这些副本已经添加数据了.

因此,在副本中,你能够放数据到 '卸载' 目录, 同时使用 ALTER ... ATTACH 查询来添加数据到所有副本的表中.

ALTER TABLE [db.] table FREEZE PARTITION 'name'

从一个或多个分区中创建一个本地备份. 名称是分区的全名 (例如, 201403), 或者 它的前缀 (例如, 2014): 然后为所有对应的分区创建备份.

查询执行如下: 对于一个时间点的数据快照, 它创建硬链接到表数据,目录为 /var/lib/clickhouse/shadow/N/...

/var/lib/clickhouse/ 是一个配置中的工作目录. N 备份的增量数字.

相同的目录结构在备份的目录中被创建出来 /var/lib/clickhouse/. 同时也可以为所有文件执行 'chmod' 命令, 防止对文件进行写入.

备份可立即被创建(但是它需要等待当前的查询结束后执行)。首先,备份不占用任何磁盘空间。当系统运行时,数据有更新操作,备份将耗费磁盘空间;如果备份的是历史数据,那么将不耗费磁盘空间。

在创建备份之后, /var/lib/clickhouse/shadow/ 中的数据被拷贝到远程服务器上,然后在本地服务器上删除。整个备份过程执行不需要停服务器。

ALTER ... FREEZE PARTITION 查询是不同步的. 一个本地备份仅创建在本地服务器.

作为替代, 你可以手工拷贝数据从 /var/lib/clickhouse/data/database/table 目录. 但是,如果你在服务器运行时拷贝数据, 当文件正在添加或更改时,拷贝目录可能产生竞争条件, 可能导致备份不一致. 如果服务器没有运行,那么你可以做此操作  – 然后结果数据和 ALTER TABLE t FREEZE PARTITION 执行后的数据基本相同.

ALTER TABLE ... FREEZE PARTITION 仅拷贝数据, 不拷贝表的元数据. 为了备份表的元数据, 拷贝文件 /var/lib/clickhouse/metadata/database/table.sql.

为了从备份中恢复:

使用 CREATE 语句来创建表. 语句将从一个.sql 文件中加载 (用 CREATE 来替代 ATTACH).

从目录 data/database/table/ 拷贝数据到 /var/lib/clickhouse/data/database/table/detached/ 目录.

运行 ALTER TABLE ... ATTACH PARTITION YYYYMM 查询, 其中 YYYYMM 是月份.

在这种方式下, 在备份中的数据将被添加到表中. 从备份中恢复数据不需要停服务器.

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,013评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,205评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,370评论 0 342
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,168评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,153评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,954评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,271评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,916评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,382评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,877评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,989评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,624评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,209评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,199评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,418评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,401评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,700评论 2 345

推荐阅读更多精彩内容