作者:张连壮 PostgreSQL 研发工程师

从事多年 PostgreSQL 数据库内核开发,对 citus 有十分深刻的钻研。

疾速找回失落数据,是数据库的一项重要性能需要,个别倡议应用官网举荐的工具。面向开源数据库,生态中也呈现很多好用的开源工具。

PostgreSQL 是十分风行的开源数据库,接下来介绍一款近期在社区开源的 PostgreSQL 数据找回工具 pg_recovery ,并实例演示如何找回误操作而失落的数据。

| 什么是 pg_recovery?

pg_recovery 是一款 PostgreSQL 数据找回工具。能够复原 COMMIT / DELETE / UPDATE / ROLLBACK / DROP COLUMN 操作后导致的数据变动,并以表的模式返回。装置不便,操作简略。仓库地址:https://github.com/radondb/pg...

疾速装置

依据环境配置 PG_CONFIG。

$ make PG_CONFIG=/home/lzzhang/PG/postgresql/base/bin/pg_configgcc -Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Werror=vla -Wendif-labels -Wmissing-format-attribute -Wformat-security -fno-strict-aliasing -fwrapv -fexcess-precision=standard -Wno-format-truncation -Wno-stringop-truncation -g -g -O0 -fPIC -I. -I./ -I/home/lzzhang/PG/postgresql/base/include/server -I/home/lzzhang/PG/postgresql/base/include/internal  -D_GNU_SOURCE   -c -o pg_recovery.o pg_recovery.cgcc -Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Werror=vla -Wendif-labels -Wmissing-format-attribute -Wformat-security -fno-strict-aliasing -fwrapv -fexcess-precision=standard -Wno-format-truncation -Wno-stringop-truncation -g -g -O0 -fPIC -shared -o pg_recovery.so pg_recovery.o -L/home/lzzhang/PG/postgresql/base/lib    -Wl,--as-needed -Wl,-rpath,'/home/lzzhang/PG/postgresql/base/lib',--enable-new-dtags  $ make install PG_CONFIG=/home/lzzhang/PG/postgresql/base/bin/pg_config/usr/bin/mkdir -p '/home/lzzhang/PG/postgresql/base/lib'/usr/bin/mkdir -p '/home/lzzhang/PG/postgresql/base/share/extension'/usr/bin/mkdir -p '/home/lzzhang/PG/postgresql/base/share/extension'/usr/bin/install -c -m 755  pg_recovery.so '/home/lzzhang/PG/postgresql/base/lib/pg_recovery.so'/usr/bin/install -c -m 644 .//pg_recovery.control '/home/lzzhang/PG/postgresql/base/share/extension/'/usr/bin/install -c -m 644 .//pg_recovery--1.0.sql  '/home/lzzhang/PG/postgresql/base/share/extension/'

初始化插件胜利,返回如下信息。

$ create extension pg_recovery ;CREATE EXTENSION

| 数据找回演示

1. 筹备初始化数据

筹备一个表和一些数据。

$ create table lzzhang(id int, dp int);CREATE TABLE# insert into lzzhang values(1, 1);INSERT 0 1$ insert into lzzhang values(2, 2);INSERT 0 1

2. 找回 UPDATE 数据

对数据进行变更操作,不加 WHERE 条件。

$ update lzzhang set id=3, dp=3;UPDATE 2lzzhang=# select * from pg_recovery('lzzhang') as (id int, dp int); id | dp ----+----  1 |  1  2 |  2(2 rows)$ select * from lzzhang; id | dp ----+----  3 |  3  3 |  3(2 rows)

3. 找回 DELETE 数据

尝试复原 DELETE 的数据。

$ delete from lzzhang;DELETE 2lzzhang=# select * from lzzhang; id | dp ----+----(0 rows)$ select * from pg_recovery('lzzhang') as (id int, dp int); id | dp ----+----  1 |  1  2 |  2  3 |  3  3 |  3(4 rows)

4. 找回 ROLLBACK 数据

尝试复原回滚操作之前的数据。

$ begin ;BEGIN$ insert into lzzhang values(4, 4);INSERT 0 1$ rollback ;ROLLBACK$ select * from lzzhang; id | dp ----+----(0 rows)$ select * from pg_recovery('lzzhang') as (id int, dp int); id | dp ----+----  1 |  1  2 |  2  3 |  3  3 |  3  4 |  4(5 rows)

5. 找回 DROP COLUMN 数据

尝试复原表中被删除的列及数据。

$ alter table lzzhang drop column dp;ALTER TABLE$ select attnum from pg_attribute, pg_class where attrelid = pg_class.oid and pg_class.relname='lzzhang' and attname ~ 'dropped'; attnum --------      2(1 row)$ select * from lzzhang; id ----(0 rows)$ select * from pg_recovery('lzzhang') as (id int, dropped_attnum_2 int); id | dropped_attnum_2 ----+------------------  1 |                1  2 |                2  3 |                3  3 |                3  4 |                4(5 rows)-- dropped_attnum_2: if the drop attnum is 5, set dropped_attnum_2 to dropped_attnum_5

6. 显示找回数据

显示该表历史上所有写入过的数据。

$ insert into lzzhang values(5);INSERT 0 1$ select * from lzzhang; id ----  5(1 row)$ select * from pg_recovery('lzzhang', recoveryrow => false) as (id int, recoveryrow bool); id | recoveryrow ----+-------------  1 | t  2 | t  3 | t  3 | t  4 | t  5 | f(6 rows)

注意事项

  • 反对的 PostgreSQL 版本

目前 pg_revovery工具已反对 PostgreSQL 12/13/14 。

  • 可复原事务数

PostgreSQL 通过参数 vacuum_defer_cleanup_age 值大小,可限度可复原的事务数。如果预期须要复原的数据量较大,可通过配置参数值,进步可复原的事务数。

pg_recovery 通过读取 PostgreSQL dead 元组来复原不可见的表数据。如果元组被 vacuum 革除掉,那么 pg_recovery 便不能复原数据。

  • 锁申请

pg_recovery 应用期间,反对失常的读表的锁申请。此外 pg_recovery未应用期间,不会对数据库造成任何额定的开销或是影响,无需暂停服务。