ClickHouse数据库引擎引起的数据丢失

转载说明:如果您喜欢这篇文章并打算转载它,请私信作者取得授权。感谢您喜爱本文,请文明转载,谢谢。


1. 问题

在测试环境运行了3个月的一套测试工具,突然报错了,界面各种Error,数据都显示不出来。

后端数据库是使用容器部署的clickhouse数据库。登录数据库查看database和table,发现database存在,但是table全部没有了。

2. 排查

1)有权限的小伙伴均未删除过表,且查看数据库的语句执行记录,无删除表操作,基本排除人为误删;

2)查看clickhouse挂载到本地的数据目录(对应容器的/var/lib/clickhouse目录),文件完整,且到data目录下找到对应的库目录,可以看到里面的表文件是存在的。

3)尝试登录clickhouse,在database下重建这些table,提示:TABLE_ALREADY_EXISTS

3. 原因

经过排查和查询资料发现,原因在建库的时候建库语句中使用了参数"ENGINE = Memory",这个参数代表数据库的元数据(即库里有几张表、表名叫什么)只缓存在内存中,不会持久化到磁盘。一旦服务发生重启,内存被清空,数据就没有了。

对于持久化引擎(如 MergeTree),数据才会被写入磁盘,写入 /var/lib/clickhouse/data/数据库名/ 目录下。

之所以在/var/lib/clickhouse下还能看到表文件,是因为建表时使用的MergeTree引擎。但因为库是用的memory引擎,在容器发生重启后,内存中的元数据丢失,数据库变成了一个"空壳子",无法与MergeTree 表关联起来。

4. 解决方案

一旦 ClickHouse 服务重启,使用 ENGINE = Memory 创建的表中的数据无法找回。这是该引擎的固有特性,只能删除重建。因此Memory 引擎仅适用于以下特定场景:

  • 临时数据:处理查询时用到的外部数据。

  • 测试环境:跑一些不要求数据保留的测试用例。

  • 缓存或中间结果:行数极少(官方建议不超过1亿行)、允许丢失的极速查询表。

5. 测试复现

5.1 复用记录ClickHouse部署并开通AI远程对接的clickhouse,在clickhouse数据库创建2个测试database

创建带"ENGINE = Memory"参数的database---test

复制代码
# 创建库test:
CREATE DATABASE test ENGINE = Memory COMMENT 'The memory test database';
# 创建一张表users:
CREATE TABLE users (
    id UInt32,
    name Test,
    age UInt8,
    email String,
    created_at DateTime
) ENGINE = MergeTree()  #为复现问题,依然采用MergeTree引擎
ORDER BY id; 

创建不带"ENGINE = Memory"参数的database---test001

复制代码
# 创建库test001:
CREATE DATABASE test001 COMMENT 'The memory test database';
# 创建一张表users001:
CREATE TABLE users001 (
    id UInt32,
    name Test,
    age UInt8,
    email String,
    created_at DateTime
) ENGINE = MergeTree()
ORDER BY id; 

创建完毕:

创建好后,查看容器的/var/lib/clickhouse目录下的test和test001下的文件,是有差异的:

注意:因为2个库的表都用的ENGINE = MergeTree,才会看到这个目录,如果test库下面的users表使用的是ENGINE = Memory,test下是不会生成users这个目录的,test目录下将会是空的。

5.2 然后重启clickhouse容器

5.3 再次进入容器查看test和test001下面的表,检查表,可以看到test库下面的表没了,而test001下面的表还在:

5.4 进入test下面重新建表,提示表已经存在:

但关联clickhouse的服务已经不停报错表不存在了,无法查询到表和数据。

欢迎关注SRE成长记一起探讨学习!↓↓↓

相关推荐
海浪仙人掌1 小时前
应收账款分析如何操作?应收账款分析有哪些注意事项?
数据库·人工智能
Elastic 中国社区官方博客1 小时前
在 Elasticsearch 中回填时间序列数据:通过批量 API 加载数月的历史指标数据
大数据·运维·数据库·人工智能·elasticsearch·搜索引擎·全文检索
Horn Still Sounds1 小时前
Linux网络并发服务器模型与SQLite数据库学习笔记
linux·服务器·数据库
昵称画2 小时前
POC验证怎么设计用例?不走过程的实操要点
大数据·数据库·人工智能·低代码·excel
TDengine (老段)2 小时前
TDengine Catalog 与元数据缓存
大数据·数据库·物联网·缓存·时序数据库·tdengine
CarIise2 小时前
MySQL数据库表关系与多表查询:从表间关系设计到JOIN联表查询
数据库·mysql
网络工程小王3 小时前
【LLM开发实验】FastAPI 学习笔记
数据库·笔记·学习·mysql·fastapi
Aime_Perfect3 小时前
sqlserver always on
服务器·数据库·sqlserver
摘星编程3 小时前
从“数据出库“到“模型入库“:DolphinDB 库内机器学习全流程实践
数据库