Oracle19c 如何用rman duplicate 克隆一个数据库。(Backup-Based, achive log)

Oracle19c 如何用rman duplicate 克隆一个数据库。(Backup-Based, achive log)

首先克隆有两种方法,一种是Backup-Based,一种是Active方式。官网文档链接
https://docs.oracle.com/database/121/BRADV/rcmdupdb.htm#BRADV010

在这里我用的是Backup-based方式。这一次我的操作是开启归档日志的情况下进行克隆。


前言,在开始归档日志的时候,我在源机器没有进行业务操作(即没有数据更新)的情况下简单的进行备份恢复。
但很遗憾,RMAN最后会因为没有归档日志而报错(没有数据,就没有REDO,也无所谓归档了)。

RMAN-05541: no archived logs found in target database
Problem:
You are getting RMAN-05541 error when duplicating database from a consistent (cold) RMAN backup.

解决方案可以再上NOREDO,但这不是我想要测试的结果。
Example:
DUPLICATE DATABASE TO targetDB
BACKUP LOCATION '/backup_Location' NOREDO;


好了,闲话少说,步入正题。


步骤如下:
我用的机器oracle19c源库(IP:192.168.56.110),oracle19c-toclone目标库(192.168.56.111)
1)在目标库用DBCA创建一个空的database,实例名为newdb(非容器)。
因为我的源库是有HR DATABASE的,你的空库可以不安装HR,这样克隆后也好比较。

2) 配置host和监听
Backup-based方式可以不配置静态监听,因为文件都是用FTP或SCP方式直接传输的。恢复过程中不需要连接源库。
所以,在Backup-based方式下第2步可以完全忽略。

3)复制前的准备工作
3.1)在源库,编辑pfile文件(这个initorcl.ora实际上就是默认生成的pfile)
(如果文件没有的话,你可以在源库database open的情况下,执行create pfile from memory创建一个。注:还有其它方法)
[oracle@oracle19c dbs]$ pwd
/u01/app/oracle/product/19c/db_1/dbs

做如下修改,修改control_files路径为新的实例, db_name。
还有最重要的是db_file_name_convert,log_file_name_convert。
因为源库和目标库的实例名不同(如果完全一样,应该不用加convert呢),所以需要转换。
注意:与前面语句略有不同,还增加了归档日志的转换目录
*.control_files='/u01/app/oracle/oradata/NEWDB/control01.ctl'#Restore Controlfile
*.db_name='newdb'
*.db_recovery_file_dest_size=5368709120
*.db_recovery_file_dest='/u01/app/oracle/fra'
*.db_file_name_convert='/u01/app/oracle/oradata/ORCL','/u01/app/oracle/oradata/NEWDB/'
*.log_file_name_convert='/u01/app/oracle/oradata/ORCL','/u01/app/oracle/oradata/NEWDB','/u01/app/oracle/oradata/ORCL/arch','/u01/app/oracle/oradata/NEWDB/arch'

3.2)复制密码文件,和spfile到目标库
scp initorcl.ora 192.168.56.111:/u01/app/oracle/product/19c/db_1/dbs/initnewdb.ora
scp orapworcl 192.168.56.111:/u01/app/oracle/product/19c/db_1/dbs/orapwnewdb

3.3)在源库生成一个备份,并复制到目标机器。
3.3.1)源库直接正常启动数据库
(在打开归档模式下,是可以在OPEN状态下进行备份的)
SQL>startup

你可以先检查一下,你的归档日志是否打开?如果没有在sqlplus下进行如下操作打开
SQL> archive log list;
Database log mode No Archive Mode
Automatic archival Disabled
Archive destination USE_DB_RECOVERY_FILE_DEST
Oldest online log sequence 2
Current log sequence 4

SQL>alter system set log_archive_dest_1='location=/u01/app/oracle/oradata/ORCL/arch' scope=spfile;
SQL>shutdown immediate
SQL>startup mount;
SQL>alter database archivelog;
SQL>alter database open;

3.3.2)前言我提到了,因为没有数据变化,所有没有产生归档。那我们就自己动手,产生一些数据吧。
这里我写了一个简单脚本,可循环插入数据。
[oracle@oracle19c ~]$ cat insert-500.sh
#!/bin/sh
sqlplus -S / as sysdba << EOF
drop table t1;
create table t1 as select * from dba_objects;
exit
EOF

for((i=1;i<=500;i++));
do
sqlplus -S / as sysdba << EOF
insert into t1 ( select * from dba_objects);
commit;
exit
EOF
done

#赋予所有用户执行权限,执行
[oracle@oracle19c ~]$ chmod a+x insert-500.sh
[oracle@oracle19c ~]$ ./insert-500.sh
Table dropped.
Table created.
72901 rows created.

3.3.2)用rman备份

[oracle@oracle19c full]$ rman target /

RMAN> backup database include current controlfile format '/full/full_%d_%s_%T_%p.bak';
备份成功后,最后会还会备份控制文件,控制文件也需要COPY到目标机器。
Starting Control File and SPFILE Autobackup at 04-JUN-21
piece handle=/u01/app/oracle/fra/ORCL/autobackup/2021_06_04/o1_mf_s_1074316419_jcmvtwog_.bkp comment=NONE
Finished Control File and SPFILE Autobackup at 04-JUN-21
---最新说明,控制文件的备份可以不用单独复制到目标机器。因为上面的语句(include current controlfile),实际上备份已经包含了控制文件了。

备份归档日志
RMAN> BACKUP ARCHIVELOG ALL FORMAT '/full/arch/ar_%t_%s_%p'

3.3.3)把数据文件和归档日志的备份都copy到目标机器 /home/oracle/bak目录,此目录是你到时进行克隆恢复时指定的目录

因为我的RMAN这里配置为3个并发,所以生成了3个文件。(是不是感觉前面所学的知识都结合起来了啊?:-)
RMAN>SHOW ALL
CONFIGURE DEVICE TYPE DISK PARALLELISM 3 BACKUP TYPE TO BACKUPSET;

[oracle@oracle19c full]$ scp /full/full_ORCL_* 192.168.56.111:/home/oracle/bak
oracle@192.168.56.111's password:
full_ORCL_183_20210604_1.bak 100% 807MB 30.7MB/s 00:26
full_ORCL_184_20210604_1.bak 100% 616MB 26.9MB/s 00:22
full_ORCL_185_20210604_1.bak 100% 10MB 21.3MB/s 00:00
[oracle@oracle19c arch]$ scp /full/arch/ar* 192.168.56.111:/home/oracle/bak
oracle@192.168.56.111's password:
1_75_1073900400.dbf 100% 4801KB 56.4MB/s 00:00
1_76_1073900400.dbf 100% 197MB 39.4MB/s 00:05
1_77_1073900400.dbf 100% 182MB 36.2MB/s 00:05
1_78_1073900400.dbf 100% 183MB 35.0MB/s 00:05
1_79_1073900400.dbf 100% 194MB 32.1MB/s 00:06
1_80_1073900400.dbf 100% 176MB 34.9MB/s 00:05


4)用pfile启动目标库
(目标库需要在NOMOUNT方式下进行克隆。)
startup nomount pfile='/u01/app/oracle/product/19c/db_1/dbs/initnewdb.ora';


5)连接RMAN进行复制
5.1)连接anxiliary(目标库)
注意,这里只需连接目标库就可以了,因为所需文件前面已经全部COPY过来了。
[oracle@oracle19c-toclone ~]$ rman auxiliary /


5.2)执行RMAN复制命令(可以仔细查看一下与Active方式命令的不同)
nofilenamecheck参数表示复制过去,文件是用同样的名字。如果不加,会报错。

RMAN> duplicate database to newdb backup location '/home/oracle/bak' nofilenamecheck;
Starting Duplicate Db at 04-JUN-21

RMAN的恢复过程解释:

第1步,先恢复控制文件,如下可以看到是从全量备份里面提取出来的
contents of Memory Script:
{
restore clone primary controlfile from '/home/oracle/bak/full_ORCL_206_20210604_1.bak';
}

channel ORA_AUX_DISK_1: restoring control file
channel ORA_AUX_DISK_1: restore complete, elapsed time: 00:00:00
output file name=/u01/app/oracle/oradata/NEWDB/control01.ctl

第2步,恢复表空间(即数据文件)
contents of Memory Script:
{
set until scn 3887310;
set newname for datafile 1 to
"/u01/app/oracle/oradata/NEWDB//system01.dbf";
set newname for datafile 3 to
"/u01/app/oracle/oradata/NEWDB//sysaux01.dbf";
set newname for datafile 4 to
"/u01/app/oracle/oradata/NEWDB//undotbs01.dbf";
set newname for datafile 7 to
"/u01/app/oracle/oradata/NEWDB//users01.dbf";
restore
clone database
;
}

第3步,就是所谓media recovery了。即通过归档日志进行数据推进。
starting media recovery

channel ORA_AUX_DISK_1: starting archived log restore to default destination
channel ORA_AUX_DISK_1: restoring archived log
archived log thread=1 sequence=85
channel ORA_AUX_DISK_1: reading from backup piece /home/oracle/bak/ar_1074378119_210_1
channel ORA_AUX_DISK_1: piece handle=/home/oracle/bak/ar_1074378119_210_1 tag=TAG20210604T222155
channel ORA_AUX_DISK_1: restored backup piece 1
channel ORA_AUX_DISK_1: restore complete, elapsed time: 00:00:09
archived log file name=/u01/app/oracle/oradata/NEWDB/arch/1_85_1073900400.dbf thread=1 sequence=85
channel clone_default: deleting archived log(s)
archived log file name=/u01/app/oracle/oradata/NEWDB/arch/1_85_1073900400.dbf RECID=1 STAMP=1074380003

最后成功会显示
database opened
Cannot remove created server parameter file
Finished Duplicate Db at 04-JUN-21


6)检查目标库,及后续工作
RMAN复制完后,会自动OPEN目标库。此时,你可以用sqlplus重新连接。
[oracle@oracle19c-toclone admin]$ sqlplus / as sysdba
SQL> select status from v$instance;

STATUS
------------
OPEN

SQL> select count(*) from hr.employees;

COUNT(*)
----------
107


6.2)最后,你可以在目标库手动删除pfile里面的convert行。再用pfile启动。
启动完后(create spfile from memory),生成spfile。
下次正常启动,你就不再需要pfile了。

 

总结,归档日志开启与不开启对于ORACLE数据库的影响与不同?
先问题自己几个问题。
1)什么是REDO日志,它的作用是什么?为何REDO至少需要2个日志组?
2)为何需要归档日志?
3)为何未开启归档,只能是MOUNT方式下进行全量备份?
而开启了归档,就可以在OPEN状态下备份?
4)为何RMAN duplicate恢复时,一定需要归档日志?


redo是进行数据库恢复所用的(异常掉电,可以用redo恢复)。
但是REDO是一个循环使用的,也即随时时间的推移,前面的数据可能被覆盖。
简单来说两个文件可以在一个写满后,写下一个,再直接TRUNCATE第一个文件。
归档日志在REDO未被覆盖前,进行保存,这样你就相当于有了所有的REDO日志。

现实情况数据库只要服务在,会一直有业务数据更新。
没有归档,数据一致性无法保证。所以MOUNT下(应用无法连接),可保证数据一致性。
有了归档,虽然备份数据文件开始后,还会一直有数据更新。
但archive log可以在备份完成后,再应用重做,从而实现一个一致性的数据备份。
这也是为何RMAN duplicate恢复时,一定需要归档日志的原因了。

 

posted @ 2021-07-12 23:25  老杨伏枥  阅读(1134)  评论(0编辑  收藏  举报