物化视图的快速刷新(FAST REFRESH)依赖一张”变更日志表”——MLog(materialized view log)。基表每发生一次 DML,MLog 就追加一行带旧值/新值的变更记录。只写不删,这张表迟早会吃掉整个租户的存储空间,所以必须有人负责回收。OceanBase 4.3 里承担这个职责的是 storage/mview/ob_mlog_purge.cpp 中的 ObMLogPurger。这篇文章拆解它的三段式流程,以及最核心的那个问题:一次到底能删到哪个位点。
OceanBase源码解读:物化视图刷新统计清理任务
物化视图(Materialized View)每次刷新都会在系统表 __all_mview_refresh_stats 里记录一条刷新统计:刷新耗时、刷新 SCN、成功与否等。这些统计是运维观测的重要依据,但如果只写不删,长期运行下来这张表会无限膨胀。OceanBase 4.3 为此引入了一个专门的后台任务——ObMViewRefreshStatsMaintenanceTask,它按用户为每个物化视图设置的保留期(retention_period),周期性地清理过期的刷新统计记录。本文解读它的实现文件 rootserver/mview/ob_mview_refresh_stats_maintenance_task.cpp,重点看两个设计亮点:一是”单拍自续”的定时器调度模式,二是游标驱动的分批限流清理。
OceanBase源码解读:物化视图快照推进任务 ob_mview_push_snapshot_task
在 OceanBase 4.3 的物化视图(MV)体系里,”大版本刷新”(major refresh mv)是一种重量级操作:它不是在事务里实时计算刷新,而是依赖存储层的多版本快照,把刷新推迟到一次 Major Compaction 中批量完成。这就带来一个关键问题——刷新期间所依赖的最低快照版本(min_refresh_scn)必须被系统”保住”,否则事务的多版本数据一旦被回收,刷新就会读到不完整的数据。本文要解读的 ob_mview_push_snapshot_task.cpp(209 行)正是解决这个问题的组件:一个由 RootService 定时驱动的”快照推进任务” ObMViewPushSnapshotTask,它周期性地把所有大版本刷新物化视图所需的最小快照 SCN 推送到快照表,为刷新链路兜底。
OceanBase源码解读:物化视图刷新信息缓存任务 ob_mview_update_cache_task
在 OceanBase 4.3 的物化视图(Materialized View)体系里,有一类 MV 的刷新节奏被绑定在基表的合并/冻结节拍上,也就是 REFRESH_MODE = MAJOR_COMPACTION。合并线程推进 major freeze 时,必须反复回答一个问题:这些 MV 里的数据是否已经刷到当前版本?这个判定处在极热路径上,如果每次都去扫一遍元数据表 __all_mview,代价完全不可接受。于是就有了本文要解读的 ob_mview_update_cache_task.cpp——一个专职”抄表”的后台任务:它每 5 秒把 __all_mview 里每个 MV 的 LAST_REFRESH_SCN 抄进内存哈希表,让热路径只查内存。整个文件不到 200 行,却是理解 OceanBase「持久化元数据 + 内存旁路缓存」这套读写分离设计的好样本。
OceanBase源码解读:MV依赖更新任务 ob_mview_update_deps_task
物化视图支持嵌套构建——一个 MV 可以基于另一个 MV 建立,这样就形成了一张”依赖图”。当依赖链上的基表或其他 MV 发生 DDL 变更后,这张依赖图可能过期,如果不及时重建,刷新调度就会拿到错误的依赖关系。本文解读的 ob_mview_update_deps_task.cpp(全文 136 行)就是负责这件事的后台定时任务:ObMViewUpdateDepsTask。它跑在 RootService(RS)侧,周期性探测当前租户是否存在嵌套 MV 依赖,一旦发现就触发整张依赖图的全量重建。代码虽短,却是物化视图元数据一致性的重要守护者。
OceanBase源码解读:物化视图 MDS 操作记录同步任务
在 OceanBase 4.x 的物化视图(Materialized View)体系里,有一个不起眼但很关键的定时任务:ObMViewMdsOpTask。它的职责是周期性扫描系统日志流(SYS_LS)上的事务上下文,把仍活跃事务携带的 mview 相关 MDS(Multi-Data Source,表级事务性元数据管理框架)操作收集到内存 Map 中,同时清理那些对应事务已经消失、且记录本身已过期的条目。简单说,它是”刷新任务读取 mds 记录”与”事务真实状态”之间的同步桥梁——没有它,刷新任务可能拿到早已回滚事务的脏数据,内存 Map 也会随时间无限膨胀。
OceanBase源码解读:MV快照清洁任务 ob_mview_clean_snapshot_task
物化视图(MV)的 major 刷新依赖”基表快照”来保证一致性取数,这些快照记录落在内部表 __all_acquired_snapshot 中。但有四类场景会让快照变成”孤儿”:MV 被删除、MV 创建中途失败、同一基表被多个 MV 引用产生冗余记录、基表的所有 MV 都删光。这篇我们解读负责定期打扫这些孤儿快照的后台任务——ObMViewCleanSnapshotTask(源码位于 rootserver/mview 目录,约 250 行),它是 rootserver 下 MV 定时任务家族的一员,继承自共享定时器外壳 ObMViewTimerTask。
OceanBase源码解读:物化视图定时任务 ob_mview_timer_task
物化视图的”major 合并刷新”是 OceanBase 4.3.4 引入的新刷新模式:不再逐条回放增量日志,而是直接把物化视图随租户的合并(major compaction)一起物化到基线数据里。这套机制要运转起来,必须有一个站在 RootService 侧、周期性观察”租户合并进度”并决定”要不要把新合并版本推给物化视图”的调度器——这就是 ob_mview_timer_task.cpp 里 ObMViewTimerTask 的职责。整个文件不到 200 行,却把”定时器外壳 + 调度判定 + 一致性自检”三件事讲得非常清楚,是理解 MV 与合并联动机制的最佳入口。
OceanBase源码解读:MLog维护任务 ob_mlog_maintenance_task
物化视图能加速复杂查询,靠的是一张”记账本”——物化视图日志(MLog,Materialized View Log)。基表每次 DML 都会把变更记录追加到 MLog 里,刷新时据此增量更新物化视图。但记账本本身也需要人管:用户把基表或物化视图删掉之后,遗留的 MLog 元数据和它挂载的 purge 定时任务如果没人清理,就会在系统表里越积越多。本文要解读的 ob_mlog_maintenance_task.cpp(约 340 行,位于 rootserver/mview 模块)就是干这件事的”MLog 垃圾回收员”——它周期性扫描全租户的 MLog 元数据,发现 schema 里已经查不到对应对象时,就把 MLog 干净利落地回收掉。
OceanBase源码解读:全文检索词项结构 ob_fts_struct
前面几篇我们把 OceanBase 4.3 全文检索(FTS)的分词器家族走了一遍——IK、N-gram、空白、英文基础分词器,最后到内置解析器的插件注册。文档被分词器切分之后,产出的一个个”词”在内存里用什么结构承载?答案就是本篇的主角 ObFTWord,它的实现落在 src/storage/fts/ob_fts_struct.cpp。这个文件全文只有 52 行,是 FTS 分支里最小的一个实现文件,却是整个倒排索引数据通路的地基:无论倒排字典、构建期的临时哈希表还是词项缓存,键的类型都是它。