OceanBase 为什么"写这么快,读也不慢"?聊聊 LSM-Tree 与每日合并

传统 MySQL InnoDB 用 B+Tree,随机写会有明显写放大。OceanBase 的存储引擎走的是 LSM-Tree(日志结构合并树) 路线,核心就三步:

  • 写路径:先写预写日志 Clog(保持久化),再写内存 MemTable,内存写满就**转储(Minor Freeze)**成 SSTable 顺序落盘——全是顺序写,所以写入吞吐高。
  • 读路径:先查 MemTable,再逐层查增量/基线 SSTable,靠 Block Cache / Row Cache / Bloom Filter 做加速,避免每次都去磁盘多路归并。
  • 每日合并(Major Compaction):转储攒多了读会变慢,OceanBase 会在业务低峰(一般凌晨)把基线 SSTable + 增量转储数据合并成新基线,顺手回收空间、清理过期版本,读性能回血。

简单对比:LSM-Tree 用"写放大换读放大"的思路,把随机写转成顺序写;InnoDB 则是点查快、随机写压力大。

抛个问题引互动:从 InnoDB 迁移到 OB 的同学,最不习惯的点是啥?转储/合并的时机你们是自动还是手动控?

8 个赞

66

2 个赞

分析到位

2 个赞

传统 B+Tree(如 InnoDB)的写入痛点:
叶子节点在磁盘上分散,插入/更新往往要"先把页读进内存 → 改 → 写回",是随机 I/O;
页分裂、页合并还会产生额外写;
为保证持久化与崩溃一致性,还要写 redo log,外加 double write buffer 防 partial write;
叠加起来就是典型的"写放大 + 随机写压力"。
OceanBase 的 LSM-Tree 写入路径:
写 Clog(Commit Log / 预写日志):这是 WAL,顺序追加写,只负责"事务持久化"这一件事,不组织成树;
写 MemTable:内存中的有序结构(通常是跳跃表 SkipList),写内存几乎是 O(log n),没有磁盘随机 I/O;
1MemTable 写满触发转储(Minor Freeze)*:把内存 MemTable 顺序 dump 成增量 SSTable 落盘。

1 个赞

读需要合并数据

1 个赞

说到点子上了

对的呢