目前常用的数据恢复办法基本都是依靠备份进行恢复,备份包括逻辑备份和物理备份。
逻辑备份与恢复 :利用数据库自带的类似dump的命令,或者是用图形化界面执行导入导出时,底层就是基于这个dump命令实现的。
优点:简单,方便操作。
缺点:数据数据量比较大,这种方式巨慢,可能导出、导入一天,都无法完所有数据。
物理备份与恢复 :找到当前数据库数据文件在磁盘存储的位置,将数据文件直接复制一份或多份,存储在不同的物理机上。
优点:相比逻辑备份,恢复的速度快。
缺点:在备份数据时,可能数据还正在写入,一定程度上会丢失数据。在恢复数据时,也需要注意数据库的版本和环境必须保持高度的一致。如果是线上正在运行的数据库,这种复制的方式无法在生产环境实现。
以上2中备份和恢复都是能够保证数据的正确完整恢复的,但是日常工作当中,用户或者开发很有可能误删除很小量的数据,但是影响范围很大,需要及时快速的在线进行数据恢复,那就需要一款能在最短时间内恢复误操作的数据的工具。
pg_recovery 能够快速在halo数据库恢复误操作数据。该工具支持 update、delete、rollback、dropcolumn 后的数据恢复。
一、下载编译安装
github下载地址:https://github.com/radondb/pg_recovery
[halo@localhost src]$ ls -rlt pg_recovery-master.zip
-rw-r--r-- 1 root root 13023 10月 30 10:19 pg_recovery-master.zip
[halo@localhost ~]$ unzip pg_recovery-master.zip
Archive: pg_recovery-master.zip
886fc628534b43eb27344aaa07aabcc85f4d0b0e
creating: pg_recovery-master/
inflating: pg_recovery-master/.gitignore
inflating: pg_recovery-master/License
inflating: pg_recovery-master/Makefile
inflating: pg_recovery-master/README.md
inflating: pg_recovery-master/README_zh_CN.md
creating: pg_recovery-master/expected/
inflating: pg_recovery-master/expected/recovery.out
inflating: pg_recovery-master/pg_recovery--1.0.sql
inflating: pg_recovery-master/pg_recovery.c
inflating: pg_recovery-master/pg_recovery.control
creating: pg_recovery-master/sql/
inflating: pg_recovery-master/sql/recovery.sql
[halo@localhost pg_recovery-master]$ cd pg_recovery-master/
[halo@localhost pg_recovery-master]$ make PG_CONFIG=/u01/app/halo/product/dbms/14/bin/pg_config
[halo@localhost pg_recovery-master]$ make install PG_CONFIG=/u01/app/halo/product/dbms/14/bin/pg_config
/bin/mkdir -p '/u01/app/halo/product/dbms/14/lib/postgresql'
/bin/mkdir -p '/u01/app/halo/product/dbms/14/share/postgresql/extension'
/bin/mkdir -p '/u01/app/halo/product/dbms/14/share/postgresql/extension'
/bin/install -c -m 755 pg_recovery.so '/u01/app/halo/product/dbms/14/lib/postgresql/pg_recovery.so'
/bin/install -c -m 644 .//pg_recovery.control '/u01/app/halo/product/dbms/14/share/postgresql/extension/'
/bin/install -c -m 644 .//pg_recovery--1.0.sql '/u01/app/halo/product/dbms/14/share/postgresql/extension/'
二、创建扩展
halo0root=# create extension pg_recovery;
CREATE EXTENSION
halo0root=# \dx pg_recovery
已安装扩展列表
名称 | 版本 | 架构模式 | 描述
-------------+------+----------+---------------------------------------------------------------------
pg_recovery | 1.0 | public | recovery table data of update/delete/rollback rows and drop columns
(1 行记录)
1、创建测试数据
halo0root=# create table halo_test(id int,name varchar(20));
CREATE TABLE
halo0root=# insert into halo_test values(1,'杭州');
INSERT 0 1
halo0root=# insert into halo_test values(2,'北京');
INSERT 0 1
halo0root=# select * from halo_test;
id | name
----+------
1 | 杭州
2 | 北京
(2 行记录)
2、模拟update修改数据的恢复(recovery update)
halo0root=# update halo_test set id=3,name='重庆' where id=1 and name='杭州';
UPDATE 1
halo0root=# update halo_test set id=4,name='天津' where id=2 and name='北京';
UPDATE 1
halo0root=# select * from halo_test;
id | name
----+------
3 | 重庆
4 | 天津
(2 行记录)
halo0root=# select*from pg_recovery('halo_test')as(id int,name varchar(20));
id | name
----+------
1 | 杭州
2 | 北京
(2 行记录)
3、模拟delete删除数据的恢复(recovery delete)
halo0root=# delete from halo_test;
DELETE 2
halo0root=# select * from halo_test;
id | name
----+------
(0 行记录)
halo0root=# select * from pg_recovery('halo_test')as(id int,name varchar(20));
id | name
----+------
1 | 杭州
2 | 北京
3 | 重庆
4 | 天津
(4 行记录)
4、恢复回滚操作之前的数据(recovery rollback)
halo0root=# begin;
BEGIN
halo0root=*# insert into halo_test values(5,'南京');
INSERT 0 1
halo0root=*# rollback;
ROLLBACK
halo0root=# select * from halo_test;
id | name
----+------
(0 行记录)
halo0root=# select * from pg_recovery('halo_test')as(id int,name varchar(20));
id | name
----+------
1 | 杭州
2 | 北京
3 | 重庆
4 | 天津
5 | 南京
(5 行记录)
5、模拟删除的列(recovery drop column)
halo0root=# alter table halo_test drop column name;
ALTER TABLE
halo0root=# select attnum from pg_attribute a, pg_class where attrelid = pg_class.oid and pg_class.relname='halo_test' and attname ~ 'dropped';
attnum
--------
2
(1 行记录)
halo0root=# select * from halo_test;
id
----
(0 行记录)
halo0root=# select * from pg_recovery('halo_test') as (id int, dropped_attnum_2 varchar(20));
id | dropped_attnum_2
----+------------------
1 | 杭州
2 | 北京
3 | 重庆
4 | 天津
5 | 南京
(5 行记录)
6、显示该表历史上所有写入过的数据(show all data)
halo0root=# insert into halo_test values(6);
INSERT 0 1
halo0root=# select * from halo_test;
id
----
6
(1 行记录)
halo0root=# select*from pg_recovery('halo_test', recoveryrow =>false)as(id int, dropped_attnum_2 varchar(20), recoveryrow bool);
id | dropped_attnum_2 | recoveryrow
----+------------------+-------------
1 | 杭州 | t
2 | 北京 | t
3 | 重庆 | t
4 | 天津 | t
5 | 南京 | t
6 | | f
(6 行记录)
三、注意事项
pg_recovery是通过读取postgresql表中的死元组进行数据恢复。
如果表做了vacuum或者vacuum full操作清理了死元组后,pg_recovery无法对表数据进行恢复。
涉及参数 vacuum_defer_cleanup_age (integer)
halo0root=# show vacuum_defer_cleanup_age;
vacuum_defer_cleanup_age
--------------------------
0
(1 row)
指定VACUUM和HOT更新在清除死亡行版本之前,应该推迟多久(以事务数量计)。默认值是零个事务,表示死亡行版本将被尽可能快地清除,即当它们不再对任何打开的事务可见时尽快清除。




