一.一些准备知识
Oracle分归档和非归档模式。这两者的区别就是对redolog的处理。归档模式下,当一个redolog写满之后,就会把这个redolog里的内容写入归档文件,等写完之后,这个redolog就可以继续使用,如果是非归档模式下,redolog就直接覆盖了。恢复一般都需要归档文件,这里面记录了对数据库的操作,所以生产库一般都运行在归档模式下。关于归档模式和非归档模式的切换参考Blog:
Oracle归档与非归档的切换
http://blog.csdn.net/tianlesoftware/archive/2009/10/19/4693470.aspx
RMAN备份的存放位置也有2种选择,一种是直接备份到磁盘,另一种就是备份到磁带。现在的大公司,一般都使用SymnatecVeritasNetBackup软件来进行备份。这款软件扩展了RMAN的功能和优点,所有用起来比较方便。08年刚工作的时候就遇到了一个安装NetBackup的实战机会,可惜那时刚接触Oracle,连Oracle都不了解,更不提NetBackup了,转眼2年过去了,在也没有遇到这样的机会,不知道什么时候才能玩玩NetBackup。遗憾啊。
使用RMAN备份也分catalog和nocatalog,就是是否使用恢复目录,如果不使用恢复目录,那么就是用controlfile作为catalog,每一次备份都要往控制文件里面写好多备份信息,控制文件里面会有越来越多的备份信息。因此,当使用rmannocatalog方式备份时,备份controlfile是非常重要的。如果使用catalog模式,就需要句需要创建catalog目录。当库比较多时,使用catalog也是比较方便的。具体参考:
RMANCatalog和Nocatalog的区别
http://blog.csdn.net/tianlesoftware/archive/2010/06/02/5641763.aspx
RMAN的备份也分两种,一种是全备,另一种增量备份。全备适用与数据库比较小的情况,如果库大的话就需要使用增量备份了,因为这样能减少备份的时间。Window下的备份脚本,参考Blog:
Windows下RMAN备份脚本
http://blog.csdn.net/tianlesoftware/archive/2010/01/13/5181414.aspx
关于控制文件对于RMAN的重要性,可以参考下面blog中的第四节:
RMAN系列(一)----RMAN体系结构概述
http://blog.csdn.net/tianlesoftware/archive/2010/06/09/5659701.aspx
修改控制文件的保存时间,从默认的7天改成14天
SQL>showparametercontrol
SQL>altersystemsetcontrol_file_record_keep_time=14scope=both;
开启控制文件的自动备份,开启之后在数据库备份或者数据文件(比如添加数据文件)有修改的时候都会自动备份控制文件和spfile文件。
Configurecontrolfileautobackupon;
二.全备脚本
以nocatalog模式为例:
Shell脚本:
########################################################################
##hot_database_backup.sh##
##createdbyTianlesoftware##
##2010-7-16##
#########################################################################
#!/bin/sh
#---------------------------------------------------------------------------
#Determinetheuserwhichisexecutingthisscript.
#---------------------------------------------------------------------------
CUSER=`id|cut-d"("-f2|cut-d")"-f1`
#---------------------------------------------------------------------------
#Putoutputin<thisfilename>.out.Changeasdesired.
#Note:outputdirectoryrequireswritepermission.
#---------------------------------------------------------------------------
RMAN_LOG_FILE=${0}.out
#---------------------------------------------------------------------------
#Youmaywanttodeletetheoutputfilesothatbackupinformationdoes
#notaccumulate.Ifnot,deletethefollowinglines.
#---------------------------------------------------------------------------
if[-f"$RMAN_LOG_FILE"]
then
rm-f"$RMAN_LOG_FILE"
fi
#-----------------------------------------------------------------
#Initializethelogfile.
#-----------------------------------------------------------------
echo>>$RMAN_LOG_FILE
chmod666$RMAN_LOG_FILE
#---------------------------------------------------------------------------
#Logthestartofthisscript.
#---------------------------------------------------------------------------
echoScript$0>>$RMAN_LOG_FILE
echo====startedon`date`====>>$RMAN_LOG_FILE
echo>>$RMAN_LOG_FILE
#---------------------------------------------------------------------------
#Oraclehomepath.
#---------------------------------------------------------------------------
ORACLE_HOME=/u01/app/oracle/product/10.2.0/db_1
exportORACLE_HOME
#---------------------------------------------------------------------------
#theOracleSIDofthetargetdatabase.
#---------------------------------------------------------------------------
ORACLE_SID=orcl
exportORACLE_SID
#---------------------------------------------------------------------------
#TheOracleDBAuserid(account).
#---------------------------------------------------------------------------
ORACLE_USER=oracle
exportORACLE_USER
#---------------------------------------------------------------------------
#SettheOracleRecoveryManagername.
#---------------------------------------------------------------------------
RMAN=$ORACLE_HOME/bin/rman
#---------------------------------------------------------------------------
#Printoutthevalueofthevariablessetbythisscript.
#---------------------------------------------------------------------------
echo>>$RMAN_LOG_FILE
echo"RMAN:$RMAN">>$RMAN_LOG_FILE
echo"ORACLE_SID:$ORACLE_SID">>$RMAN_LOG_FILE
echo"ORACLE_USER:$ORACLE_USER">>$RMAN_LOG_FILE
echo"ORACLE_HOME:$ORACLE_HOME">>$RMAN_LOG_FILE
#---------------------------------------------------------------------------
#Printoutthevalueofthevariablessetbybphdb.
#---------------------------------------------------------------------------
#echo>>$RMAN_LOG_FILE
#echo"NB_ORA_FULL:$NB_ORA_FULL">>$RMAN_LOG_FILE
#echo"NB_ORA_INCR:$NB_ORA_INCR">>$RMAN_LOG_FILE
#echo"NB_ORA_CINC:$NB_ORA_CINC">>$RMAN_LOG_FILE
#echo"NB_ORA_SERV:$NB_ORA_SERV">>$RMAN_LOG_FILE
#echo"NB_ORA_POLICY:$NB_ORA_POLICY">>$RMAN_LOG_FILE
#---------------------------------------------------------------------------
#NOTE:Thisscriptassumesthatthedatabaseisproperlyopened.Ifdesired,
#thiswouldbetheplacetoverifythat.
#---------------------------------------------------------------------------
echo>>$RMAN_LOG_FILE
#---------------------------------------------------------------------------
#---------------------------------------------------------------------------
#CallRecoveryManagertoinitiatethebackup.
#---------------------------------------------------------------------------
CMD_STR="
ORACLE_HOME=$ORACLE_HOME
exportORACLE_HOME
ORACLE_SID=$ORACLE_SID
exportORACLE_SID
$RMANnocatalogtargetsys/adminmsglog$RMAN_LOG_FILEappend<<EOF
RUN{
allocatechannelc1typedisk;
allocatechannelc2typedisk;
BACKUPFORMAT'/u01/backup/orcl_%U_%T'skipinaccessiblefilesperset5 DATABASETAGorcl_hot_db_bk;
sql'altersystemarchivelogcurrent';
BACKUPFORMAT'/u01/backup/arch_%U_%T'skipinaccessiblefilesperset5ARCHIVELOGALLDELETEINPUT;
backupcurrentcontrolfiletag='bak_ctlfile'format='/u01/backup/ctl_file_%U_%T';
backupspfiletag='spfile'format='/u01/backup/ORCL_spfile_%U_%T';
releasechannelc2;
releasechannelc1;
}
reportobsolete;
deletenopromptobsolete;
crosscheckbackup;
deletenopromptexpiredbackup;
listbackupsummary;
#EOF
"
#Initiatethecommandstring
if["$CUSER"="root"]
then
echo"RootCommandString:$CMD_STR">>$RMAN_LOG_FILE
su-$ORACLE_USER-c"$CMD_STR">>$RMAN_LOG_FILE
RSTAT=$?
else
echo"UserCommandString:$CMD_STR">>$RMAN_LOG_FILE
/bin/sh-c"$CMD_STR">>$RMAN_LOG_FILE
RSTAT=$?
fi
#---------------------------------------------------------------------------
#Logthecompletionofthisscript.
#---------------------------------------------------------------------------
if["$RSTAT"="0"]
then
LOGMSG="endedsuccessfully"
else
LOGMSG="endedinerror"
fi
echo>>$RMAN_LOG_FILE
echoScript$0>>$RMAN_LOG_FILE
echo====$LOGMSGon`date`====>>$RMAN_LOG_FILE
echo>>$RMAN_LOG_FILE
/bin/mailx-s"RMANBackupSID"[email protected]<$RMAN_LOG_FILE
exit$RSTAT
三.增量备份
以catalog模式为例:
在存放catalog的实例上创建catalog目录:
1.创建Catalog所需要的表空间
SQL>createtablespacecatalog_tsdatafile'D:/APP/ADMINISTRATOR/ORADATA/ORCL/catalog_ts1.dbf'size20M;
2.创建RMAN用户并授权
SQL>createusercatalogidentifiedbycatalogdefaulttablespacecatalog_ts;
SQL>grantrecovery_catalog_ownertocatalog;
查看角色所拥有的权限:
select*fromdba_sys_privswheregrantee='RECOVERY_CATALOG_OWNER';
3.创建恢复目录
[oracle@db1scripts]$rmantarget/catalogcatalog/catalog@catalog1;
RecoveryManager:Release10.2.0.1.0-ProductiononThuJul1512:03:162010
Copyright(c)1982,2005,Oracle.Allrightsreserved.
connectedtotargetdatabase:ORCL(DBID=1248423599)
connectedtorecoverycatalogdatabase
RMAN>createcatalogtablespacecatalog_ts;
recoverycatalogcreated
如果此处报错:
ORACLEerrorfromrecoverycatalogdatabase:ORA-00955:nameisalreadyusedbyanexistingobject
可以用命令删除catalog,在创建:
RMAN>dropcatalog;
recoverycatalogownerisCATALOG
enterDROPCATALOGcommandagaintoconfirmcatalogremoval
RMAN>dropcatalog
recoverycatalogdropped
RMAN>registerdatabase;
databaseregisteredinrecoverycatalog
startingfullresyncofrecoverycatalog
fullresynccomplete
RMAN>
差异备份有3个级别:
0级:相当于全备,不同的是0级可用于增量备份,全备不行。
1级:备份自上次0级备份以来的数据
2级:备份自上次备份依赖的数据
脚本的增量备份策略:周日0级备份,周四1级备份,其他2级备份
Shell脚本:
########################################################################
##incremental_hot_database_backup.sh##
##createdbyTianlesoftware##
##2010-7-16##
#########################################################################
#!/bin/ksh
exportLANG=en_US
BACKUP_DATE=`date+%d`
RMAN_LOG_FILE=${0}.out
TODAY=`date`
USER=`id|cut-d"("-f2|cut-d")"-f1`
echo"-----------------$TODAY-------------------">$RMAN_LOG_FILE
ORACLE_HOME=/u01/app/oracle/product/10.2.0/db_1
exportORACLE_HOME
RMAN=$ORACLE_HOME/bin/rman
exportRMAN
ORACLE_SID=orcl
exportORACLE_SID
ORACLE_USER=oracle
exportORACLE_USER
echo"ORACLE_SID:$ORACLE_SID">>$RMAN_LOG_FILE
echo"ORACLE_HOME:$ORACLE_HOME">>$RMAN_LOG_FILE
echo"ORACLE_USER:$ORACLE_USER">>$RMAN_LOG_FILE
echo"==========================================">>$RMAN_LOG_FILE
echo"BACKUPDATABASEBEGIN......">>$RMAN_LOG_FILE
echo"">>$RMAN_LOG_FILE
chmod666$RMAN_LOG_FILE
WEEK_DAILY=`date+%a`
case"$WEEK_DAILY"in
"Mon")
BAK_LEVEL=2
;;
"Tue")
BAK_LEVEL=2
;;
"Wed")
BAK_LEVEL=2
;;
"Thu")
BAK_LEVEL=1
;;
"Fri")
BAK_LEVEL=2
;;
"Sat")
BAK_LEVEL=2
;;
"Sun")
BAK_LEVEL=0
;;
"*")
BAK_LEVEL=error
esac
exportBAK_LEVEL=$BAK_LEVEL
echo"Todayis:$WEEK_DAILYincrementallevel=$BAK_LEVEL">>$RMAN_LOG_FILE
RUN_STR="
BAK_LEVEL=$BAK_LEVEL
exportBAK_LEVEL
ORACLE_HOME=$ORACLE_HOME
exportORACLE_HOME
ORACLE_SID=$ORACLE_SID
exportORACLE_SID
$RMANTARGETsys/adminCATALOGcatalog/catalog@catalog1msglog$RMAN_LOG_FILEappend<<EOF
run
{
allocatechannelc1typedisk;
allocatechannelc2typedisk;
backupincrementallevel=$BAK_LEVELskipinaccessiblefilesperset5Databaseformat='/u01/backup/orcl_lev"$BAK_LEVEL"_%U_%T'tag='orcl_lev"$BAK_LEVEL"';
sql'altersystemarchivelogcurrent';
backuparchivelogalltag='arc_bak'format='/u01/backup/arch_%U_%T'skipinaccessiblefilesperset5notbackedup1timesdeleteinput;
backupcurrentcontrolfiletag='bak_ctlfile'format='/u01/backup/ctl_file_%U_%T';
backupspfiletag='spfile'format='/u01/backup/ORCL_spfile_%U_%T';
releasechannelc2;
releasechannelc1;
}
reportobsolete;
deletenopromptobsolete;
crosscheckbackup;
deletenopromptexpiredbackup;
listbackupsummary;
resynccatalog;
EOF
"
#Initiatethecommandstring
if["$CUSER"="root"]
then
echo"RootCommandString:$RUN_STR">>$RMAN_LOG_FILE
su-$ORACLE_USER-c"$RUN_STR">>$RMAN_LOG_FILE
RSTAT=$?
else
echo"UserCommandString:$RUN_STR">>$RMAN_LOG_FILE
/bin/sh-c"$RUN_STR">>$RMAN_LOG_FILE
RSTAT=$?
fi
#---------------------------------------------------------------------------
#Logthecompletionofthisscript.
#---------------------------------------------------------------------------
if["$RSTAT"="0"]
then
LOGMSG="endedsuccessfully"
else
LOGMSG="endedinerror"
fi
echo>>$RMAN_LOG_FILE
echoScript$0>>$RMAN_LOG_FILE
echo====$LOGMSGon`date`====>>$RMAN_LOG_FILE
echo>>$RMAN_LOG_FILE
/bin/mailx-s"RMANBackupSID"[email protected]<$RMAN_LOG_FILE
exit$RSTAT
将该备份脚本添加到crontab,然后定时执行:
[oracle@db1u01]$crontab-l
001***/u01/scripts/incremental_hotbackup.sh
Unixcrontab命令详解
http://blog.csdn.net/tianlesoftware/archive/2010/02/22/5315039.aspx
在测试的时候,我们可以手工的修改,然后查看脚本的执行情况即可:
[root@db1~]#date--set"2010-7-1611:11:11"
------------------------------2010年8月23日补充--------------------------
用这个脚本的时候发现一个问题,备份集可以通过设定保存粗略定期删除,但是备份的归档文件无法删除。
所以还需要定期的删除备份的归档文件。 一般保存15天。 shell 脚本如下。添加到crontab 里定时执行就可以了。
del_archive_backup.sh
#!/bin/ksh
# ##################################################################
#
# delete archvivelog backup file.sh
# tianlesoftware
#
# ##################################################################
PATH=/usr/bin:/usr/ucb:/etc:.:/usr/X/bin:/bin
export PATH
find /u01/incremental_hotbackup -mtime +15 -name "arch_*" -exec rm {} /;
说明,这里的路径写你自己的就可以了。
感谢jonkingwar,你说的地方已经修改,至于#EOF ,估计是和平台有关系。 我在调试的时候运行有错误,把这行注释掉就可以运行了。 所以如果相同错误的,可以考虑这种方法。没有更好。
------------------------------------------------------------------------------
Blog:http://blog.csdn.net/tianlesoftware
网上资源:http://tianlesoftware.download.csdn.net
相关视频:http://blog.csdn.net/tianlesoftware/archive/2009/11/27/4886500.aspx
DBA1群:62697716(满);DBA2群:62697977
DBA3群:63306533;聊天群:40132017
<!--EndFragment-->