重庆思庄Oracle、KingBase、PostgreSQL、Redhat认证学习论坛

标题: tidb的mvcc为什么不象POSTGRESQL 的mvcc表膨胀现象那么严重 [打印本页]

作者: 郑全    时间: 2025-12-13 14:33
标题: tidb的mvcc为什么不象POSTGRESQL 的mvcc表膨胀现象那么严重
TiDB 的 MVCC 机制在数据存储和垃圾回收(GC)设计上,与 PostgreSQL 的 MVCC 有显著差异,这直接导致了 TiDB 的表膨胀现象远没有 PostgreSQL 严重。核心原因在于 存储架构垃圾回收机制 的根本不同。


核心差异对比特性TiDB (基于 TiKV)PostgreSQL
MVCC 版本存储方式
追加写入,多版本独立存储原地更新,版本与主数据混合存储
数据组织基于 LSM-Tree 的 KV 存储 (RocksDB)。更新/删除操作会写入新的 KV 记录(带新时间戳),旧版本作为独立的 KV 记录保留。
基于堆表(Heap)。UPDATE 操作实际上是插入新版本元组,并将旧版本标记为“死元组”。所有版本都存储在同一张表的堆文件中。
垃圾回收 (GC) 机制主动、全局、异步的 GC 线程。定期(默认10分钟)根据全局 safe point 删除所有早于该时间点的旧版本数据。GC 是集中式、后台自动运行的任务。VACUUM。可以是手动的 (VACUUM) 或自动的 (autovacuum)。它标记“死元组”空间为可重用,但不会立即将空间返还给操作系统。除非执行 VACUUM FULL(锁表并重建),否则物理空间不会释放。
存储空间回收GC 会物理删除旧版本 KV 记录,并通过 RocksDB 的 Compaction 过程最终回收磁盘空间。VACUUM 通常只进行逻辑标记,物理空间留在表中等待复用。长期积累导致表文件膨胀。
事务ID耗尽问题使用全局单调递增的时间戳(TSO),64位,几乎无耗尽风险。使用32位事务ID (XID),可能环绕(wraparound),需要频繁的 VACUUM 来防止冻结,加剧膨胀压力。
写放大与压缩LSM-Tree 有固有的写放大,但通过后台 Compaction 合并和清理数据,能有效回收空间。堆表更新产生死元组,如果 VACUUM 跟不上写入速度,死元组会持续积累。为什么 TiDB 的表膨胀不那么严重?简单比喻总结TiDB 表膨胀现象远轻于 PostgreSQL,主要得益于其 为分布式设计的、基于 LSM-Tree 的存储引擎主动、全局、异步的垃圾回收机制。这套机制能够更积极、更可预测地清理不再需要的多版本数据,并从物理上回收磁盘空间。而 PostgreSQL 经典的堆表 MVCC 设计,加上惰性的 VACUUM 机制,使其在面临高并发更新时,更容易积累死元组,导致表空间膨胀,需要更精细的运维调优。






欢迎光临 重庆思庄Oracle、KingBase、PostgreSQL、Redhat认证学习论坛 (http://bbs.cqsztech.com/) Powered by Discuz! X3.2