compact和checkpoint、wal的区别

compact和checkpoint、wal的区别

机制 解决什么问题 一句话
WAL 写入性能 vs 数据安全 "先记日志,再写数据"
Checkpoint 恢复时间 vs 磁盘IO开销 "定期把日志对应的数据刷盘,标记恢复点"
Compact 存储空间膨胀 vs 读写性能 "合并整理,清理垃圾,压实数据"

详细对比
WAL(Write-Ahead Log)

用户写入 ──→ 内存(Buffer Pool)←── 快
     │
     └─→ 先写 WAL/Redo Log ──→ 磁盘 ←── 顺序IO,也快
              │
              ↓
         事务即可提交(即使数据还在内存!)
              │
              ↓
         后台异步刷脏页到数据文件
维度 说明
时机 每次事务提交/数据修改时同步
内容 记录"改了什么"(物理页变更或逻辑操作)
目的 宕机后能通过日志重做(Redo)恢复数据
代价 多一次顺序磁盘IO,但比随机IO快得多
关键参数 innodb_flush_log_at_trx_commit(MySQL)、fsync 策略

没有 WAL:每次写都要等数据页刷盘(随机IO),性能极差,且宕机丢失未刷盘数据。

Checkpoint

时间点 ─────────────────────────────────────→

T1: 事务A修改页P1 ──→ 写Redo Log(LSN=100)
T2: 事务B修改页P2 ──→ 写Redo Log(LSN=200)
T3: 事务C修改页P3 ──→ 写Redo Log(LSN=300)
       │
       │  Checkpoint 触发(比如每1GB日志、或每60秒)
       ↓
   ┌─────────────────────────┐
   │ 1. 把 LSN≤300 的脏页刷盘 │
   │ 2. 更新 Checkpoint LSN=300 │
   │ 3. LSN<<300 的日志可删除/复用 │
   └─────────────────────────┘
       │
T4: 宕机重启 ──→ 从 LSN=300 开始重放日志(不用从0开始)
维度 说明
时机 定时/定量触发(非每次事务)
内容 把内存脏页刷到数据文件,并记录恢复点
目的 缩短崩溃恢复时间,回收旧日志空间
代价 突发磁盘IO(刷脏页),可能阻塞短暂时间
关键参数 Checkpoint 频率、脏页比例阈值

没有 Checkpoint:崩溃后要从数据库创建之初的所有日志重放,恢复时间不可接受;日志文件无限增长。

Compact

LSM-Tree 场景(RocksDB/HBase):

L0: [SST_1(1MB)] [SST_2(1MB)] [SST_3(1MB)]  ← 刚刷盘,文件多,重叠多
        │
        │  Compact 触发
        ↓
L1: [SST_merged(2.5MB)]  ← 合并后文件少,无重叠,去掉了删除标记和旧版本

B+Tree 场景(InnoDB):

数据页: [记录1][记录2][删除标记][记录3][删除标记][删除标记][记录4]
        │
        │  Compact/Optimize
        ↓
数据页: [记录1][记录2][记录3][记录4]_______  ← 碎片整理,空闲空间紧凑
维度 说明
时机 后台异步触发(或手动执行)
内容 合并文件、清理删除标记/旧版本、整理碎片
目的 回收存储空间,减少读放大,提升查询性能
代价 大量磁盘IO和CPU(排序、解压、压缩),可能抢占前台资源
关键参数 Compact 线程数、触发阈值、Rate Limiter

没有 Compact:LSM-Tree 文件爆炸,读一个key要扫几十个文件;B+Tree 页内碎片严重,空间浪费。

三者协作关系(以 LSM-Tree 为例)

用户写入
    │
    ├─→ WAL(顺序写日志)←── 保证不丢数据
    │
    └─→ MemTable(内存)←── 快速响应
            │
            │  刷盘(MemTable → SSTable L0)
            ↓
        L0 SSTable 文件累积
            │
            │  Compact(L0→L1→L2...)
            ↓
        多层有序 SSTable(空间回收、读性能提升)
            │
            │  Checkpoint(标记元数据一致性点)
            ↓
        快照备份可用

一句话区分

场景 对应机制
"事务提交了,数据还没写进数据文件,断电了怎么办?" WAL(Redo Log 重放)
"重启要恢复多久?日志文件怎么越来越大?" Checkpoint(定期刷盘+标记恢复点)
"磁盘快满了,查询越来越慢,文件/页内碎片太多?" Compact(合并整理+清理垃圾)

常见误区

误区 纠正
"Checkpoint 就是刷脏页" Checkpoint 包含刷脏页,但核心是标记恢复点,让日志可回收
"Compact 和 Checkpoint 一样" Compact 是数据整理,Checkpoint 是恢复标记;Compact 不标记恢复点
"WAL 写了就不用 Checkpoint" WAL 只保证可恢复,Checkpoint 保证恢复快;两者缺一不可
"B+Tree 不需要 Compact" B+Tree 也有碎片整理(MySQL OPTIMIZE TABLE、PostgreSQL VACUUM),只是不叫 Compact
posted @ 2026-05-22 10:00  小海哥哥de  阅读(5)  评论(0)    收藏  举报