253 Star 648 Fork 460

GVPopenGauss / openGauss-server

 / 详情

【业务范畴:开源】【测试类型:工具功能】【测试活动:社区】【测试版本:2.0.0】【特性名称:PITR】【环境:裸机】PITR指定时间戳恢复失败

Accepted
Bug
Opened this issue  
2021-08-05 17:02

【硬件类型版本】(cat /etc/system-release):openEuler release 20.03 (LTS)
【数据库版本号】(gaussdb –V): gaussdb (openGauss 2.0.1 build 18b92d01) compiled at 2021-08-04 20:41:29 commit 0 last mr
【测试环境】:arm+openEuler
【被测功能】:PITR
【测试类型】:功能测试
【对应用例号】:无
【预置条件】:单机
【测试步骤】:
1.开启归档开关
gs_guc reload -N all -D dn1 -c "archive_mode=on"
gs_guc reload -N all -D dn1 -c "archive_command='cp %p archive/%f'"
2.创建表1并插入数据,并查询当前时间
CREATE TABLE tab1(a1 int);
INSERT INTO tab1 VALUES (1),(2),(3);
select now();
3.进行数据库全量备份
select pg_start_backup('bak_time001');
select pg_stop_backup();
select pg_switch_xlog();
4.创建表2并插入数据
CREATE TABLE tab2(a1 int);
INSERT INTO tab2 VALUES (1),(2),(3);
5.打包dn1目录
tar -cvzf data.tar dn1
6.模拟数据库故障
停止集群
gs_om -t stop
删除dn1目录
rm -rf dn1
7.使用备份文件恢复
解压备份文件
tar -zxvf data.tar
8.新增配置文件recovery.conf ,指定恢复时间点
restore_command = 'cp archive/%f %p'
archive_cleanup_command='pg_archivecleanup archive %r'
recovery_target_time='2020-08-26 17:17:51'(步骤1时间)
9.启动数据库,查看表及表数据;
gs_om -t start
\d
select * from tab1;
【预期输出】9.数据库启动成功
【实际输出】9.数据库启动超时,一直处于recovery状态
【原因分析】:
数据库状态异常
输入图片说明
【测试代码】:无

Comments (7)

liumin created缺陷
liumin set related repository to openGauss/openGauss-server
Expand operation logs

Hey @liumin , Welcome to openGauss Community.
All of the projects in openGauss Community are maintained by @opengauss-bot .
That means the developers can comment below every pull request or issue to trigger Bot Commands.
Please follow instructions at https://gitee.com/opengauss/community/blob/master/contributors/command.en.md to find the details.

liumin set assignee to 熊小军
liumin set priority to Serious
zhangxubo added
 
sig/storageengine
label

this issue is assigned to: @cchen676 .

opengauss-bot changed assignee from 熊小军 to cchen676

@lum123456 @熊小军
该issue其实是因为测试步骤不正确导致
解释如下:

  1. PITR功能的目的是当数据库发生崩溃时,通过一个基础备份+WAL(归档的xlog)将数据库状态恢复到指定位置
  2. 所以前提是需要一个基础的备份(可以理解为旧的数据)和WAL(可以理解为从基础备份往后的新增的数据,当然包括基础备份)
  3. issue中的测试方法之所以有误,因为issue中使用的备份不是一个基础备份,而是做完了一些操作(建tab1, 建tab2, 且希望恢复到tab1的时间点)后, 数据库崩溃时间点前的备份,这个备份本质上和崩溃时间点的数据没有任何区别,它不是一个足够旧的数据
  4. 同理,issue中使用的WAL也不是基于基础备份,且包含"需要恢复的数据"的新增WAL,它是一个和issue中使用的备份接近的一个WAL,中间可能就没有什么变化
  5. 所以如果使用issue中的测试步骤, 当数据库崩溃后, 使用备份, 又删掉了备份中所有的xlog, 数据库必然无法启动, 因为一:数据库找不到checkpoinit.redo的xlog文件, 归档中也没有(这里还有一个前提,使用的备份里面得有备份数据的标志backup_label), 二:假设数据库能启动,也必然恢复不到指定的位置,因为数据库一定会恢复到最新的checkpoint.redo的一致位置,而这个状态早就包含了前面的所有操作的数据,即tab1 和tab2

下面列出正确的测试步骤如下:

  1. 构建一个基础备份:
    这里需要注意的是, 如果使用issue中使用的sql命令进行基础备份, 需要在执行完pg_start_backup之后, 先备份数据, 再执行pg_stop_backup. 即pg_start_backup --> tar命令备份数据 --> pg_stop_backup
    因为我们所需要的备份数据里面一定需要包含backup_label这个标志文件, 如果执行顺序是 pg_start_backup --> pg_stop_backup --> tar命令备份数据, 这样备份出来的数据里面是没有backup_label的, 没有任何作用.

select pg_start_backup('bak_time001');
\! tar czf dnbackup.tar dn
select pg_stop_backup();

或者, 我们也可以直接使用gs_basebackup命令备份, 这样备份出来的数据直接就包含了backup_label

gs_basebackup -Pv -Xf -p 12300 -D /home/cctest/gsbackup

  1. 强制做下xlog归档, 这样可以确保归档的WAL是包含基础备份的

select pg_switch_xlog();

  1. 构造测试数据1, 这个是我们期望恢复的数据中包含的数据

create table tab1(a1 int);
insert into tab1 values (1), (2), (3);
select now(); //假设时间点为T3

  1. 强制做下xlog归档, 这样可以确保归档的WAL是包含我们需要恢复的数据

select pg_switch_xlog();

  1. 构造测试数据2, 这个是我们期望恢复的数据中不包含的数据

create table tab2(a2 int);
insert into tab2 values (1), (2), (3);

  1. 模拟数据库崩溃场景

kill -9 openGaussPid
rm -rf dn/*

  1. 恢复基础备份, 即将步骤1中备份的数据拷贝到dn目录下

  2. 这里是否需要删除掉pg_xlog下的所有文件, 其实删不删都可以, 因为归档的WAL一定包含了基础备份的所有数据, 而当前的备份不包含我们要恢复的数据
    如果这里要测试删除场景, 注意至少保留一个000001文件, 因为xlog目录不允许为空

  3. 在dn目录下创建recovery.conf文件, 指定恢复时间点为步骤3中的T3

restore_command = 'cp /data/archive/%f %p'
archive_cleanup_command = 'pg_archivecleanup /data/archive %r'
recovery_target_time = '2021-09-18 09:23:52'

  1. 启动数据库验证, 预期结果是, 存在tab1, 不存在tab2

实测结果如下, 步骤编号对应上一条回复里的步骤编号:

  1. 步骤1到2, 通过pg_current_xlog_insert_location可以确认当前xlog刷新的位点
	postgres=\# select pg_start_backup('bak_time001');
	pg_start_backup 
	-----------------
	3/44000028
	(1 row)
	
	postgres-# \! tar czf dnbackup.tar dn1
	
	tar: dn1/global/pg_dw: file changed as we read it
	postgres-# 
	postgres=# select pg_stop_backup();
	NOTICE:  pg_stop_backup complete, all required WAL segments have been archived
	CONTEXT:  referenced column: pg_stop_backup
	pg_stop_backup 
	----------------
	3/440004B8
	(1 row)
	
	postgres=# select pg_switch_xlog();
	
	pg_switch_xlog 
	----------------
	3/45000160
	(1 row)
	
	postgres=# 
	postgres=# select * from pg_current_xlog_insert_location();
	pg_current_xlog_insert_location 
	---------------------------------
	3/46000140
	(1 row)
  1. 步骤3到5
	postgres=# create table test1(a1 int);  
	CREATE TABLE
	postgres=# insert into test1 values (1), (2), (3);  
	INSERT 0 3
	postgres=# select now(); 
				now              
	-------------------------------
	2021-09-19 09:53:21.252124+08
	(1 row)
	
	postgres=# select pg_switch_xlog();
	pg_switch_xlog 
	----------------
	3/46001C38
	(1 row)
	
	postgres=# create table test2(a2 int);  
	CREATE TABLE
	postgres=# insert into test2 values (1), (2), (3);  
	INSERT 0 3
	postgres=# \q
  1. 步骤6到7
	[pkg0914@kwepwebenv02644 cluster]$ kill -9 2229962
	[pkg0914@kwepwebenv02644 cluster]$ rm -rf dn1/*
	[pkg0914@kwepwebenv02644 cluster]$ tar zxf dnbackup.tar 
	[pkg0914@kwepwebenv02644 cluster]$ cd dn1/pg_xlog/
  1. 步骤8,这里使用删除基础备份的xlog文件的测试方法,但因为基础备份的pg_xlog里面没有0000000001文件,那么随便保留一个可用的即可,可以保留序号小于步骤1时执行开始备份显示的xlog位点的
	[pkg0914@kwepwebenv02644 pg_xlog]$ ls -l
	total 16384
	-rw------- 1 pkg0914 pkg0914 16777216 Sep 18 11:13 000000010000000300000033
	drwx------ 2 pkg0914 pkg0914      191 Sep 19 09:57 archive_status
  1. 步骤9
	[pkg0914@kwepwebenv02644 dn1]$ vim recovery.conf 
	restore_command = 'cp /home/pkg0914/archive/%f %p'
	archive_cleanup_command = 'pg_archivecleanup /home/pkg0914/archive %r'
	recovery_target_time = '2021-09-19 09:53:22'
  1. 启动后验证如下
	postgres=# select * from test1;
	a1 
	----
	1
	2
	3
	(3 rows)
	
	postgres=# select * from test2;
	ERROR:  relation "test2" does not exist on dn_6001_6002_6003
	LINE 1: select * from test2;

已与测试人员沟通,作为非问题关闭

cchen676 changed issue state from 待办的 to 已完成
liumin changed issue state from 已完成 to 已验收

Sign in to comment

Status
Assignees
Projects
Milestones
Pull Requests
Successfully merging a pull request will close this issue.
Branches
Planed to start   -   Planed to end
-
Top level
Priority
Duration (hours)
Confirm
参与者(3)
5622128 opengauss bot 1581905080
C++
1
https://gitee.com/opengauss/openGauss-server.git
git@gitee.com:opengauss/openGauss-server.git
opengauss
openGauss-server
openGauss-server

Search

233307 c1314fcc 1850385 233305 0212f5e2 1850385