一、行结构简述
1、行头信息简述
xmin:保存 插入(insert)此元组的事务的txid,即这一行是被哪一个事务插入的,它的状态是行可见性判断的关键依据,例如:当这个值=ABORTED时,判断此行为不可见;
xmax:保存 删除(delete)或更新(update)此元组的事务的txid。如果此元组未被删除或更新,则t_xmax设置为0,这意味着无效, 它的状态是行可见性判断的关键依据;
t_ctid:指针,指向行的位置。
2、块中的行结构
在PG中,假如数据被删除,会修改行头和块头信息,但数据本身被保留,空间不会立刻释放。
3、扩展工具Pageinspect
Postgresql提供了一个扩展 pageinspect,它是一个贡献模块,用来显示数据块页面的内容;
该 pageinspect模块提供的功能允许我们从底层检査数据块页面的内容,这对于调试非常有用;
所有这些功能只能由超级用户使用;
如果表里原来有行,可以查询每个行之前操作时保留下来的信息;
使用方法:
//在想要查询的表所在的DB下执行以下命令:
CREATE EXTENSION pageinspect;
SELECT Ip as tuple,t_xmin,t_xmax,t_field3 as t_cid,t_ctid FROM heap_page_items(get_raw_page('tbl', 0));
二、DML操作过程
1、insert
t_xmin=99:由txid99插入;
t_xmax=0:此元组尚未更新或删除;
t_cid=0:此元组是txid99插入的第一个元组;
t_ctid=(0,1):指向自身,因为这是最新的元组,事务插入的第一行,未被修改过。
2、delete
t_xmin=100:由txid100插入;
t_xmax=111:由txid111删除;
t_cid=0:此元组是txid99插入的第一个元组;
t_ctid=(0,1):指向自身,因为这是最新的元组,事务插入的第一行,未被修改过;
user data=’DELETE’:数据被标记为删除,但实际上物理的行依然存在,成为死元组,等vacuum操作释放此空间(此操作将在十六章中详细描述)。
3、update
PG的update命令与oreacle在原行上直接修改不同,而是会被拆分成DELETE+INSERT两个命令,与mysql中innodb的原理较像。
执行第一个UPDATE命令时,通过将txid100设置为 t_xmax,逻辑上删除Tuple_1,再插入Tupe_2;然后,将元组1的 t_ctid重写为指向元组2。
当执行第二个 UPDATE命令时,与第一个 UPDATE命令一样, Tuple_2在逻辑上被删除, Tuple_3被插入。