注:本文为云贝教育-刘峰 原创,请尊重知识产权,转发请注明出处,不接受任何抄袭、演绎和未经注明出处的转载。
1 https://github.com/df7cb/pg_dirtyread
1 unzip pg_dirtyread-master.zip
2 cd pg_dirtyread-master/
3 make
4 make install
1 create extension pg_dirtyread ;
1 testdb=# CREATE TABLE t1 (id int, name text);2 CREATE TABLE3
1 testdb=# INSERT INTO t1 VALUES (1, 'aaa'), (2, 'bbb'),(3,'ccc');
2 INSERT 0 3
3 testdb=#
4 testdb=# SELECT lp as tuple, t_xmin, t_xmax, t_field3 as t_cid, t_ctid,t_data F
ROM heap_page_items(get_raw_page('t1', 0));
5 tuple | t_xmin | t_xmax | t_cid | t_ctid | t_data
6 -------+--------+--------+-------+--------+----------------------------
7 1 | 1104 | 0 | 0 | (0,1) | \x010000000000000009616161
8 2 | 1104 | 0 | 0 | (0,2) | \x020000000000000009626262
9 3 | 1104 | 0 | 0 | (0,3) | \x030000000000000009636363
10 (3 rows)
11
1 testdb=# DELETE FROM t1 WHERE id = 1;
2 DELETE 1
3 testdb=# DELETE FROM t1 WHERE id = 2;
4 DELETE 1
56 testdb=# SELECT lp as tuple, t_xmin, t_xmax, t_field3 as t_cid, t_ctid,t_data F
ROM heap_page_items(get_raw_page('t1', 0));
7 tuple | t_xmin | t_xmax | t_cid | t_ctid | t_data
8 -------+--------+--------+-------+--------+----------------------------
9 1 | 1104 | 1105 | 0 | (0,1) | \x010000000000000009616161
10 2 | 1104 | 1106 | 0 | (0,2) | \x020000000000000009626262
11 3 | 1104 | 0 | 0 | (0,3) | \x030000000000000009636363
12 (3 rows)
1 ALTER TABLE t1 SET (2 autovacuum_enabled = false , toast . autovacuum_enabled = false );
1 testdb=# \x
2 Expanded display is on.
3 testdb=# select * from pg_stat_all_tables where relname='t1';
4 -[ RECORD 1 ]-------+-------
5 relid | 49546
6 schemaname | public
7 relname | t18 seq_scan | 3
9 seq_tup_read | 6
10 idx_scan |
11 idx_tup_fetch |
12 n_tup_ins | 3
13 n_tup_upd | 0
14 n_tup_del | 2
15 n_tup_hot_upd | 0
16 n_live_tup | 1
17 n_dead_tup | 2
18 n_mod_since_analyze | 5
19 n_ins_since_vacuum | 3
20 last_vacuum |
21 last_autovacuum |
22 last_analyze |
23 last_autoanalyze |
24 vacuum_count | 0
25 autovacuum_count | 0
26 analyze_count | 0
27 autoanalyze_count | 0
1 testdb=# SELECT * FROM pg_dirtyread('t1')2 AS t(tableoid oid, ctid tid, xmin xid, xmax xid, cmin cid, cmax cid, dead boolean,id int, name text);3 tableoid | ctid | xmin | xmax | cmin | cmax | dead | id | name4 ----------+-------+------+------+------+------+------+----+------5 49546 | (0,1) | 1104 | 1105 | 0 | 0 | t | 1 | aaa6 49546 | (0,2) | 1104 | 1106 | 0 | 0 | t | 2 | bbb7 49546 | (0,3) | 1104 | 0 | 0 | 0 | f | 3 | ccc8 (3 rows)
1 testdb=# delete from t1;
2 DELETE 3
3
4 testdb=# SELECT * FROM pg_dirtyread('t1')
5 AS t(tableoid oid, ctid tid, xmin xid, xmax xid, cmin cid, cmax cid, dead bool
ean,id int, name text);
6 tableoid | ctid | xmin | xmax | cmin | cmax | dead | id | name
7 ----------+-------+------+------+------+------+------+-----+-----
8 49541 | (0,1) | 1102 | 1108 | 0 | 0 | f | 1 | aaa
9 49541 | (0,2) | 1102 | 1108 | 0 | 0 | f | 2 | bbb
10 49541 | (0,3) | 1102 | 1108 | 0 | 0 | f | 3 | ccc
11 (3 rows)
12
13 testdb=# select * from t1;
14 id | name
15 -----+-----
16 (0 rows)
17
18 testdb=# SELECT * FROM pg_dirtyread('t1')
19 AS t(tableoid oid, ctid tid, xmin xid, xmax xid, cmin cid, cmax cid, dead boole
an,id int, name text);
20 tableoid | ctid | xmin | xmax | cmin | cmax | dead | id | name
21 ----------+-------+------+------+------+------+------+-----+-----
22 49541 | (0,1) | 1102 | 1108 | 0 | 0 | t | 1 | aaa
23 49541 | (0,2) | 1102 | 1108 | 0 | 0 | t | 2 | bbb
24 49541 | (0,3) | 1102 | 1108 | 0 | 0 | t | 3 | ccc
25 (3 rows)
1 testdb=# alter system set track_commit_timestamp=on;
2 ALTER SYSTEM
3
4 #删除一条数据
5 testdb=# select * from t1;
6 id | name
7 ----+------
8 5 | EEE
9 (1 row)
10
11 testdb=# delete from t1;
12 DELETE 1
13
14 #查看删除时间
15 testdb=# SELECT pg_xact_commit_timestamp(xmin) xmin_time
16 ,pg_xact_commit_timestamp(xmax) xmax_time
17 ,*
18 FROM pg_dirtyread('t1')
19 AS t(tableoid oid, ctid tid, xmin xid, xmax xid, cmin cid, cmax cid, dead bool
ean,id int, name text)
20 where xmax<>0;
21 -[ RECORD 1 ]----------------------------
22 xmin_time | 2023-12-03 16:27:03.830358+08
23 xmax_time | 2023-12-06 10:10:29.115887+08
24 tableoid | 49776
25 ctid | (0,2)
26 xmin | 7207
27 xmax | 7235
28 cmin | 0
29 cmax | 0
30 dead | f
31 id | 5
32 name | EEE
33
1 testdb=# select * from t1;
2 id | name
3 ----+------
4 3 | ccc
5 (1 row)
6
7 testdb=#
8 testdb=# ALTER TABLE t1 DROP COLUMN name;
9 ALTER TABLE
10 testdb=# SELECT * FROM pg_dirtyread('t1') t1(id int, dropped_2 text);
11 id | dropped_2
12 ----+-----------
13 1 | aaa
14 2 | bbb
15 3 | ccc
16 3 | ccc
17 (4 rows)
18
19 testdb=# select * from t1;
20 id
21 ----
22 3
23 (1 row)
1 postgres=# vacuum t1;2 VACUUM
1 testdb=# SELECT lp as tuple, t_xmin, t_xmax, t_field3 as t_cid, t_ctid,t_data F
ROM heap_page_items(get_raw_page('t1', 0));
2 tuple | t_xmin | t_xmax | t_cid | t_ctid | t_data
3 -------+--------+--------+-------+--------+----------------------------
4 1 | | | | |
5 2 | | | | |
6 3 | | | | |
7 4 | 1110 | 0 | 0 | (0,4) | \x030000000000000009636363
8 (4 rows)
1 testdb=# \x
2 Expanded display is on.
3 testdb=# select * from pg_stat_all_tables where relname='t1';
4 -[ RECORD 1 ]-------+------------------------------
5 relid | 49546
6 schemaname | public
7 relname | t1
8 seq_scan | 8
9 seq_tup_read | 33
10 idx_scan |
11 idx_tup_fetch |
12 n_tup_ins | 4
13 n_tup_upd | 0
14 n_tup_del | 3
15 n_tup_hot_upd | 0
16 n_live_tup | 1
17 n_dead_tup | 0
18 n_mod_since_analyze | 7
19 n_ins_since_vacuum | 0
20 last_vacuum | 2023-12-01 14:55:44.099392+0821 last_autovacuum |
22 last_analyze |
23 last_autoanalyze |
24 vacuum_count | 1
25 autovacuum_count | 0
26 analyze_count | 0
27 autoanalyze_count | 0
28
29 testdb=# SELECT * FROM pg_dirtyread('t1') t1(id int, dropped_2 text);
30 id | dropped_2
31 ----+-----------
32 3 | ccc
33 (1 row)
1 ALTER TABLE t1 SET (autovacuum_enabled = false, toast.autovacuum_enabled = false);
1 create table t1_bak select id ,name from ((SELECT * FROM pg_dirtyread('t1')2 AS t(tableoid oid, ctid tid, xmin xid, xmax xid, cmin cid, cmax cid, dead boolean,id int, name text))) as foo;
注:本文为云贝教育 刘峰 原创,请尊重知识产权,转发请注明出处,不接受任何抄袭、演绎和未经注明出处的转载。