最近新装的测试数据库需要做rman备份还原,将不同数据库实例名的备份还原到新的测试库中,顺便在新的库中设置rman备份脚本。
rman备份
关闭oracle闪回(fast_recovery_area)功能
由于在安装数据库的时候按照文档开启了闪回功能,会在rman备份时产生一些麻烦,了解了一下之后,最好是关闭闪回功能。
oracle默认将归档日志放到了闪回恢复区中,生产库上事物处理比较频繁的情况下,若是有个大的事物提交,并有频繁的日志切换的话,闪回恢复区设定的大小很快就会被用完。闪回恢复区的空间被占满了以后,很严重的后果就是,无法再归档了,整个数据库就会不可用,将直接影响生产系统的运行,直到你增大闪回恢复区或转移/删除闪回恢复区里的归档日志,清理出足够空间来继续进行归档为止。
检查是否开启闪回:
select flashback_on from v$database;
关闭闪回:
1
2
3
4
SQL> shutdown immediate;
SQL> startup mount;
SQL> alter database flashback off;
SQL> alter database open;
将数据库设置为归档模式
要使用rman进行联机备份,数据库必须处于归档模式,检查是否是归档模式
1
2
3
sqlplus /nolog
conn / as sysdba
SQL> archive log list;
修改为归档模式
1
2
3
4
5
SQL> shutdown immediate;
SQL> startup mount;
SQL> alter database archivelog;
SQL> archive log list;
SQL> alter database open;
图中的 USE_DB_RECOVERY_FILE_DESC
表示归档日志默认使用oracle闪回区,这是之前安装时选择闪回功能导致的,可以选择修改归档日志默认路径,然后重启数据库:
1
alter system set log_archive_dest_1='location=/data/oracle/product/11.2.0/dbhome_1/dbs/archlog';
配置rman备份参数
设置备份的并行级别,通道数
1
2
rman target /
RMAN> configure device type disk parallelism 1;
打开控制文件与服务器参数文件的自动备份
1
configure controlfile autobackup on;
启用备份优化
1
configure backup optimization on;
配置备份保留策略,这个参数看自己的需要设置
1
CONFIGURE RETENTION POLICY TO RECOVERY WINDOW OF 1 DAYS;
设置备份的文件路径和格式
1
CONFIGURE CHANNEL DEVICE TYPE DISK FORMAT '/data/orabak/%F';
以上参数的意思可以网上查询详细说明,根据自己的需要配置,配完参数之后可以 show all
查看刚刚修改过的参数,然后编写rman备份脚本:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#. /home/oracle/.bash_profile
#source 11.2.0.4 env
. /home/oracle/11g.env
TARGET_DIR=/data/orabak
export START_TIME=`date +"%Y%m%d-%H:%M:%S"`
export logfile=$TARGET_DIR/logfile_FINTEST_rman.log
export workdate=`date +"%Y%m%d"`
export begindate=`date +"%Y%m%d-%T"`
export agodate=`date -d "1 days ago" +%Y%m%d`
rman target / <<EOF
run {
crosscheck backup;
backup as compressed backupset database format='$TARGET_DIR/bf_%d_%T_%s_%p.db' filesperset=2;
sql 'alter system archive log current';
backup archivelog all format='$TARGET_DIR/arch_%d_%T_%s_%p.arc' delete all input;
DELETE ARCHIVELOG ALL COMPLETED BEFORE 'SYSDATE-2';
delete noprompt obsolete device type disk;
delete noprompt archivelog until time 'sysdate-1';
}
exit
EOF
if [ $? -eq 0 ]; then
echo $workdate' FINTEST数据库RMAN备份 '$begindate' '`date +"%Y%m%d-%T"`' success!' >> $logfile
rm -f /data/orabak/*$agodate*.arc
rm -f /data/orabak/*$agodate*.db
else
echo $workdate' FINTEST数据库RMAN备份 '$begindate' '`date +"%Y%m%d-%T"`' failed!' >> $logfile
fi
这个是每天全备一次的脚本,设定一个crontab任务就能每天定时备份了。
数据库恢复
rman的备份恢复到同实例名称的不同数据库很简单,网上资料也很多,此处不再重复写,此次主要写备份恢复到不同数据库实例名的操作,比如从生产库prod_db恢复到测试库test_db,网上的帖子比较乱,这里写一个可以实际操作的版本。
源数据库db_name和sid都为DMSTEST,新数据库db_name为FIN_TEST,sid为FINTEST
拷贝DMSTEST的数据库备份文件到FINTEST服务器的RMAN备份目录
拷贝所有备份文件到新服务,包括db文件,归档日志文件和控制文件,使用scp或者移动硬盘都可以,略。
修改初始化参数文件,修改数据库实例名
cd $ORACLE_HOME/dbs
找到initFINTEST.ora文件,如果目录下不存在这个文件,则去 /data/oracle/admin/FIN_TEST/pfile
目录下,会有一个init.ora.9112019164630文件,将此文件复制到$ORACLE_HOME/dbs目录,并修改名称为initFINTEST.ora
vi initFINTEST.ora 将db_name修改为DMSTEST
连接RMAN,读取控制文件
1
2
3
4
5
6
7
8
9
10
11
12
rman target /
RMAN> shutdown immediate;
RMAN> startup nomount;
# 从备份的控制文件中复制DBID
RMAN> set DBID= 4271865336;
RMAN> restore controlfile from '/data/orabak/c-4271865336-20191014-00';
# 如果执行此命令报数据库名称不对的错误,见文章最后解决方式
RMAN> alter database mount;
# 查看备份的文件
RMAN> list backup;
RMAN> catalog start with '/data/orabak/';
RMAN> list backup;
登录DMSTEST数据库,查询datafile的路径,并将路径替换成FIN_TEST的
1
2
3
4
SELECT 'set newname for datafile ' || file# || ' to ''' || REPLACE(NAME
,'/data/oracle/oradata/DMSTEST/'
,'/data/oracle/oradata/FIN_TEST/') || ''';'
FROM v$datafile;
将复制的内容替换如下脚本set newname部分:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
run{
allocate channel d1 device type disk;
allocate channel d2 device type disk;
allocate channel d3 device type disk;
allocate channel d4 device type disk;
set newname for datafile 1 to '/data/oracle/oradata/FIN_TEST/system01.dbf';
set newname for datafile 2 to '/data/oracle/oradata/FIN_TEST/sysaux01.dbf';
set newname for datafile 3 to '/data/oracle/oradata/FIN_TEST/undotbs01.dbf';
set newname for datafile 4 to '/data/oracle/oradata/FIN_TEST/users01.dbf';
set newname for datafile 5 to '/data/oracle/oradata/FIN_TEST/hdm_data01.dbf';
set newname for datafile 6 to '/data/oracle/oradata/FIN_TEST/fp_data.dbf';
set newname for datafile 7 to '/data/oracle/oradata/FIN_TEST/hdm2019_data01.dbf';
set newname for datafile 8 to '/data/oracle/oradata/FIN_TEST/FIN_PUB_DATA01.dbf';
restore database;
switch datafile all;
recover database;
}
在RMAN窗口中执行,如果报错:RMAN-06054: media recovery requesting unknown archived log for thread 1 with sequence 1055 and starting SCN of 6222833174894
则是恢复需要的日志记录在控制文件或恢复目录中找不到。解决方法分两种情况:
- 如果相关的日志存在且可用的话,就将此日志记录添加到控制文件或恢复目录中。
- 如果相关的日志已经被删除了或不可用了,那么就按照错误的提示scn将数据库恢复到此scn,本案例是6222833174894。也就是说此时数据库只能进行不完全恢复了,在打开数据库时得使用resetlogs打开。
此处只能采用第二种
recover database until scn 6222833174894;
修改logfile路径
在DMSTEST中查询logfile路径,并替换成新的路径
1
2
3
4
SELECT 'alter database rename file ''' || MEMBER || ''' to ''' || REPLACE(MEMBER
,'/data/oracle/oradata/DMSTEST/'
,'/data/oracle/oradata/FIN_TEST/') || ''';'
FROM v$logfile;
将结果复制出来到FIN_TEST的sqlplus下dba执行
1
2
3
alter database rename file '/data/oracle/oradata/DMSTEST/redo01.log' to '/data/oracle/oradata/FIN_TEST/redo01.log';
alter database rename file '/data/oracle/oradata/DMSTEST/redo02.log' to '/data/oracle/oradata/FIN_TEST/redo02.log';
alter database rename file '/data/oracle/oradata/DMSTEST/redo03.log' to '/data/oracle/oradata/FIN_TEST/redo03.log';
启动数据库
1
alter database open resetlogs;
生成控制文件的trace文件,并关闭数据库
这个文件可以自定义路径和名称,只是临时输出内容,方便后续复制里面的语句进行更改得到生成控制文件的脚本,使用完成后可以删除该文件。
1
2
3
alter database backup controlfile to trace as '/home/oracle/test.ora';
shutdown immediate;
修改初始化参数,将数据库名称改回FIN_TEST
vi initFINTEST.ora
重建控制文件
1
2
3
sqlplus /nolog
SQL> conn /as sysdba
SQL> startup nomount;
打开之前生成的test.ora文件,复制如下内容
修改为
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
-- 注意不只是修改路径和名称,CREATE后面的语句也发生了修改
CREATE CONTROLFILE SET DATABASE "FIN_TEST" RESETLOGS NOARCHIVELOG
MAXLOGFILES 16
MAXLOGMEMBERS 3
MAXDATAFILES 100
MAXINSTANCES 8
MAXLOGHISTORY 292
LOGFILE
GROUP 1 '/data/oracle/oradata/FIN_TEST/redo01.log' SIZE 1024M BLOCKSIZE 512,
GROUP 2 '/data/oracle/oradata/FIN_TEST/redo02.log' SIZE 1024M BLOCKSIZE 512,
GROUP 3 '/data/oracle/oradata/FIN_TEST/redo03.log' SIZE 1024M BLOCKSIZE 512
-- STANDBY LOGFILE
DATAFILE
'/data/oracle/oradata/FIN_TEST/system01.dbf',
'/data/oracle/oradata/FIN_TEST/sysaux01.dbf',
'/data/oracle/oradata/FIN_TEST/undotbs01.dbf',
'/data/oracle/oradata/FIN_TEST/users01.dbf',
'/data/oracle/oradata/FIN_TEST/hdm_data01.dbf',
'/data/oracle/oradata/FIN_TEST/fp_data.dbf',
'/data/oracle/oradata/FIN_TEST/hdm2019_data01.dbf',
'/data/oracle/oradata/FIN_TEST/FIN_PUB_DATA01.dbf'
CHARACTER SET AL32UTF8
在sqlplus中执行上面的脚本,可能会报错
1
2
3
4
5
6
ERROR at line 1:
ORA-01503: CREATE CONTROLFILE failed
ORA-00200: control file could not be created
ORA-00202: control file: '/data/oracle/oradata/FIN_TEST/control01.ctl'
ORA-27038: created file already exists
Additional information: 1
去 /data/oracle/oradata/FIN_TEST/ 目录删除所有control*.ctl文件,然后重新执行脚本,成功后会生成新的控制文件。
启动数据库
1
SQL> alter database open resetlogs;
修改临时表空间
去DMSTEST下查询临时表空间,并替换路径
1
2
3
4
select 'ALTER TABLESPACE ' || t.TABLESPACE_NAME || ' ADD TEMPFILE ''' ||
replace(t.FILE_NAME, '/data/oracle/oradata/DMSTEST/', '/data/oracle/oradata/FIN_TEST/') ||
''' size 2000M ;'
from dba_temp_files t;
复制所有结果到FIN_TEST的sqlplus中执行
1
ALTER TABLESPACE TEMP ADD TEMPFILE '/data/oracle/oradata/FIN_TEST/temp01.dbf' size 2000M ;
如果报错
1
2
ORA-01119: error in creating database file '/data/oracle/oradata/FIN_TEST/temp01.dbf'
ORA-27038: created file already exists
则去掉 size 2000M,重新执行修改路径。
1
ALTER TABLESPACE TEMP ADD TEMPFILE '/data/oracle/oradata/FIN_TEST/temp01.dbf';
此时数据恢复已完成,登录FIN_TEST数据库验证数据是否已完全恢复,如果数据没有问题,则需要再手动修改数据库为归档模式运行,因为前面重建控制文件时已经将数据库修改为非归档模式运行了。
以上就是rman恢复数据的全部过程。
解决数据库名称错误
如果在执行 alter database mount;
时报错:database name ‘DMSTEST’ in control file is not ‘FIN_TEST’
则需要修改数据库的启动参数文件,首先将数据库参数从 spfile 写到 pfile文件
1
2
-- 数据库必须是以spfile方式启动的,pfile路径和名称可以随意定义
create pfile='/home/oracle/pfile.11' from spfile;
打开刚刚生成的 pfile.11 文件,修改 db_name
停掉数据库,然后从 pfile 文件创建新的 spfile 文件,再启动 nomount
状态
1
2
3
shutdown immediate;
create spfile from pfile='/home/oracle/pfile.11';
startup nomount;
再次执行 alter database mount;
命令
此时数据库正常打开,然后可以继续之前的操作。但是在rman恢复后,除了修改 initFINTEST.ora
文件之外,还需要再次执行一遍修改spfile操作,将 db_name
修改回来。