IT技术博客大学习 共学习 共进步
全部 移动开发 后端 数据库 AI 算法 安全 DevOps 前端 设计 开发者

注意:StarRocks 3.5.x 滚动升级触发 MV 全量刷新问题

crossoverJie's Blog 2026-07-24 12:40:41 累计浏览 15 次
本机暂存

背景

我们的 StarRocks 集群一直跑在 3.5 分支上,最近发现 PR #57371 只 backport 到了 3.4,3.5 没收到,导致 MV 从 inactive 切到 active 的时候走的是 force=true,也就是全量刷新。

于是我手动把这个修复 cherry-pick 到了我们的 3.5 分支,改掉 force=true 的问题之后发了版。发版本身没问题,但发版触发了 FE 滚动重启,重启过程中集群突然被打满——所有分区的物化视图都在对全历史分区做全量刷新。

排查之后发现是三个因素凑到一起:3.5.15 引入的异步 MV reload + 未修复的 force=true 激活路径 + 滚动重启时的 Leader 切换。

时间线

  • 16:01 - 17:01:FE-2 上的周期刷新一直是 forceRefresh=false,只刷当天分区。
  • 17:01 后:FE-2 停止刷新,开始进入滚动重启窗口。
  • 17:07:59:FE-1 上的 MVActiveChecker 触发 ALTER MATERIALIZED VIEW ... ACTIVE,随后进入 refreshMaterializedView(..., FORCE=true, ...)
  • 17:09 - 17:15:FE-1 持续把 forceRefresh=true 传播到后续 batch task,开始刷历史分区。

问题在哪

异步 MV reload(3.5.15 引入)

FE 重启加载 checkpoint 镜像时,MaterializedView.onReload() 先把所有 MV 设为 active = false,然后提交异步任务去检查基表可用性,检查通过再恢复 active。这个异步检查可能耗时几分钟,这期间 MV 都处于 inactive 状态。

MVActiveChecker 补刀

MVActiveChecker 是一个后台守护线程,默认每 60 秒扫一次,看到 inactive 的 MV 就自动执行 ALTER MATERIALIZED VIEW xxx ACTIVE。重启后 grace-period map 是空的,没有任何退避,扫到就激活。

force=true(3.5 分支的老代码)

ALTER MATERIALIZED VIEW xxx ACTIVE 的代码里,激活后会调用 refreshMaterializedView(..., force=true, ...)。3.5 分支切出来的时候,社区刚好有一个把 force 改为 false 的 PR 合入了 main 分支,但 3.5 没收到 backport。

最近社区也发现了这个问题,有客户现场出现了 MV 全量刷新导致数据同步出现延迟,然后才 backport 到 3.5.21 这个版本上。

PR #76576 的说明里写得很清楚:

since 3.5.15 the async MV reload on FE restart makes this a serious regression: during image load onReload() sets active = false first and restores it asynchronously, leaving a minutes-long window in which MVs are transiently inactive. MVActiveChecker picks them up and runs ALTER MATERIALIZED VIEW xxx ACTIVE, and the activation path calls refreshMaterializedView(…, force=true, …) — so every FE leader restart triggers a FORCE full refresh of all async MVs.

所以触发链路是:

FE 重启 → async reload 设 active=false → MVActiveChecker 激活 
→ refreshMaterializedView(force=true) → 全量刷新

滚动重启放大

我们的 K8s 集群有 3 个 FE Pod,滚动更新逐个重启。每次当前 Leader 被重启,就会触发 failover,新 Leader 的 MVActiveChecker 再扫一遍所有 inactive 的 MV,又来一波全量刷新。也就是说,只要某一轮切换后的 Leader 还没拿到修复版代码,就可能再刷一波;实际波次数取决于 leader 切换路径和滚动顺序。

日志证据

日志里能看到 FE-2 先一直正常周期刷新,forceRefresh=false

2026-07-23 16:01:09  FE-2  forceRefresh=false
2026-07-23 16:16:11  FE-2  forceRefresh=false
2026-07-23 17:01:09  FE-2  forceRefresh=false

随后 FE-1 在 17:07:59 接管并触发自动激活:

2026-07-23 17:07:59  MVActiveChecker Start to activate MV dws_trd_period_sales_offline_store
2026-07-23 17:07:59  LocalMetastore.executeRefreshMvTask() FORCE=true
2026-07-23 17:09:24  FE-1  forceRefresh=true
2026-07-23 17:15:54  FE-1  forceRefresh=true

这说明滚动重启窗口内,Leader 已经切到了 FE-1,且当时 FE-1 仍在执行未修复的激活逻辑。

代码位置

  • fe/fe-core/src/main/java/com/starrocks/scheduler/MVActiveChecker.java
  • fe/fe-core/src/main/java/com/starrocks/alter/AlterMVJobExecutor.java
  • fe/fe-core/src/main/java/com/starrocks/server/LocalMetastore.java
  • fe/fe-core/src/main/java/com/starrocks/scheduler/PartitionBasedMvRefreshProcessor.java

实际影响

我们集群里 MV 会做全历史分区全量刷新,CN 节点 CPU 打满,数据延迟数小时。

怎么规避

3.5.21 已经合了上面的 bugfix,force=true 改成了 force=false。但如果你在升级 3.5.21 或升级 还需要做 FE 重启,保险起见可以先关掉 MVActiveChecker

ADMIN SET FRONTEND CONFIG ("enable_mv_automatic_active_check" = "false");

确认生效:

ADMIN SHOW FRONTEND CONFIG LIKE "%enable_mv_automatic_active_check%";

滚动重启全部完成后,确认集群稳定(Leader 不再切换、没有历史分区的刷新任务在跑),再打开:

ADMIN SET FRONTEND CONFIG ("enable_mv_automatic_active_check" = "true");

关闭期间不影响定时刷新和手动刷新,只影响”从 inactive 自动恢复 active”这一种场景,业务无感。

总结

这个问题本质上是三个因素碰到了一起:异步 reload 制造了 inactive 窗口、MVActiveChecker 在这个窗口里激活了 MV、激活路径又走的是 force=true。3.5.21 修了 force=true,但如果之后 FE 重启时异步 reload 还没完成,MVActiveChecker 仍可能先动手;只是刷新会变成增量,不再是全量。

所以升级前后的保险操作是:先关掉自动激活,等全部 FE 滚动完成且 Leader 稳定后,再重新打开。

参考链接:

额外再补充一下,现在 DS 感觉降智有点严重,整个问题的分析过程我分别交给了 DS v4 Pro 和 kimi2.7

kimi2.7 很快就定位到是滚动更新导致 leader 切换出现的问题,希望 DS 最近要发布的正式版

同分类推荐文章

  1. 快速处理 ORA-01210: data file header is media corrupt 故障 (2026-07-24 07:38:56)
  2. 记录block 0损坏,数据文件大量坏块,使用不当数据库版本恢复等各种操作之后的故障处理 (2026-07-03 21:47:20)
  3. 需要注意:dbv 检测controlfile可能不准 (2026-07-03 18:25:57)

查看更多 数据库 文章 →

建议继续学习

  1. Java应用运维 (累计阅读 5,520)
  2. strace命令用法详解 (累计阅读 4,319)
  3. 使用strace工具故障排查的5种简单方法 (累计阅读 3,931)
  4. 实时计算引擎处理延迟的排查过程 (累计阅读 2,261)
  5. RDS典型客户工单——空间问题 (累计阅读 2,130)
  6. 我做了一个 AI 版的 StarRocks 升级风险扫描工具,直接帮我定位到一个风险 (累计阅读 255)
  7. 我的 Claude Code 常用 SKILLS 和工具 (累计阅读 158)
  8. 如何在本地打包 StarRocks 发行版 (累计阅读 122)
  9. 使用deepseek进行Oracle恢复,引起重大故障 (累计阅读 127)
  10. Linux 桌面系统故障排查指南(六) - 系统关机与电源管理 (累计阅读 112)