最佳实践

Halo数据库快速恢复数据

D
DBA 团队
2023年10月25日

目前常用的数据恢复办法基本都是依靠备份进行恢复,备份包括逻辑备份和物理备份。

逻辑备份与恢复:利用数据库自带的类似dump的命令,或者是用图形化界面执行导入导出时,底层就是基于这个dump命令实现的。

优点:简单,方便操作。

缺点:数据数据量比较大,这种方式巨慢,可能导出、导入一天,都无法完所有数据。

物理备份与恢复:找到当前数据库数据文件在磁盘存储的位置,将数据文件直接复制一份或多份,存储在不同的物理机上。

优点:相比逻辑备份,恢复的速度快。

缺点:在备份数据时,可能数据还正在写入,一定程度上会丢失数据。在恢复数据时,也需要注意数据库的版本和环境必须保持高度的一致。如果是线上正在运行的数据库,这种复制的方式无法在生产环境实现。

以上2种备份和恢复都是能够保证数据的正确完整恢复的,但是日常工作当中,用户或者开发很有可能误删除很小量的数据,但是影响范围很大,需要及时快速的在线进行数据恢复,那就需要一款能在最短时间内恢复误操作的数据的工具。

pg_recovery 能够快速在halo数据库恢复误操作数据。该工具支持 update、delete、rollback、dropcolumn 后的数据恢复。

一、下载编译安装

github下载地址:https://github.com/radondb/pg_recovery

bash
[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
bash
[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/'

二、创建扩展

sql
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 行记录)

2.1 创建测试数据

sql
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.2 模拟update修改数据的恢复(recovery update)

sql
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 行记录)

2.3 模拟delete删除数据的恢复(recovery delete)

sql
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 行记录)

2.4 恢复回滚操作之前的数据(recovery rollback)

sql
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 行记录)

2.5 模拟删除的列(recovery drop column)

sql
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 行记录)

2.6 显示该表历史上所有写入过的数据(show all data)

sql
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)

sql
halo0root=# show vacuum_defer_cleanup_age;

  vacuum_defer_cleanup_age 

--------------------------

 0

(1 row)

指定VACUUM和HOT更新在清除死亡行版本之前,应该推迟多久(以事务数量计)。默认值是零个事务,表示死亡行版本将被尽可能快地清除,即当它们不再对任何打开的事务可见时尽快清除。


最新文章

安全公告
2025年04月11日

羲和(Halo)数据库关键补丁更新公告 - 2025年4月

安全公告
2024年06月20日

羲和(Halo)数据库关键补丁更新公告 - 2024年6月

安全公告
2023年12月18日

羲和(Halo)数据库关键补丁更新公告 - 2023年12月