从未经授权的ClickHouse迁移到具有授权的ClickHouse的结果是什么?


让我们从一些背景开始。 在我们公司中,一个项目正在维护中,直到最近才处于测试/开发阶段。 当时,它使用了带有3个碎片(每个2个副本)的ClickHouse。 考虑到该项目的基础架构是经过测试的,不需要任何其他授权(ClickHouse位于封闭部分),因此没有人提出这个问题。


随着时间的推移,该项目不断壮大,ClickHouse成为了生产基地,我们将数据从旧基础架构迁移到了新的基础架构,其中包含1个分片,3个不同服务器上的3个副本(ClickHouse位于基于StatefulSets的Kubernetes中),当然还有授权。


这是接下来发生的事情。


在生产中启动项目后,几乎立即发现,在用户数据库的datadir ClickHouse中的非分片表(在我们的示例中,是位于每个节点本地的那些表,没有分片后缀,类型为Distributed),其中有很多没有丢失二进制日志。 日志的日期早于ClickHouse授权的安装日期。


以下是测试数据库的表table_1的ClickHouse副本之一的控制台输出:


ls -l /var/lib/clickhouse/data/test/table_1/test_usr@clickhouse%2D0%2Eclickhouse%2Eclickhouse%2Dprod%2Esvc%2Ecluster%2Elocal\:9000 | tail -n 10 -rw-r----- 1 clickhouse clickhouse 1472 Jul 8 08:26 9983.bin -rw-r----- 1 clickhouse clickhouse 1453 Jul 8 08:26 9985.bin -rw-r----- 1 clickhouse clickhouse 1383 Jul 8 08:26 9987.bin -rw-r----- 1 clickhouse clickhouse 1461 Jul 8 08:27 9989.bin -rw-r----- 1 clickhouse clickhouse 1458 Jul 8 08:28 9991.bin -rw-r----- 1 clickhouse clickhouse 1468 Jul 8 08:29 9993.bin -rw-r----- 1 clickhouse clickhouse 1413 Jul 8 08:29 9995.bin -rw-r----- 1 clickhouse clickhouse 1509 Jul 8 08:32 9997.bin -rw-r----- 1 clickhouse clickhouse 1504 Jul 8 08:32 9999.bin drwxr-x--- 2 clickhouse clickhouse 4096 Sep 16 12:59 tmp 

即 数据本身被放置在特定副本的本地Distributed表中,但是由于当时的未知原因,它没有被移动到带有分片后缀(例如ReplicatedMergeTree)的表中,而该后缀可以通过本地表(不带后缀)访问所有集群副本而访问分片)。


分析后发现,记录在旧基础架构上的ClickHouse数据库中的数据,即 在启用授权之前,它们将无法再在新基础架构上的副本之间分发,因为 在新的ClickHouse服务器上,授权已启用。


为什么这样 未经授权将数据写入ClickHouse时,将在相应数据库目录和表的clickHouse datadir目录中生成以下形式的链接(该链接是基于对数据库的请求生成的):


 test_usr@clickhouse%2D0%2Eclickhouse%2Eclickhouse%2Dprod%2Esvc%2Ecluster%2Elocal\:9000 

让我们更详细地看一下。 上面的链接由用户test_usr访问,但未指定授权密码。 发生了什么,如果在数据库中启用授权之前,在ClickHouse中记录了大量数据,形成了bin日志,而旧服务器上的ClickHouse没有时间丢失它们,那么在新的ClickHouse服务器上启用授权并迁移旧的而不丢失后, bin日志到新服务器,这些bin日志将不再播放,因为 链接已经在未经用户test_usr授权的情况下生成。


ClickHouse中所有新传入的数据还将在相应的数据库目录和表中生成bin-log,然后将其播放,但具有不同的链接,其中指示了授权(因为应用程序已在新基础架构上访问ClickHouse是使用用户test_usr的密码进行的,否则请求将不会到达数据库):


 test_usr:password@clickhouse%2D0%2Eclickhouse%2Eclickhouse%2Dprod%2Esvc%2Ecluster%2Elocal\:9000 

因为 数据被异步写入数据库,也就是说,它们首先被放置在一个被访问的本地ClickHouse副本上,然后才被发送到集群的其他副本。


因此,记录在本地ClickHouse副本之一上的旧数据,但是没有在其余的群集副本中分发(由于生成的链接不包含用户密码,但已经设置了),因此甚至无法访问它们。读取未应用的二进制日志直接位于的副本。


我们如何解决问题并且没有丢失未分配的数据?


事实证明一切都很简单。 对数据库中未分配的数据执行以下操作就足够了:


  1. 为问题数据库的每个表生成的链接应重命名(重命名)为所需的形式:
     mv /var/lib/clickhouse/data/test/table_1/test_usr@clickhouse%2D0%2Eclickhouse%2Eclickhouse%2Dprod%2Esvc%2Ecluster%2Elocal\:9000 /var/lib/clickhouse/data/test/table_1/test_usr:password@clickhouse%2D0%2Eclickhouse%2Eclickhouse%2Dprod%2Esvc%2Ecluster%2Elocal\:9000 
  2. 重新启动ClickHouse副本,这将启动播放bin日志并将其放置在分片表(ReplicatedMergeTree)中的过程。

PS :我建议所有人检查其ClickHouse服务器的运行以了解所描述的问题。 如果找到了这些内容,那么本说明将帮助您节省寻找解决方案的时间,并在以后设置/更改ClickHouse密码时更加小心。


另请阅读我们博客上的其他文章:


Source: https://habr.com/ru/post/zh-CN468779/


All Articles