首页 > 数据库 > 国内数据库 > openGauss 基于PITR的恢复,实战经验满满
作者:IT邦德
中国DBA联盟(ACDU)成员,10余年DBA工作经验,
Oracle、PostgreSQL ACE
CSDN博客专家及B站知名UP主,全网粉丝10万+
擅长主流Oracle、MySQL、PG、高斯及Greenplum备份恢复,
安装迁移,性能优化、故障应急处理
微信:jem_db
QQ交流群:587159446
公众号:IT邦德
国产数据库使用的过程中,基于PITR的恢复非常的重要,这里给大家分享openGauss 基于PITR的恢复
当数据库崩溃或希望回退到数据库之前的某一状态时,opengauss的即时恢复功能( Point-In-Time Recovery,简称PITR ),可以支持恢复到备份归档数据之后的任意时间点。
仅主节点可以进行PITR恢复,备机需要进行全量build达成与主机数据同步。
1.使用omm用户登录主库确认归档是否开启 查看当前归档日志相关参数,查看当前openGauss数据库管理系统的归档设置: openGauss=# select name,setting from pg_settings where name like 'archive%' or name = 'wal_level'; name | setting ------------------+------------- archive_command | (disabled) archive_dest | archive_interval | 1 archive_mode | off archive_timeout | 0 wal_level | hot_standby (6 rows) 说明:可以看出,数据库在非归档方式(参数archive_mode的值为off)。 vi $PGDATA/postgresql.conf # 修改archive_mode的值需要重启动数据库 archive_mode=on # 修改archive_command的值不需要重启动数据库,只需要reload archive_command = 'cp %p /archivelog/%f' # 修改archive_time:归档周期,900表示每900秒(15分钟)切换一次 archive_timeout = 900 用Linux用户omm,执行下面的命令,启动openGauss数据库: gs_om -t restart 再次查看归档日志相关参数 执行下面的命令,查看当前openGauss数据库的归档设置: [omm@centos79 ~]$ gsql -c "select name,setting from pg_settings where name like 'archive%' or name = 'wal_level'" name | setting ------------------+---------------------- archive_command | cp %p /archivelog/%f archive_dest | archive_interval | 1 archive_mode | on archive_timeout | 900 wal_level | hot_standby (6 rows)
PITR恢复流程: 1.将物理备份的文件替换目标数据库目录。 2.删除数据库目录下pg_xlog/中的所有文件。 3.将归档的WAL日志文件复制到pg_xlog文件中 4.在数据库目录下创建恢复命令文件recovery.conf,指定数据库恢复的程度。 5.启动数据库。 6.连接数据库,查看是否恢复到希望预期的状态。 7.若已经恢复到预期状态,通过pg_xlog_replay_resume()指令使主节点对外提供服务。 #### 归档恢复配置 #### ## 该SHELL命令获取已归档的WAL文件。 restore_command = 'cp /gauss/bak/archive/%f %p' ## 清理备库WAL归档日志的shell命令,每次重启时会执行 archive_cleanup_command = 'pg_archivecleanup /gauss/bak/archive %r' #### 恢复目标设置(四选一) #### ## 还原到一个使用pg_create_restore_point()创建的还原点 recovery_target_name = 'restore_point_1' ## 还原到一个指定时间戳 recovery_target_time = '2020-01-01 12:00:00' ## 还原到一个事务ID recovery_target_xid = '3000' ## 还原到日志的指定LSN点 recovery_target_lsn = '0/0FFFFFF' ## 声明是否在指定恢复目标之后停止(true) 或 之前停止(false),不支持recovery_target_name 配置 recovery_target_inclusive = true ## 注意:如果不配置任何恢复目标 或 配置目标不存在,则默认恢复到最新的WAL日志点。
#使用gs_basebackup全量备份 创建备份文件存储目录,gs_basebackup备份 数据库需要处于开启状态 [omm@centos79 ~]$ mkdir -p /home/omm/gs_bak [omm@centos79 ~]$ gs_basebackup -D /home/omm/gs_bak -p 15400 INFO: The starting position of the xlog copy of the full build is: 0/E000028. The slot minimum LSN is: 0/0. The disaster slot minimum LSN is: 0/0. The logical slot minimum LSN is: 0/0. [2024-09-19 05:49:45]:begin build tablespace list [2024-09-19 05:49:45]:finish build tablespace list [2024-09-19 05:49:45]:begin get xlog by xlogstream [2024-09-19 05:49:45]: check identify system success [2024-09-19 05:49:45]: send START_REPLICATION 0/E000000 success [2024-09-19 05:49:45]: keepalive message is received [2024-09-19 05:49:45]: keepalive message is received [2024-09-19 05:49:50]:gs_basebackup: base backup successfully
1)记录操作的起始位置
--创建测试数据
openGauss=# \c testdb
testdb=# \dt
List of relations
Schema | Name | Type | Owner | Storage
--------+---------+-------+-------+----------------------------------
public | test | table | omm | {orientation=row,compression=no}
public | testbak | table | omm | {orientation=row,compression=no}
(2 rows)
-- 创建一个还原点restore_point_1
testdb=# select pg_create_restore_point('restore_point_1');
pg_create_restore_point
-------------------------
0/F00B638
(1 row)
2)创建测试数据t1表(源库),切日志
drop table t1;
create table t1(name varchar(50));
insert into t1 values('This is restore_point_1');
testdb=# select pg_switch_xlog();
pg_switch_xlog
----------------
0/F016398
(1 row)
testdb=# select pg_switch_xlog();
pg_switch_xlog
----------------
0/10000A68
(1 row)
3)记录第一次数据插入后的数据库位置
testdb=# \x
Expanded display is on.
testdb=# select * from pg_get_variable_info();
-[ RECORD 1 ]------------+-----------
node_name | dn_6001
next_oid | 16417
next_xid | 45588
oldest_xid | 12666
xid_vac_limit | 4000012666
oldest_xid_db | 15649
last_extend_csn_logpage | 63
start_extend_csn_logpage | 0
next_commit_seqno | 3298
latest_completed_xid | 45587
startup_max_xid | 45154
-- 查看最近提交的XID(latestCompletedXid-->45587 || nextXid-->45588)
4)创建测试数据t2表(源库)
-- 创建表t2并插入数据
create table t2(name varchar(50));
insert into t2 values('This is insert into t2');
testdb=# select pg_current_xlog_location();
pg_current_xlog_location
--------------------------
0/1100BE28
(1 row)
testdb=# select pg_switch_xlog();
pg_switch_xlog
----------------
0/1100D060
(1 row)
testdb=# select pg_switch_xlog();
pg_switch_xlog
----------------
0/12001368
(1 row)
5)记录第二次数据插入后的数据库位置
-- 查询当前LSN 数据库t1、t2
testdb=# select pg_current_xlog_location();
pg_current_xlog_location
--------------------------
0/13002E60
(1 row)
配置recovery.conf文件(基于还原点restore_point_1恢复) #创建recovery.conf文件 cd /home/omm/data/db1/ cat> recovery.conf<<EOF restore_command = 'cp /archivelog/%f %p' archive_cleanup_command = 'pg_archivecleanup /archivelog %r' recovery_target_name = 'restore_point_1' ## 恢复到指定的还原点restore_point_1,此时还没有创建表t1和t2 recovery_target_inclusive = true EOF #由于在本机操作,关闭源数据库,避免port冲突 $ gs_om -t stop #启动恢复目标数据库并查看数据,数据目录: /home/omm/data/db1 $ gs_ctl start -D /home/omm/data/db1 -- 检查当前数据库是否处于恢复状态 gsql -r -d testdb openGauss=# select pg_is_in_recovery(); pg_is_in_recovery ------------------- t (1 row) openGauss=# select pg_current_xlog_location(); ERROR: recovery is in progress HINT: WAL control functions cannot be executed during recovery. CONTEXT: referenced column: pg_current_xlog_location openGauss=# drop table t1; ERROR: cannot execute DROP TABLE in a read-only transaction 恢复说明: 表t1和t2都不存在,且处于恢复状态数据库无法使用函数查看LSN位置,该数据库只读 #查看日志中的恢复情况 cd /openGauss/log/omm/omm/pg_log/dn_6001 grep -C 3 "restore_point_1" /openGauss/log/omm/omm/pg_log/dn_6001/postgresql-2024-09-19_060448.log

-- 修改recovery_target,继续往前恢复
cd /home/omm/data/db1/
mv recovery.done recovery.conf
vi recovery.conf
--------------------------
# 根据前面的信息得知,xid=19251这个事务完毕时,仅有t1表,没有t2表
# 我们这一阶段仅恢复t1表即可
# 修改:
recovery_target_xid = '45587'
--------------------------
-- 重启恢复测试数据
gs_ctl restart -D /home/omm/data/db1/
-- 检查当前数据库是否处于恢复状态
gsql -r -d testdb
openGauss=# select pg_is_in_recovery();
pg_is_in_recovery
-------------------
t
(1 row)
testdb=# \dt
List of relations
Schema | Name | Type | Owner | Storage
--------+---------+-------+-------+------------------------------------------------------
public | t1 | table | omm | {orientation=row,compression=no,storage_type=USTORE}
public | test | table | omm | {orientation=row,compression=no}
public | testbak | table | omm | {orientation=row,compression=no}
(3 rows)
testdb=# select * from t1;
name
-------------------------
This is restore_point_1
(1 row)
恢复说明:此时数据仅恢复了表t1,并未恢复表t2,实验结果满足预期目标 ^
-- 从日志中我们也可以看到,数据库恢复至xid=45587后
#查看日志中的恢复情况
cd /openGauss/log/omm/omm/pg_log/dn_6001
grep -C 3 "45587" /openGauss/log/omm/omm/pg_log/dn_6001/postgresql-2024-09-19_061518.log

-- 修改recovery_target,继续往前恢复
cd /home/omm/data/db1/
mv recovery.done recovery.conf
vi recovery.conf
# 根据前面的信息得知,lsn='0/13002E60'这个LSN位置时,t1表和t2表已经创建完毕
# 修改:
recovery_target_lsn = '0/13002E60'
-- 重启恢复测试数据
gs_ctl restart -D /home/omm/data/db1/
-- 检查当前数据库是否处于恢复状态
gsql -r -d testdb
openGauss=# select pg_is_in_recovery();
pg_is_in_recovery
-------------------
t
(1 row)
testdb=# \dt
List of relations
Schema | Name | Type | Owner | Storage
--------+---------+-------+-------+------------------------------------------------------
public | t1 | table | omm | {orientation=row,compression=no,storage_type=USTORE}
public | t2 | table | omm | {orientation=row,compression=no,storage_type=USTORE}
public | test | table | omm | {orientation=row,compression=no}
public | testbak | table | omm | {orientation=row,compression=no}
(4 rows)
testdb=# select * from t1;
name
-------------------------
This is restore_point_1
(1 row)
testdb=# select * from t2;
name
------------------------
This is insert into t2
(1 row)
-- 从日志中我们也可以看到,数据库恢复至LSN=0/13002E60后,
检测到Double-write日志后续内容为空(Empty),则认为数据库已恢复至最新状态,此时恢复任务结束(Finish)
#查看日志中的恢复情况
cd /openGauss/log/omm/omm/pg_log/dn_6001
grep -A 5 "0/13002E60" /openGauss/log/omm/omm/pg_log/dn_6001/postgresql-2024-09-19_062157.log

9.结束PITR
当未将数据库恢复至最新时刻状态时,此时需要手动结束PITR恢复任务。 -- 查询数据库恢复状态 testdb=# select pg_is_in_recovery(); pg_is_in_recovery ------------------- t (1 row) -- 结束恢复,使机器对外提供读写服务 testdb=# select pg_xlog_replay_resume(); pg_xlog_replay_resume ----------------------- -- 查询数据库恢复状态(已结束) testdb=# select pg_is_in_recovery(); pg_is_in_recovery ------------------- f (1 row) --可以看到目前数据库可以读写了 testdb=# drop table testbak; DROP TABLE
%f即归档检索中的文件名,%p即复制目的地的路径名,%r最新可用重启点的文件名
如果多个备机从相同的归档路径恢复时,需要确保该路径存在所有备机恢复所需要的WAL文件。
整个恢复的过程为了方式端口被占用,请关闭原库
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/69947868/viewspace-3027909/ ,如需转载,请注明出处,否则将追究法律责任。