Postgresql 连续归档和时间点恢复(PITR)

连续归档和时间点恢复(PITR)

    • 连续归档设置
    • 什么情况下会触发归档?
    • PIRT恢复
          • 一.前期准备
          • 二.恢复到某一时间点
            • 模拟情景
            • 示例
          • 三.恢复到指定还原点
            • 情景模拟
            • 恢复
          • 四.恢复到指定事务
            • 情景模拟
            • 假设要恢复表test01的数据,示例

连续归档设置

所谓WAL日志归档,其实就是把在线的WAL日志备份出来。
要启用WAL归档,需设置wal_level配置参数为replica或更高,设置archive_mode为on,并且使用archive_command配置参数指定一个shell命令。
在pg中配置归档的方法就是配置参数archive_command,参数的配置值是一个Unix命令。此命令把WAL日志文档拷贝到其他的地方。例:
archive_command = ‘cp %p /backup/pgwal/%f’;
//cp 命令。实际执行时,pg会把%p 替换成实际的在线WAL日志文件的全路径名,并把%f替换成不包括路径的WAL日志名。

最后被执行的时候是下面这样:
cp pg_wal/00000001000000A900000065 /backup/pgwal/00000001000000A900000065
对每一个将要被归档的新文件都会生成一个类似的命令。 
我们也可以归档到远程计算机:
archive_command ='scp %p [email protected]:/backup/pgwal/%f';

什么情况下会触发归档?

建立归档后,什么情况下会触发归档?
方法一:手动切换 WAL 日志
PostgreSQL 提供 pg_switch_xlog() 函数可以手工切换 WAL 日志,如下:

--手动归档
Type "help" for help.
postgres=# select pg_switch_xlog();
 pg_switch_xlog 
----------------
 0/87000000
(1 row)
备注:执行 pg_switch_xlog() 后,WAL 会切换到新的日志,这时会将老的 WAL日志归档

方法二:WAL 日志写满后触发归档
WAL 日志被写满后会触发归档,文档在说明配置参数 archive_command 时的第一句说就说明了这点, WAL 日志文件默认为 16MB,这个值可以在编译 PostgreSQL 时通过参数 “–with-wal-segsize” 更改,编译后不能修改。

方法三:设置 archive_timeout
另外可以设置archive 超时参数 archive_timeout ,假如设置 archive_timeout=60 ,那么每 60 s ,
会触发一次 WAL 日志切换,同时触发日志归档,这里有个隐含的假设: 当前 WAL 日志中仍有未归档的 WAL 日志内容.
注:尽量不要把archive_timeout设置的很小,如果设置的很小,他会膨胀你的归档存储,因为,你强制归档的日志,即使没有写满,也会是默认的16M(假设wal日志写满的大小为16M)

PIRT恢复

实现目标:	恢复到指定时间点
实现步骤:	基于数据库做基础备份
			插入新数据
			删除表中部分数据
			基于备份做指定时间点的恢复
			验证数据是否恢复
一.前期准备
  1. 开启WAL归档
vim postgresql.conf
wal_level='replica'    #wal_level至少设置为replica
archive_mode='on'
archive_command='cp %p /backup/pgarch'
#注意/backup/pgarch目录的属主属组都要为postgres(chown -R postgres:postgres /backup/pgarch )
  1. 备份
pg_basebackup -Ft -Pv -Xf -z -Z5 -p5432 -D /pdback
  1. 初始化数据
create table test01(id int primary key,name varchar(20));
insert into test01 values(1,'a'),(2,'b'),(3,'c');
  1. 备份完之后做一次WAL切换,保证最新的WAL日志归档到归档目录
select pg_switch_wal();
二.恢复到某一时间点
模拟情景
  1. test01表目前有四条数据
select * from test01;
 id | name 
----+------
  1 | a
  2 | b
  3 | c
  4 | d
  1. 误操作将数据删除
delete from test01;
select * from test01;
 id | name 
----+------
  1. 数据恢复
#先查看一下当前的时间戳
select current_timestamp;
  current_timestamp       
-------------------------------
 2018-09-10 09:54:55.794813+08
select pg_switch_wal();
 pg_switch_wal 
---------------
 2/DA0003E0
#删除操作大概是3分钟之前的操作,那么将这个时间戳往前推3分钟,切换一下wal日志,确保最新的wal日志同步到归档目录
#思路是利用最新的备份+wal日志恢复数据
示例
  1. 将之前的数据目录备份一下
pg_ctl stop
mv /pgdata /pgdata.bak
  1. 将最新的备份恢复到数据目录
mkdir /pgdata
vim recovery.done
restore_command='cp /backup/pgarch/%f %p'
recovery_target_time='2018-09-10 09:51:55.794813+08'
recovery_target_timeline='latest'
mv ./recovery.done ./recovery.conf
chown -R postgres:postgres /pgdata
chmod 700 /pgdata
select * from test01;
 id | name 
----+------
  1 | a
    2 | b
    3 | c
  4 | d
#可以看到数据已恢复
  1. 解除暂停状态
select pg_wal_replay_resume();
三.恢复到指定还原点
情景模拟
select * from test01;
 id | name 
----+------
    1 | a
    2 | b
     3 | c
    4 | d
select pg_create_restore_point('rp1');
pg_create_restore_point 
-------------------------
  2/D90003B0
#创建一个还原点
drop table test01;
select pg_switch_wal();
 pg_switch_wal 
---------------
 2/DA005700
恢复

思路:最新的备份+wal日志

  1. 将备份恢复,配置recovery.conf文件
vim recovery.conf
restore_command='cp /backup/pgarch/%f %p'
recovery_target_name='rp1'
recovery_target_timeline='latest'
  1. 启动并进入数据库,查看数据是否被恢复
select * from test01 ;
 id | name 
----+------
  1 | a
  2 | b
  3 | c
  4 | d
#可以看到数据已经被恢复了
#当前数据库状态为pause状态(recovery_target_action),我们可以判断当前的数据是否满足我们的预期值,如果不满足,那么可以继续向后推,直到达到我们的预期值
  1. 解除暂停状态
select pg_wal_replay_resume();
四.恢复到指定事务
情景模拟
select * from test01 ;
id | name 
----+------
1 | a
2 | b
3 | c
   4 | d
begin;
select txid_current();
 txid_current 
--------------
   342261
drop table test01 ;
end;
select pg_switch_wal();
假设要恢复表test01的数据,示例
  1. 将最新的备份恢复后,配置recovery.conf文件
vim recovery.conf
restore_command='cp /backup/pgarch/%f %p'
recovery_target_xid='342261'
recovery_target_inclusive = false
recovery_target_timeline='latest'
  1. 启动并进入数据库,检查test01数据是否恢复
select * from test01 ;
id | name 
----+------
1 | a
2 | b
3 | c
   4 | d
#恢复成功
  1. 关闭数据库pause状态
select pg_wal_replay_resume()

你可能感兴趣的:(postgresql,postgresql,wal,归档,PITR)