ClickHouse 更新操作导致不可写,应该选择哪种表引擎?
一个工作日下午,某大型通信运营商业务人员报告,一套 ClickHouse 集群在进行插入数据操作的时候,系统报错 too many mutations(1036)
,插入数据失败!
作者:张宇,爱可生DBA,负责数据库运维和故障分析。擅长 ClickHouse、MySQL、Oracle,爱好骑行、AI、动漫和技术分享。
爱可生开源社区出品,原创内容未经授权不得随意使用,转载请联系小编并注明来源。
本文约 1500 字,预计阅读需要 5 分钟。
回到现场
一个工作日下午,某大型通信运营商业务人员报告,一套 ClickHouse 集群在进行插入数据操作的时候,系统报错 too many mutations(1036)
,插入数据失败!
排查过程中发现,系统表 system.mutations
里(is_done=0)存在大量的未处理的更新(mutations)操作,且都是 alter table xxx update xxx
语句。
与业务沟通之后得知,业务每天有 50 次左右的数据更新操作,若更新失败则会重试直至成功。每个节点会因数据不同,对应数量不等的 mutations 操作。
先说故障原因。系统设置的 mutations 最大值为 1000,超过会导致插入操作失败(业务数据无法新增)。
基本信息
先了解一下这套 ClickHouse 集群的情况。
- ClickHouse 版本:23.9.1
- 集群架构:2 副本,11 分片
- 数据量:约 4 TB(11×362GB)
- 部署规划:
副本交叉部署,高可用业务无感知。
恢复思路
在 ClickHouse 数据库当中,mutations 操作语句 alter table xxx update/delete
操作会对表产生非常大的工作负载。
再确认业务操作流程无法修改后,只能选择适配这类操作,计划将表引擎改造为更适合覆盖更新的类型,如:
- ReplacingMergeTree
- CollapsingMergeTree
- VersionedCollapsingMergeTree
这几种类型的引擎,可以通过复制功能(Replicated)来控制更新。这样既能保证快速查询能力,也不会让系统耗费大量的资源,保证系统的健壮性。
三种类型的使用方式本文不做介绍,可以在官方文档查询。
现在,需要尽快回复业务。经业务沟通后,将按照以下流程恢复服务:
- 清理 mutations
- 更新表引擎
- 启动服务
- 验证解决
1. 清理 mutations
我们选择整个集群 23805 个 mutations 通过 kill mutation
的方式"杀掉"。然后尽快修改表引擎类型,回复业务使用。
-- kill 掉未完成的 mutation KILL MUTATION WHERE database = 'default' AND table = 'table'
2. 更新表引擎
三种表引擎有多种优化方式,这里演示 ReplacingMergeTree 的一种。
准备数据库
-- 创建 ReplacingMergeTree 表 CREATE TABLE hackernews_rmt ( id UInt32, author String, comment String, views UInt64 ) ENGINE = ReplacingMergeTree PRIMARY KEY (author, id) -- 插入两行数据 INSERT INTO hackernews_rmt VALUES (1, 'ricardo', 'This is post #1', 0), (2, 'ch_fan', 'This is post #2', 0) -- 在插入两行数据 INSERT INTO hackernews_rmt VALUES (1, 'ricardo', 'This is post #1', 100), (2, 'ch_fan', 'This is post #2', 200)
经过查询,表里面存在 4 行数据。建表的时候主键是author
和 id
,当没有指定 ORDER BY 的时候,和主键一致。
现在使用 final
查询,如果排序键相同(在这里是 id,author
)会自动选择最新的插入的数据。
然后当我们使用 optimize
进行分区合并的时候,会直接删除旧数据保留新数据。合并是 ClickHouse 系统自动判断,无需手工处理,这里是为了演示手工执行了 optimize
的效果。
我们使用以上方式进行表引擎更改优化,优化后查询判断是否产生新的 mutations。
-- default 是集群名称,不是用户名称 SELECT count(*) FROM clusterAllReplicas('default', system.mutations) WHERE is_done = 0;
选择替换数据库引擎替换成 ReplacingMergeTree 后业务恢复正常,本次故障共造成业务暂停 30 分钟。
总结
- 及时监控,分析 mutations 的原因并根据业务需求进行分析和处理。
- 如果业务存在频繁的 UPDATE 或 DELETE 操作产生大量 mutations,建议更换表引擎。
- 如果 mutations 是由于增加字段或列等操作产生的,可忽略第 2 条。
优化数据更新和删除策略: 设计数据更新和删除策略时,应考虑系统的承载能力和潜在的风险。优化业务逻辑来减少不必要的数据更新和删除操作,并在操作失败时采取更合理的重试策略,如果是少量或者偶尔的删除可以使用 ClickHouse 轻量级删除(Lightweight Deletes)。
后记:经过该解决方案处理后,至今已稳定运行 4 个月。
更多技术文章,请访问:https://opensource.actionsky.com/
关于 SQLE
SQLE 是一款全方位的 SQL 质量管理平台,覆盖开发至生产环境的 SQL 审核和管理。支持主流的开源、商业、国产数据库,为开发和运维提供流程自动化能力,提升上线效率,提高数据质量。
✨ Github:https://github.com/actiontech/sqle
📚 文档:https://actiontech.github.io/sqle-docs/
💻 官网:https://opensource.actionsky.com/sqle/
👥 微信群:请添加小助手加入 ActionOpenSource

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
openGauss dfx工具梳理
日志pg_log 文档链接:https://docs-opengauss.osinfra.cn/zh/docs/latest/docs/DatabaseReference/%E9%94%99%E8%AF%AF%E6%8A%A5%E5%91%8A%E5%92%8C%E6%97%A5%E5%BF%97.html 主要看的一般就是pg_log。 pg_log的记录内容、格式、级别等,都有相关的GUC进行控制。 常用的:log_min_messages、logging_module。 openGauss 系列表视图函数 文档链接1:https://docs-opengauss.osinfra.cn/zh/docs/latest/docs/SQLReference/%E5%87%BD%E6%95%B0%E5%92%8C%E6%93%8D%E4%BD%9C%E7%AC%A6.html 文档链接2:https://docs-opengauss.osinfra.cn/zh/docs/latest/docs/DatabaseReference/%E7%B3%BB%E7%BB%9F%E8%A7%86%E5...
- 下一篇
Elasticsearch:Painless scripting 语言(一)
Painless 是一种高性能、安全的脚本语言,专为 Elasticsearch 设计。你可以使用 Painless 在 Elasticsearch 支持脚本的任何地方安全地编写内联和存储脚本。 Painless 提供众多功能,这些功能围绕以下核心原则: 安全性:确保集群的安全性至关重要。为此,Painless 使用细粒度的允许列表,粒度细到类的成员。任何不属于允许列表的内容都会导致编译错误。请参阅Painless API 参考,了解每个脚本上下文的可用类、方法和字段的完整列表。 性能:Painless 直接编译为 JVM 字节码,以利用 JVM 提供的所有可能的优化。此外,Painless 通常会避免在运行时需要额外较慢检查的功能。 简单性:Painless 实现的语法对任何具有一些基本编码经验的人来说都很自然熟悉。Painless 使用 Java 语法的子集,并进行了一些额外的改进,以增强可读性并消除样板。 开始编写脚本 准备好开始使用 Painless 编写脚本了吗?让我开始编写我们的第一个脚本。 只要ElasticsearchAPI 支持脚本,语法就会遵循相同的模式;你可以指定...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- CentOS7安装Docker,走上虚拟化容器引擎之路
- CentOS7设置SWAP分区,小内存服务器的救世主
- CentOS8安装MyCat,轻松搞定数据库的读写分离、垂直分库、水平分库
- CentOS7编译安装Gcc9.2.0,解决mysql等软件编译问题
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- CentOS7,8上快速安装Gitea,搭建Git服务器
- CentOS7编译安装Cmake3.16.3,解决mysql等软件编译问题
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- SpringBoot2全家桶,快速入门学习开发网站教程
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装