点击上方蓝字关注我们

点击上方蓝字关注我们


PostgreSQL 非常擅长保护用户的数据,避免数据无故丢失。不幸的是,反之亦然——如果数据被删除了,它就无法恢复。
在这篇文章中,我们将探讨从PostgreSQL表中恢复已删除数据的选项。

-- remove an entry from our contact listdb=> DELETE FROM addressbook WHERE name = 'Heinz Schmidt';DELETE 3-- PANIC: WHY WERE THERE 3 ROWS AND NOT JUST ONE
-- remove an entry from our contact listdb=> BEGIN;BEGINdb=*> DELETE FROM addressbook WHERE name = 'Heinz Schmidt';DELETE 3-- NOTICE: huh?db=*> ROLLBACK;ROLLBACK

-- remove an entry from our contact listdb=> DELETE FROM addressbook WHERE name = 'Heinz Schmidt';DELETE 3-- WARNING: oh no, not againdb=> SELECT now();now-----------------------------2024-03-11 16:22:25.1679+01

-- remove an entry from our contact listdb=> DELETE FROM addressbook WHERE name = 'Heinz Schmidt';DELETE 3-- NOTICE: sighdb=> SELECT * FROM addressbook;name | city---------------------+-------------Christoph Berg | KrefeldHans-Jürgen Schönig | Wöllersdorf(2 rows)-- WARNING: put on safety goggles now, we'll need superuser privileges
$ sudo apt install postgresql-16-dirtyreaddb=# CREATE EXTENSION pg_dirtyread;CREATE EXTENSION
db=# \d addressbookTable "public.addressbook"Column | Type | Collation | Nullable | Default--------+------+-----------+----------+---------name | text | | |city | text | | |
db=# SELECT * from pg_dirtyread('addressbook') addressbook(name text, city text);name | city---------------------+-------------Christoph Berg | KrefeldHeinz Schmidt | BerlinHeinz Schmidt | WienHeinz Schmidt | BaselHans-Jürgen Schönig | Wöllersdorf(5 rows)-- NOTICE: phew
db=# CREATE TABLE addressbook_recover ASSELECT * from pg_dirtyread('addressbook') addressbook(name text, city text)WHERE name = 'Heinz Schmidt';SELECT 3db=# SELECT * from addressbook_recover ;name | city---------------+--------Heinz Schmidt | BerlinHeinz Schmidt | WienHeinz Schmidt | Basel(3 rows)db=# INSERT INTO addressbook SELECT * FROM addressbook_recover;INSERT 3

db=# select oid from pg_database where datname = current_database();oid-----5db=# select relfilenode from pg_class where relname = 'addressbook';relfilenode-------------125616db=# select pg_walfile_name(pg_current_wal_lsn());pg_walfile_name--------------------------000000010000000700000037
$ usr/lib/postgresql/16/bin/pg_waldump --relation=1663/5/125616 16/main/pg_wal/000000010000000700000037 | grep DELETErmgr: Heap len (rec/tot): 59/ 359, tx: 1894, lsn: 7/373798E0, prev 7/373798A8, desc: DELETE xmax: 1894, off: 2, infobits: [KEYS_UPDATED], flags: 0x00, blkref #0: rel 1663/5/125616 blk 0 FPWrmgr: Heap len (rec/tot): 54/ 54, tx: 1894, lsn: 7/37379A48, prev 7/373798E0, desc: DELETE xmax: 1894, off: 3, infobits: [KEYS_UPDATED], flags: 0x00, blkref #0: rel 1663/5/125616 blk 0rmgr: Heap len (rec/tot): 54/ 54, tx: 1894, lsn: 7/37379A80, prev 7/37379A48, desc: DELETE xmax: 1894, off: 4, infobits: [KEYS_UPDATED], flags: 0x00, blkref #0: rel 1663/5/125616 blk 0
$ usr/lib/postgresql/16/bin/pg_waldump --save-fullpage=fpw --relation=1663/5/125616 16/main/pg_wal/000000010000000700000037 | grep DELETErmgr: Heap len (rec/tot): 59/ 359, tx: 1894, lsn: 7/373798E0, prev 7/373798A8, desc: DELETE xmax: 1894, off: 2, infobits: [KEYS_UPDATED], flags: 0x00, blkref #0: rel 1663/5/125616 blk 0 FPWrmgr: Heap len (rec/tot): 54/ 54, tx: 1894, lsn: 7/37379A48, prev 7/373798E0, desc: DELETE xmax: 1894, off: 3, infobits: [KEYS_UPDATED], flags: 0x00, blkref #0: rel 1663/5/125616 blk 0rmgr: Heap len (rec/tot): 54/ 54, tx: 1894, lsn: 7/37379A80, prev 7/37379A48, desc: DELETE xmax: 1894, off: 4, infobits: [KEYS_UPDATED], flags: 0x00, blkref #0: rel 1663/5/125616 blk 0$ ls -l fpw-rw-r--r-- 1 postgres postgres 8192 5. Mär 17:18 00000001-00000007-373798E0.1663.5.125616.0_main-rw-r--r-- 1 postgres postgres 8192 5. Mär 17:18 00000001-00000007-37379E00.1663.5.125616.0_main$ rm fpw/00000001-00000007-37379E00.1663.5.125616.0_main
db=# create table addressbook_fpw (like addressbook);CREATE TABLEdb=# select relfilenode from pg_class where relname = 'addressbook';relfilenode-------------125628$ sudo systemctl stop postgresql$ cat fpw/* > base/5/125628$ sudo systemctl start postgresql
db=# SELECT * FROM pg_dirtyread('addressbook_fpw') addressbook(name text, city text);name | city---------------------+-------------Christoph Berg | KrefeldHeinz Schmidt | BerlinHeinz Schmidt | WienHeinz Schmidt | BaselHans-Jürgen Schönig | Wöllersdorf(5 Zeilen)db=# INSERT into addressbookSELECT * FROM pg_dirtyread('addressbook_fpw') addressbook(name text, city text)WHERE name = 'Heinz Schmidt';INSERT 3-- NOTICE: hopefully for the last time

文章转载自KunlunBase 昆仑数据库,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。





