Oracle事务的回滚,通过回滚段保存原有数据实现,但,PG没有回滚段!以下以Update操作为例,说明PG实现机制上存在的空间暴涨问题。
在执行Update时,Oracle就地更新,如出现原block空间不足的情况,通过link的方式链接至新block上(不精确,大体表述);PG的Update,不是原地更新,而是保留原有数据,通过新增新的tuple(数据行)保存新增数据,原有数据通过Vacuum机制清理。Vacuum机制需要满足MVCC(多版本并发控制)的要求,在某些情况下,不会清理“垃圾”数据,在事务繁忙的时候导致会导致数据表空间不断增长。
--------------------------- Session A
-- 开启事务
begin;
-- 查询当前事务
select txid_current();
txid_current
--------------
1500987
(1 row)
-- 什么都不做,会导致Vacuum不能清理“垃圾”数据
--------------------------- Session B
-- 开启事务
begin;
select txid_current();
txid_current
--------------
1500988
(1 row)
-- 创建表&插入100数据
drop table if exists t1;
create table t1(id int,c1 varchar(50));