前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >如何在ClickHouse中快速实现AB表切换

如何在ClickHouse中快速实现AB表切换

作者头像
Nauu
发布2021-05-27 14:46:20
2.2K0
发布2021-05-27 14:46:20
举报

AB 表切换的使用场景应该说还是很广泛的,比如历史表归档、批量抽数的时候都可以采用 AB 表切换的思路来实现。

比如有这样一个场景,test_a 是面向终端查询的数据表,数据每天定点全量更新。为了减少数据更新对查询的影响,这里准备用 AB 表切换的思路进行。

在数据更新时,首先写入一张按日期编号的 B 表,例如 test_a_2021_04_29。当 B 表数据写完以后,将 AB 两张表切换。

那么在 ClickHouse 中怎样实现 AB 两张表的快速切换呢? 这里介绍两种主要的方法。

  • 第一种是利用 RENAME 语法

首先新建 AB 两张表

代码语言:javascript
复制
 CREATE TABLE test_a_2021_04_29(
   id UInt32,
   name String,
   value UInt32
 )ENGINE = MergeTree()
 ORDER BY id
 
 CREATE TABLE test_a(
   id UInt32,
   name String,
   value UInt32
 )ENGINE = MergeTree()
 ORDER BY id

首先向 test_a_2021_04_29 写入一千万测试数据:

代码语言:javascript
复制
INSERT INTO TABLE test_a_2021_04_29(id,name,value)
WITH(
  SELECT ['A','B','C','D','E','F','G']
)AS dict
SELECT number AS id, dict[number%7+1],id FROM numbers(10000000)

写完之后进行 AB 切换:

代码语言:javascript
复制
RENAME TABLE test_a_2021_04_29 TO tmp, test_a TO test_a_2021_04_29, tmp TO test_a

Query id: d23eda37-b494-48ea-8a6f-64f319b172f6

Ok.

0 rows in set. Elapsed: 0.013 sec.

可以发现,这里利用了一张临时表 tmp,实现了 AB 表名的切换,是不是很方便呢?

现在验证一下效果,首先查询 test_a,可以看到一千万数据已经在这张表了:

代码语言:javascript
复制
SELECT COUNT()
FROM test_a

Query id: 51335286-55f6-4e79-8207-d39afffbd18c

┌──count()─┐
│ 10000000 │
└──────────┘

而 test_a_2021_04_29 已经没有数据了:

代码语言:javascript
复制
SELECT COUNT()
FROM test_a_2021_04_29

Query id: 7ad19597-0ad8-4544-878b-701a8fa6c0f6

┌─count()─┐
│       0 │
└─────────┘

1 rows in set. Elapsed: 0.003 sec.

RENAME TABLE A TO C, B TO A, C TO B 虽然很方便,但也存在一定的风险,因为利用到了中间临时表,所以整个过程不是原子的,如果出现意外可能会导致不一致的情况发生,于是 ClickHouse 提供了第二种方式。

  • 第二种是利用 EXCHANGE TABLES 语法

在新版本中,ClickHouse 提供了一种新的 Atomic 数据库引擎,在这个引擎下创建的数据表,能够支持无锁的 CREATE/DROP/RENAME 操作,并且支持

EXCHANGE TABLES A and B 直接交换两张表。

继续用例,首先新建一个 Atomic 数据库:

代码语言:javascript
复制
CREATE DATABASE test_atom ENGINE = Atomic

查看它的元数据,就会发现它和 Ordinary 数据库的不同:

代码语言:javascript
复制
% cat ./data/metadata/test_atom.sql 
ATTACH DATABASE _ UUID 'fa22ace8-05a9-4cba-9366-97e625fad12f'
ENGINE = Atomic

元数据中,Atomic 数据库没有名字,取而代之的是一个 UUID。

进一步查看数据库文件,也能发现不同。Ordinary 数据库是一个目录,而 Ordinary 数据库则是一个文件链接,指向了 store 目录下,以 UUID 为名称的目录。

代码语言:javascript
复制
% ls -l
total 24
drwxr-xr-x  27 nauu  staff  864  4 29 21:17 default
-rw-r-----   1 nauu  staff   42  8 10  2020 default.sql
drwxr-xr-x   6 nauu  staff  192  1 28 21:52 system
-rw-r-----   1 nauu  staff   41  1 28 21:51 system.sql
lrwxr-xr-x   1 nauu  staff   71  4 29 21:41 test_atom -> /media/psf/ch9-data/data/store/fa2/fa22ace8-05a9-4cba-9366-97e625fad12f
-rw-r-----@  1 nauu  staff   78  4 29 21:41 test_atom.sql

在 Atomic 数据库下新建 AB 表:

代码语言:javascript
复制
 CREATE TABLE test_atom.test_a_2021_04_29(
   id UInt32,
   name String,
   value UInt32
 )ENGINE = MergeTree()
 ORDER BY id
 
 CREATE TABLE test_atom.test_a(
   id UInt32,
   name String,
   value UInt32
 )ENGINE = MergeTree()
 ORDER BY id

在以 test_atom 数据库 UUID 命名的目录下,发现了两张表的元数据:

代码语言:javascript
复制
% pwd
/data/store/fa2/fa22ace8-05a9-4cba-9366-97e625fad12f

% ls -l
total 16
-rw-r-----  1 nauu  staff  183  4 29 21:52 test_a.sql
-rw-r-----  1 nauu  staff  183  4 29 21:52 test_a_2021_04_29.sql

同样的,这些表的元数据也没有表名,用唯一的 UUID 取而代之:

代码语言:javascript
复制
% cat ./test_a_2021_04_29.sql 
ATTACH TABLE _ UUID 'ae429533-a558-4e59-8232-950f5dc970be'
(
    `id` UInt32,
    `name` String,
    `value` UInt32
)
ENGINE = MergeTree
ORDER BY id
SETTINGS index_granularity = 8192

 % cat ./test_a.sql 
ATTACH TABLE _ UUID '2839166f-4c7c-4d57-ad21-8615a79d71f6'
(
    `id` UInt32,
    `name` String,
    `value` UInt32
)
ENGINE = MergeTree
ORDER BY id
SETTINGS index_granularity = 8192

从系统表也能看出两种数据库的表差异,非 Atomic 是没有 UUID 的:

代码语言:javascript
复制
SELECT database ,name,uuid ,data_paths ,metadata_path FROM  `system`.tables t WHERE name = 'test_a'

现在可以直接用 EXCHANGE TABLES 交换两张表,这个操作是原子的。

代码语言:javascript
复制
EXCHANGE TABLES test_atom.test_a AND test_atom.test_a_2021_04_29;

不过这里有一点值得注意,EXCHANGE TABLES 的原子性是利用了底层系统的 renameat2 命令。它只有至少在 linux kernel 3.15 的操作系统上才能支持。

所以如果你的 linux kernel 版本不够,是不能使用 EXCHANGE TABLES 的,会得到 RENAME EXCHANGE is not supported 的错误。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-04-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 ClickHouse的秘密基地 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
数据库
云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档