StarRocks 升级注意事项

devtools/2025/3/22 15:22:39/

前段时间升级了生产环境的 StarRocks,从 3.3.3 升级到了 3.3.9,期间还是踩了不少坑所以在这里记录下。

因为我们的集群使用的是存算分离的版本,也是使用官方提供的 operator 部署在 kubernetes 里的,所以没法按照官方的流程进入虚拟机手动启停对应的服务。

只能使用 operator 提供的方案手动修改对应组件的镜像版本,后续的升级操作交给 operator 去完成。

理论上这个升级流程没什么问题,修改镜像版本之后只需要安静等待他滚动更新即可。

元数据备份与恢复

但考虑到之前在社区看到有存算分离集群升级失败导致数据丢失的案例,我们的全量业务已经切换到 StarRocks,如果数据丢失那需要花几天时间进行数据同步,这在业务上是无法接受的,所以我们最好是可以在升级前备份数据,即便是升级失败数据依然还在。

原本官方社区是有提供数据备份与恢复能力的,但是我们使用的存算分离集群不支持😂,而想要获得社区版的支持应该还要等一段时间,即便是支持了我们升级到那个版本依然是需要备份的。

好消息,在最新的 3.4.1 版本中已经支持了快照备份了,只是作为一个新 feature,稳定性还有待观察。

所以我们的计划是在当前这个版本(3.3.3)能否自己备份数据,由于我们是存算分离的版本,所以数据主要分为两部分:

  • 存储在所有 FE 节点里的 meta 元数据

  • 存储在云存储里的业务数据

备份的时候自然就需要备份这两部分的数据。

备份元数据

在元数据里存放了所有的数据库、表、视图等信息,具体在磁盘的结构如下:

|-- bdb
|   |-- 00000000.jdb
|   |-- je.config.csv
|   |-- je.info.0
|   |-- je.info.0.lck
|   |-- je.lck
|   `-- je.stat.csv
|-- image
|   |-- ROLE
|   |-- VERSION
|   |-- image.327375
|   |-- starmgr
|   |   `-- image.390
|   `-- v2
|       |-- checksum.327375
|       `-- image.327375

bdb 目录主要是用于 leader 选举的,理论上并不需要备份,真正需要的是 image 目录下的 image.327375 等元数据文件。

里面是用 JSON 存储的各种类型的元数据,FE 在启动的时候会读取该文件,然后根据不同的类型取不同的偏移量读取其中的元数据加载到内存里。

我们的 FE 一共有三个节点,需要找到其中的 leader 节点(理论上只需要备份 leader 节点即可,其他节点会在 leader 启动后同步过去),直接将这个 meta 目录备份到本地即可:

在开始之前需要停掉所有的写入任务,暂停所有的物化视图刷新。

# inactive 所有的物化视图
SELECT CONCAT('ALTER MATERIALIZED VIEW ', TABLE_NAME, ' INACTIVE;') FROM information_schema.materialized_views;# 手动创建镜像
ALTER SYSTEM CREATE IMAGE;# 找到 leader 节点
SHOW FRONTENDS;

然后进入 leader 节点备份元数据:

k exec -it kube-starrocks-fe-0-n sr -- bashtar -zcvf meta.tar.gz meta/# 下载备份元数据到本地
k cp starrocks-fe-0:/opt/starrocks/fe/meta/image.tar.gz image.tar.gz -n starrocks -c fe --retries=5

备份云存储数据

云存储的备份就需要结合你使用的云厂商来备份了,通常他们都有提供对应的备份能力。

要注意的是我们再备份的时候需要记录在存储桶里的目录名称,之后还原的时候名称得保持一致才行。

恢复元数据

当出现极端情况升级失败的时候,我们需要把元数据覆盖回去;但由于我们的应用运行在容器里,不可以在应用启动之后再替换元数据。

只能在应用启动之前将之前备份的元数据覆盖回去,这里可以使用 kubernetes 中的 initContainers 提前将数据复制到应用容器里。

在开始之前我们需要先把备份的元数据打包为一个镜像。

FROM busybox  
ADD meta.tar.gz /temp

然后我们需要手动修改 FE 的 statefulset 的资源,创建一个 initContainers。

initContainers:  
-name:copy-file-initimage:meta:0.0.1command:["/bin/sh","-c"]args:["rm-rf/meta-target/*&&cp-r/temp/meta/./meta-target"]volumeMounts:-name:fe-metamountPath:"/meta-target"

原理就是在 initContainers 中挂载原本 FE 的元数据目录,这样就可以直接将之前备份的元数据覆盖过去。

当然也可以直接使用 k8s 的 go client 用代码的方式来修改,会更容易维护。

还原的时候需要先将云存储里的数据先还原之后再还原元数据。

物化视图刷新策略

真正升级的时候倒是没有碰到升级失败的情况,所以没有走恢复流程;但是却碰到了一个更麻烦的事情。

物化视图作为基表

我们在升级前将所有的物化视图设置为了 INACTIVE,升级成功后需要将他们都改为 ACTIVE

第一个问题是如果某个物化视图 MV1 的基表也是一个物化视图 MV-base,这样会导致 MV1 的全量刷新。

我之前在这个 PR 里新增了一个参数:excluded_refresh_tables 可以用于排除基表发生变化的时候刷新物化视图,但是忘记了基表也是物化视图的场景。

所以在这个 PR 中修复了该问题,现在基表是物化视图的时候也可以使用了。

物化视图手动 ACTIVE

前面提到在升级之前需要将所有的物化视图设置为 INACTIVE,升级成功后再手动设置为 ACTIVE。

我们在手动 ACTIVE 之后发现这些物化视图又在做全量刷新了,于是我们检查了代码。

发现在使用 ALTER MATERIALIZED VIEW order_mv ACTIVE; 修改视图状态的时候会强制刷新物化视图的所有分区。

force: true 的时候会直接跳过基表的分区检查,导致分区的全量刷新。

同时会在 ACTIVE 的时候将视图基表的 baseTableVisibleVersionMap 版本号缓存清空,FE 需要在刷新的时候判断当前需要刷新的分区是否存在与缓存中,如果存在的话说明不需要刷新,现在被清空后就一定会被刷新。

所以我提了一个 PR 可以在 ACTIVE 物化视图的时候人工判断是否需要刷新:

alter materialized view mv_test1 ACTIVE WITH NO_VALIDATION

这样带上 NO_VALIDATION 参数后就 force=false 也就不会全量刷新了。

如果在 ACTIVE 物化视图的时候碰到类似场景,可以在这个 PR 发布之后加上 NO_VALIDATION 来跳过刷新。

参考链接:

  • https://github.com/StarRocks/starrocks/pull/50926

  • https://github.com/StarRocks/starrocks/pull/56428

  • https://github.com/StarRocks/starrocks/pull/56864

往期推荐

虽迟但到的 2024 总结

StarRocks 开发环境搭建踩坑指北之存算分离篇

k8s 云原生应用如何接入监控.md

深入解析 Istioctl:如何正确更新 Istio 配置?

点分享

点收藏

点点赞

点在看


http://www.ppmy.cn/devtools/169178.html

相关文章

人工智能之数学基础:高斯消元法求解线性方程组

本文重点 前面我们已经学习过了矩阵,以及矩阵的一系列含义,相信此时此刻在你的眼中矩阵已经不是一个简单的东西了,它是线性代数中的函数。将线性方程组中的系数组成一个矩阵,就可以通过这个矩阵来求解方程组的解了,本文介绍高斯消元法求解线性方程组。 线性方程组的矩阵…

ES、Kibana一键式部署脚本执行文件,外加IK分词器和拼音分词器

#!/bin/bash# 设置变量 ES_VERSION"7.12.1" KIBANA_VERSION"7.12.1" ES_CONTAINER"es" KIBANA_CONTAINER"kibana" NETWORK_NAME"es-net" ES_DATA_VOLUME"es-data" ES_PLUGINS_VOLUME"es-plugins" ES_PO…

HTML5拖拽功能教程

HTML5拖拽功能教程 简介 HTML5引入了原生拖放(Drag and Drop)API,使开发者能够轻松实现网页中的拖拽功能,无需依赖第三方库。拖拽功能可以大大提升用户体验,适用于文件上传、列表排序、看板系统等多种交互场景。本教程将带您全面了解HTML拖…

数据类设计_图片类设计之7_矩阵图形类设计更新_实战之页面简单设计(前端架构)

前言 学的东西多了,要想办法用出来.C和C是偏向底层的语言,直接与数据打交道.尝试做一些和数据方面相关的内容 引入 前面讲过的混合类型设计,实际上是矩阵类图形设计(名称已更新).他能够产生的视觉效果是这样的: 注意:外层的矩形边框可以不存在,只是说明了图形存在于一个矩形区…

Java 第十一章 GUI编程(3)

目录 内部类 内部类定义 内部类的特点 匿名内部类 格式: 内部类的意义 实例 内部类 ● 把类定义在另一个类的内部,该类就被称为内部类。 ● 如果在类 Outer 的内部再定义一个类 Inner,此时类 Inner 就称为内部类 (或称为嵌…

简化神经元模型7 -- GIF Model

Hindmarsh-Rose 模型 目录 0. 写在前面 1. GIF 模型的定义 2. GIF 模型的动力学分析 2.1. 角度一:GIF 模型的变量较多 2.2. 角度二:GIF 模型的更新规则较为复杂多 4. 分析过程所用到的一系列 BrainPy 代码 0. 写在前面 前面介绍了: Hodgkin-…

【最后203篇系列】021 Q201再计划

忙了一周,终于到周末有时间再细细想这个问题了。这周还是不经意的弥补了kv硬盘存储库这个小空白的,这样也有助于构建更好的Q201。 计划是到6.1再发版,之所以留那么长时间,一方面是因为平时的确忙,另一方面则是可以有更…

【C++进阶】try块和异常处理

目录 一、异常处理概述 1.1 什么是异常 1.2 为什么需要异常处理 1.3 异常处理基本框架 二、异常处理核心机制 2.1 基本语法要素 2.2 异常传播机制 2.3 异常安全保证 三、try 块和 catch 块的使用 3.1 简单的 try-catch 示例 3.2 多个 catch 块的使用 3.3 catch 块的…