Postgresql页面xmax与multixact

2022-05-12 11:08:38 浏览数 (2)

结论1:

  1. xmax和Infomask匹配使用,可能保存修改者的xid,也可能保存读或写行锁的xid。
  2. 如果保存读写行锁的xid,只要加过行锁,就算释放了xmax也会一直记录xid。
  3. 如果保存读行锁的xid,如果有多个事务加行锁,xmax会保存multixact数组的位置,具体信息存在multixact结构中(SLRU页面同CLOG)。

结论2:

注意到PG使用xmax记录行锁的事务ID,那么判断行锁还有没有就依赖xid的状态了,也就是CLOG。

在vacuum freeze的时候如果看到xmax上记录的事务ID过旧,也需要freeze的:

  • vacuum_multixact_freeze_min_age 同 autovacuum_freeze_max_age : 五千万开始正常vacuum freeze,用最新xid-五千万=Limit,扫描页面如果有脏数据顺便freeze。
  • autovacuum_multixact_freeze_max_age 同 autovacuum_multixact_freeze_max_age : 两亿开始eager freeze取oldxmin为Limit,用Limit来freeze所有页面。

正常保存

代码语言:javascript复制
create table m7(id int primary key, info text);
insert into m7 select generate_series(1,10), md5(random()::text);
select lp,lp_off,lp_flags,lp_len,t_xmin,t_xmax,t_field3,t_ctid,t_infomask2,t_infomask,t_hoff,t_bits,t_oid from heap_page_items(get_raw_page('m7',0));
 lp | lp_off | lp_flags | lp_len |   t_xmin   | t_xmax | t_field3 | t_ctid | t_infomask2 | t_infomask | t_hoff | t_bits | t_oid 
---- -------- ---------- -------- ------------ -------- ---------- -------- ------------- ------------ -------- -------- -------
  1 |   8128 |        1 |     61 | 1477538885 |      0 |        0 | (0,1)  |           2 |       2050 |     24 |        |      
  2 |   8064 |        1 |     61 | 1477538885 |      0 |        0 | (0,2)  |           2 |       2050 |     24 |        |      
  3 |   8000 |        1 |     61 | 1477538885 |      0 |        0 | (0,3)  |           2 |       2050 |     24 |        |      
  4 |   7936 |        1 |     61 | 1477538885 |      0 |        0 | (0,4)  |           2 |       2050 |     24 |        |      
  5 |   7872 |        1 |     61 | 1477538885 |      0 |        0 | (0,5)  |           2 |       2050 |     24 |        |      
  6 |   7808 |        1 |     61 | 1477538885 |      0 |        0 | (0,6)  |           2 |       2050 |     24 |        |      
  7 |   7744 |        1 |     61 | 1477538885 |      0 |        0 | (0,7)  |           2 |       2050 |     24 |        |      
  8 |   7680 |        1 |     61 | 1477538885 |      0 |        0 | (0,8)  |           2 |       2050 |     24 |        |      
  9 |   7616 |        1 |     61 | 1477538885 |      0 |        0 | (0,9)  |           2 |       2050 |     24 |        |      
 10 |   7552 |        1 |     61 | 1477538885 |      0 |        0 | (0,10) |           2 |       2050 |     24 |        |      

postgres=# select lp,lp_len,t_xmin,t_xmax,t_ctid,t_infomask2,t_infomask,t_hoff from heap_page_items(get_raw_page('m7',0));
 lp | lp_len |   t_xmin   |   t_xmax   | t_ctid | t_infomask2 | t_infomask | t_hoff 
---- -------- ------------ ------------ -------- ------------- ------------ --------
  1 |     61 | 1477538885 | 1477538886 | (0,1)  |        8194 |        258 |     24
  2 |     61 | 1477538885 |          0 | (0,2)  |           2 |       2050 |     24
  3 |     61 | 1477538885 |          0 | (0,3)  |           2 |       2050 |     24
  4 |     61 | 1477538885 |          0 | (0,4)  |           2 |       2050 |     24
  5 |     61 | 1477538885 |          0 | (0,5)  |           2 |       2050 |     24
  6 |     61 | 1477538885 |          0 | (0,6)  |           2 |       2050 |     24
  7 |     61 | 1477538885 |          0 | (0,7)  |           2 |       2050 |     24
  8 |     61 | 1477538885 |          0 | (0,8)  |           2 |       2050 |     24
  9 |     61 | 1477538885 |          0 | (0,9)  |           2 |       2050 |     24
 10 |     61 | 1477538885 |          0 | (0,10) |           2 |       2050 |     24

id=1删除提交

id=2删除回滚

id=3行读锁

id=4行写锁

id=5行2读锁

代码语言:javascript复制
postgres=# select lp,lp_len,t_xmin,t_xmax,t_ctid,t_infomask2,t_infomask,t_hoff from heap_page_items(get_raw_page('m7',0));
 lp | lp_len |   t_xmin   |   t_xmax   | t_ctid | t_infomask2 | t_infomask | t_hoff 
---- -------- ------------ ------------ -------- ------------- ------------ --------
  1 |     61 | 1477538885 | 1477538886 | (0,1)  |        8194 |        258 |     24
  2 |     61 | 1477538885 | 1477538887 | (0,2)  |        8194 |        258 |     24
  3 |     61 | 1477538885 | 1477538889 | (0,3)  |           2 |        466 |     24
  4 |     61 | 1477538885 | 1477538890 | (0,4)  |        8194 |        450 |     24
  5 |     61 | 1477538885 |        343 | (0,5)  |           2 |       4562 |     24
  6 |     61 | 1477538885 |          0 | (0,6)  |           2 |       2050 |     24
  7 |     61 | 1477538885 |          0 | (0,7)  |           2 |       2050 |     24
  8 |     61 | 1477538885 |          0 | (0,8)  |           2 |       2050 |     24
  9 |     61 | 1477538885 |          0 | (0,9)  |           2 |       2050 |     24
 10 |     61 | 1477538885 |          0 | (0,10) |           2 |       2050 |     24
 
 
t_infomask 
258:  HEAP_HASVARWIDTH |                                                                     HEAP_XMIN_COMMITTED
466:  HEAP_HASVARWIDTH | HEAP_XMAX_KEYSHR_LOCK | HEAP_XMAX_EXCL_LOCK | HEAP_XMAX_LOCK_ONLY | HEAP_XMIN_COMMITTED
450:  HEAP_HASVARWIDTH |                         HEAP_XMAX_EXCL_LOCK | HEAP_XMAX_LOCK_ONLY | HEAP_XMIN_COMMITTED
4562: HEAP_HASVARWIDTH | HEAP_XMAX_KEYSHR_LOCK | HEAP_XMAX_EXCL_LOCK | HEAP_XMAX_LOCK_ONLY | HEAP_XMIN_COMMITTED | HEAP_XMAX_IS_MULTI
2050: HEAP_HASVARWIDTH | HEAP_XMAX_INVALID


t_infomask2
8194: 0010000000000010 : HEAP_KEYS_UPDATED | 低11位保存元素数量,这里是两列
2   : 0000000000000010 : 低11位保存元素数量,这里是两列

0 人点赞