4. 修改了数据,为什么‘看不见’?

2022-02-26 15:21:24 浏览数 (1)

上一篇中描述了存储页面的格式和回滚机制,也了解了删除数据并不会马上释放空间,但是你可能还是有疑问,有没有办法‘看到’事务修改过程呢,下面我们一起来‘看看’数据更新时元数据的变化。

在开始演示之前,我们先引入pg_attribute表(The catalog pg_attribute stores information about table columns. There will be exactly one pg_attribute row for every column in every table in the database.)

从官方文档看出,attname对应列名,attnum和attname对应,代表该列在postgresql表中列序号,其中系统列的序号是负数。

看一个实际的例子,还是用t_mvcc表举例:

postgres=> select attrelid,attname,attnum from pg_attribute where attrelid='public.t_mvcc'::regclass;

接下来看一个实际更新的例子:

T

A Session

B Session

T1

begin;--查看XID select txid_current(); txid_current-------------- 12548select cmax,xmax,cmin,xmin,ctid,id,val from t_mvcc where id=20000003;

--查看XID select txid_current(); txid_current-------------- 12549--select txid_current_snapshot();

T2

--更新数据 update t_mvcc set val='11923:12548:11923,11928,11932,11939-update' where id=20000003;

--查询ID=20000003的数据select cmax,xmax,cmin,xmin,ctid,id,val from t_mvcc where id=20000003;

T3

--提交事务 commit;

--查询ID=20000003的数据select cmax,xmax,cmin,xmin,ctid,id,val from t_mvcc where id=20000003; --select txid_current_snapshot();

  1. T1时刻A Session XID=12548,B Session XID=12549,由于A先开启事务且未提交/回滚,所以A Session对B Session来说是活跃事务。
  2. T2时刻A Session执行update SQL,它把对应版本XMIN标记为自己XID=12548,而自己‘看到’的内容是更新后的内容。此时B Session查询数据ID=20000003的记录时,看出xmax=12548是A Session XID且未提交,所以查出来的记录是更新前的值。
  3. T3时刻A Session提交事务,B Session再次执行查询数据ID=20000003的记录,通过查询活跃事务列表看出,A Session XID已经不再事务快照中,所以B Session能够看到A Session更新的记录。

0 人点赞