您现在的位置是:
网站首页
> 程序设计 
> PostgreSQL 
PostgreSQL内核原理之vacuum之死元组产生
简介我们知道,MVCC是数据库实现并发一致性的重要手段,但是各个数据库在实现MVCC的时候不尽相同,主要差异在于版本链的管理。以Oracle为例的undo派把历史版本单独放在undo段中,数据页上只存放最新版本,相当于是新老数据分开存储,线程回收历史版本时不会对业务产出影响;而以Postgres为例的append派把历史版本和最新版都存放在数据页上,回收老版本需要遍历所有数据页,会产生较高的IO开销
1. DELETE产生的死元组
如图所示,页面上有3条元组,当执行delete from t1 where ctid='(0, 2)'删除第二条元时,delete操作只是给 Tuple上打一个删除标记,行指针和Tuple本身不会做任何修改,此时Tuple2会一直残留在页面上。
2. UPDATE跨页产生的死元组
前面提到,Postgres是append更新,因此当我们执行update后老元组就会变成死元组,如图所示,当执行update t1 set a=a+1 where ctid='(0, 1)'来更新Tuple1时,新元组Tuple1'被写到了其他页面,这是Tuple1就是页面上的死元组。
3. HOT UPDATE产生的死元组
Postgres中为了提升性能,当满足条件时可以执行HOT UPDATE,如图所示,将Tuple1更新成Tuple4,此时Tuple1成了死元组,但是要注意的是在清理的时候LP1并不能清除,这个下面会说到。
如图所示,当我们使用HOT UPDATE更新Tuple1时,假如更新后的元组是Tuple4,则Tuple1上的ctid字段会指向LP4,此时的Tuple1也可以认为是死元组,当执行vacuum时能够被清掉,但是LP1仍保留。