使用pg_resetwal时空穿梭找回“幽灵”元组

本文介绍了如何使用pg_resetwal工具来修改PostgreSQL控制文件,从而观察MVCC机制下死元组的显现与消失。通过模拟事务删除和事务号推进,展示了在不同xid下表记录的变化,揭示了事务可见性规则。这一方法可用于应急查找未被vacuum清理的死元组记录。
摘要由CSDN通过智能技术生成

pg_resetwal工具是个很有用的工具,我们使用它来修改控制文件的一些信息,可能用的最多的地方是应急清理wal日志并更新lsn信息。但是pg_resetwal这个功能你可能没听说过,可以使用pg_resetwal修改当前事务号来达到查看死元组的信息,这些死元组随着事务号的推进可能会像“幽灵”一样出现,然后消失,通过这种方法可以找回以前的行记录信息。下面具体来看看。

创建一张表,插入三条数据

postgres=# create table test(id int);  
CREATE TABLE
postgres=# insert into test values(1);
INSERT 0 1
postgres=# insert into test values(2);
INSERT 0 1
postgres=# insert into test values(3);
INSERT 0 1

查看表的xmin相关信息,xmin代表插入的事务号

postgres=# select xmin,xmax,* from test;
 xmin | xmax | id
------+------+----
  510 |    0 |  1
  511 |    0 |  2
  512 |    0 |  3
(3 rows)

模拟删除id=2的记录

postgres=# delete from test where id=2;
DELETE 1
postgres=# select xmin,xmax,* from test;
 xmin | xmax | id
------+------+----
  510 |    0 |  1
  512 |    0 |  3
(2 rows)

关闭数据库,使用pg_resetwal设置下一个事务号

[postgres@HWFBS01 ~]$ pg_ctl stop
waiting for server to shut down....... done
server stopped
[postgres@HWFBS01 ~]$ pg_resetwal -x 511 -D /pgdata/pginst1/
Write-ahead log reset

启动数据库,查看test表内容

[postgres@HWFBS01 ~]$ pg_ctl start -l logfile
waiting for server to start.... done
server started
[postgres@HWFBS01 ~]$ psql
psql (13.0)
Type "help" for help.




postgres=# select xmin,xmax,* from test;
 xmin | xmax | id
------+------+----
  510 |    0 |  1
(1 row)

竟然发现id=3的记录莫名消失了,其实也很好理解,因为当前xid=511,xid=512的事务是未来的事务,未来的事务插入的数据对当前事务不可见。

现在模拟xid向前推进,再查看表记录

postgres=# select txid_current();
 txid_current
--------------
          511
(1 row)




postgres=# select xmin,xmax,* from test;
 xmin | xmax | id
------+------+----
  510 |    0 |  1
  511 |  513 |  2
(2 rows)

发现之前删除的id=2的记录竟然惊奇的出现了,怎么来理解呢?因为id=2的记录是xid=513的事务号删除的,而这个事务对于当前xid=511的事务是不可见的,所以xid=513的删除对当前事务来说并未删除,还能看到。

继续模拟xid向前推进

postgres=# select txid_current();
 txid_current
--------------
          512
(1 row)




postgres=# select xmin,xmax,* from test;  
 xmin | xmax | id
------+------+----
  510 |    0 |  1
  511 |  513 |  2
  512 |    0 |  3
(3 rows)

因为当前xid已经推进到512,那么对于以前512号事务插入的id=3的记录此时就变成可见了。

继续推进

postgres=# select txid_current();       
 txid_current
--------------
          513
(1 row)




postgres=# select xmin,xmax,* from test;
 xmin | xmax | id
------+------+----
  510 |    0 |  1
  512 |    0 |  3
(2 rows)

xid来到513时,之前513号事务删除的id=2的元组也消失了。

所以这是一个很有意思的现象,和pg的mvcc机制有关,在某些非常规的情况下可以使用这种方法来应急找到还没来得及被vacuum掉的死元组记录内容。

c1fe42c1cf91c6894989858db979dba0.gif

各位伙伴们好,詹帅本帅搭建了一个个人博客和小程序,汇集各种干货和资源,也方便大家阅读,感兴趣的小伙伴请移步小程序体验一下哦!(欢迎提建议)

推荐阅读

牛逼!Python常用数据类型的基本操作(长文系列第①篇)

牛逼!Python的判断、循环和各种表达式(长文系列第②篇)

牛逼!Python函数和文件操作(长文系列第③篇)

牛逼!Python错误、异常和模块(长文系列第④篇)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值