感谢支持
我们一直在努力

Linux 平台下 RMAN 全备和增量备份 Shell 脚本

一. 一些准备知识


Oracle 分归档和非归档模式。 这两者的区别就是对redo log的处理。归档模式下,当一个redo log 写满之后,就会把这个redo log里的内容写入归档文件,等写完之后,这个redo log 就可以继续使用,如果是非归档模式下,redo log 就直接覆盖了。 恢复一般都需要归档文件,这里面记录了对数据库的操作,所以生产库一般都运行在归档模式下。 关于归档模式和非归档模式的切换参考Blog:


Oracle 归档与非归档的切换


http://www.linuxidc.com/Linux/2008-11/17203.htm


RMAN 备份的存放位置也有2种选择,一种是直接备份到磁盘,另一种就是备份到磁带。 现在的大公司,一般都使用Symnatec Veritas NetBackup 软件来进行备份。 这款软件扩展了RMAN的功能和优点,所有用起来比较方便。 08年刚工作的时候就遇到了一个安装NetBackup的实战机会,可惜那时刚接触Oracle,连Oracle 都不了解,更不提NetBackup了, 转眼2年过去了,在也没有遇到这样的机会,不知道什么时候才能玩玩NetBackup。 遗憾啊。


使用RMAN 备份也分catalog 和nocatalog,就是是否使用恢复目录,如果不使用恢复目录,那么就是用control file作为catalog,每一次备份都要往控制文件里面写好多备份信息,控制文件里面会有越来越多的备份信息。因此,当使用rman nocatalog方式备份时,备份controlfile是非常重要的。 如果使用catalog模式,就需要句需要创建catalog目录。 当库比较多时,使用catalog也是比较方便的。


RMAN的备份也分两种,一种是全备,另一种增量备份。 全备适用与数据库比较小的情况,如果库大的话就需要使用增量备份了,因为这样能减少备份的时间。


修改控制文件的保存时间,从默认的7天改成14天


SQL> show parameter control


SQL> alter system set control_file_record_keep_time=14 scope=both;


开启控制文件的自动备份,开启之后在数据库备份或者数据文件(比如添加数据文件)有修改的时候都会自动备份控制文件和spfile文件。


Configure controlfile autobackup on;


当数据库兼容性设置为大于等于10.0.0时,尽管在没有0级备份情况做1级的增量备份实际上是一个全备,但是这个全备也是1级的,不能用作1级积累增量备份的基础备份,这个是在设计备份策略的时候要注意的问题。


二. 全备脚本


以 nocatalog 模式为例:


Shell 脚本:


########################################################################


##   hot_database_backup.sh      ##


##   created by Tianlesoftware   ##


##        2010-7-16                 ##


#########################################################################


#!/bin/sh


# —————————————————————————


# Determine the user which is executing this script.


# —————————————————————————


CUSER=`id |cut -d”(” -f2 | cut -d “)” -f1`


# —————————————————————————


# Put output in <this file name>.out. Change as desired.


# Note: output directory requires write permission.


# —————————————————————————


RMAN_LOG_FILE=${0}.out


# —————————————————————————


# You may want to delete the output file so that backup information does


# not accumulate.  If not, delete the following lines.


# —————————————————————————


if [ -f “$RMAN_LOG_FILE” ]


then


rm -f “$RMAN_LOG_FILE”


fi


# —————————————————————–


# Initialize the log file.


# —————————————————————–


echo >> $RMAN_LOG_FILE


chmod 666 $RMAN_LOG_FILE


# —————————————————————————


# Log the start of this script.


# —————————————————————————


echo Script $0 >> $RMAN_LOG_FILE


echo ==== started on `date` ==== >> $RMAN_LOG_FILE


echo >> $RMAN_LOG_FILE


# —————————————————————————


# Oracle home path.


# —————————————————————————


ORACLE_HOME=/u01/app/oracle/product/10.2.0/db_1


export ORACLE_HOME


# —————————————————————————


# the Oracle SID of the target database.


# —————————————————————————


ORACLE_SID=orcl


export ORACLE_SID


# —————————————————————————


# The Oracle DBA user id (account).


# —————————————————————————


ORACLE_USER=oracle


export ORACLE_USER


# —————————————————————————


# Set the Oracle Recovery Manager name.


# —————————————————————————


RMAN=$ORACLE_HOME/bin/rman


# —————————————————————————


# Print out the value of the variables set by this script.


# —————————————————————————


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


# —————————————————————————


# Print out the value of the variables set by bphdb.


# —————————————————————————


#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: This script assumes that the database is properly opened. If desired,


# this would be the place to verify that.


# —————————————————————————


echo >> $RMAN_LOG_FILE


# —————————————————————————


# —————————————————————————


# Call Recovery Manager to initiate the backup.


# —————————————————————————


CMD_STR=”


ORACLE_HOME=$ORACLE_HOME


export ORACLE_HOME


ORACLE_SID=$ORACLE_SID


export ORACLE_SID


$RMAN nocatalog target sys/admin  msglog $RMAN_LOG_FILE append << EOF


RUN {


allocate channel c1 type disk;


allocate channel c2 type disk;


BACKUP FORMAT ‘/u01/backup/orcl_%U_%T’ skip inaccessible filesperset 5  DATABASE TAG orcl_hot_db_bk;


sql ‘alter system archive log current’;


BACKUP FORMAT ‘/u01/backup/arch_%U_%T’ skip inaccessible filesperset 5 ARCHIVELOG ALL DELETE INPUT;


backup current controlfile tag=’bak_ctlfile’ format=’/u01/backup/ctl_file_%U_%T’;


backup spfile tag=’spfile’ format=’/u01/backup/ORCL_spfile_%U_%T’;


release channel c2;


release channel c1;


}


report obsolete;


delete noprompt obsolete;


crosscheck backup;


delete noprompt expired backup;


list backup summary;


#EOF



# Initiate the command string


if [ “$CUSER” = “root” ]


then


echo “Root Command String: $CMD_STR” >> $RMAN_LOG_FILE


su – $ORACLE_USER -c “$CMD_STR” >> $RMAN_LOG_FILE


RSTAT=$?


else


echo “User Command String: $CMD_STR” >> $RMAN_LOG_FILE


/bin/sh -c “$CMD_STR” >> $RMAN_LOG_FILE


RSTAT=$?


fi


# —————————————————————————


# Log the completion of this script.


# —————————————————————————


if [ “$RSTAT” = “0” ]


then


LOGMSG=”ended successfully”


else


LOGMSG=”ended in error”


fi


echo >> $RMAN_LOG_FILE


echo Script $0 >> $RMAN_LOG_FILE


echo ==== $LOGMSG on `date` ==== >> $RMAN_LOG_FILE


echo >> $RMAN_LOG_FILE


/bin/mailx -s “RMAN Backup SID ” daimm@sf-express.com < $RMAN_LOG_FILE


exit $RSTAT

三. 增量备份


以catalog模式为例:


在存放catalog的实例上创建catalog 目录:


1.创建Catalog所需要的表空间


SQL>create tablespace catalog_ts datafile ‘D:\APP\ADMINISTRATOR\ORADATA\ORCL\catalog_ts1.dbf’  size 20M;


2.创建RMAN用户并授权


SQL>create user catalog identified by catalog default tablespace catalog_ts;


SQL>grant recovery_catalog_owner to catalog;


查看角色所拥有的权限:


select * from dba_sys_privs where grantee=’RECOVERY_CATALOG_OWNER’;


3.创建恢复目录


[Oracle@db1 scripts]$ rman target / catalog catalog/catalog@catalog1;


Recovery Manager: Release 10.2.0.1.0 – Production on Thu Jul 15 12:03:16 2010


Copyright (c) 1982, 2005, Oracle.  All rights reserved.


connected to target database: ORCL (DBID=1248423599)


connected to recovery catalog database


RMAN> create catalog tablespace catalog_ts;


recovery catalog created


如果此处报错:


ORACLE error from recovery catalog database: ORA-00955: name is already used by an existing object


可以用命令删除catalog,在创建:


RMAN> drop catalog;


recovery catalog owner is CATALOG


enter DROP CATALOG command again to confirm catalog removal


RMAN> drop catalog


recovery catalog dropped


RMAN> register database;


database registered in recovery catalog


starting full resync of recovery catalog


full resync complete


RMAN>


差异备份有3个级别:


0级:相当于全备,不同的是0级可用于增量备份,全备不行。


1级:备份自上次0级备份以来的数据


2级:备份自上次备份依赖的数据


脚本的增量备份策略: 周日0级备份,周四1级备份,其他2级备份


Shell 脚本:


########################################################################


##   incremental_hot_database_backup.sh      ##


##   created by Tianlesoftware            ##


##        2010-7-16                          ##


#########################################################################


#!/bin/ksh


export LANG=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


export ORACLE_HOME


RMAN=$ORACLE_HOME/bin/rman


export RMAN


ORACLE_SID=orcl


export ORACLE_SID


ORACLE_USER=oracle


export ORACLE_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 “BACKUP DATABASE BEGIN……”>>$RMAN_LOG_FILE


echo ”                   “>>$RMAN_LOG_FILE


chmod 666 $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


export BAK_LEVEL=$BAK_LEVEL


echo “Today is : $WEEK_DAILY  incremental level= $BAK_LEVEL”>>$RMAN_LOG_FILE


RUN_STR=”


BAK_LEVEL=$BAK_LEVEL


export BAK_LEVEL


ORACLE_HOME=$ORACLE_HOME


export ORACLE_HOME


ORACLE_SID=$ORACLE_SID


export ORACLE_SID


$RMAN TARGET sys/admin CATALOG catalog/catalog@catalog1  msglog $RMAN_LOG_FILE append <<EOF


run


{


allocate channel c1 type disk;


allocate channel c2 type disk;


backup  incremental level= $BAK_LEVEL  skip inaccessible filesperset 5 Database format=’/u01/backup/orcl_lev”$BAK_LEVEL”_%U_%T’  tag=’orcl_lev”$BAK_LEVEL”‘ ;


sql ‘alter system archive log current’;


backup archivelog all tag=’arc_bak’ format=’/u01/backup/arch_%U_%T’ skip inaccessible  filesperset 5 not  backed up 1 times  delete input;


backup current controlfile tag=’bak_ctlfile’ format=’/u01/backup/ctl_file_%U_%T’;


backup spfile tag=’spfile’ format=’/u01/backup/ORCL_spfile_%U_%T’;


release channel c2;


release channel c1;


}


report obsolete;


delete noprompt obsolete;


crosscheck backup;


delete noprompt expired backup;


list backup summary;


resync catalog;


EOF



# Initiate the command string


if [ “$CUSER” = “root” ]


then


echo “Root Command String: $RUN_STR” >> $RMAN_LOG_FILE


su – $ORACLE_USER -c “$RUN_STR” >> $RMAN_LOG_FILE


RSTAT=$?


else


echo “User Command String: $RUN_STR” >> $RMAN_LOG_FILE


/bin/sh -c “$RUN_STR” >> $RMAN_LOG_FILE


RSTAT=$?


fi


# —————————————————————————


# Log the completion of this script.


# —————————————————————————


if [ “$RSTAT” = “0” ]


then


LOGMSG=”ended successfully”


else


LOGMSG=”ended in error”


fi


echo >> $RMAN_LOG_FILE


echo Script $0 >> $RMAN_LOG_FILE


echo ==== $LOGMSG on `date` ==== >> $RMAN_LOG_FILE


echo >> $RMAN_LOG_FILE


/bin/mailx -s “RMAN Backup SID ” daimm@sf-express.com < $RMAN_LOG_FILE


exit $RSTAT


将该备份脚本添加到crontab, 然后定时执行:


[oracle@db1 u01]$ crontab -l


00 1 * * * /u01/scripts/incremental_hotbackup.sh


Linux计划任务crond命令用法


http://www.linuxidc.com/Linux/2009-01/17964.htm


在测试的时候,我们可以手工的修改,然后查看脚本的执行情况即可:


[root@db1 ~]# date –set “2010-7-16 11:11:11”


——————————补充————————–


用这个脚本的时候发现一个问题,备份集可以通过设定保存粗略定期删除,但是备份的归档文件无法删除。


所以还需要定期的删除备份的归档文件。 一般保存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 ,估计是和平台有关系。 我在调试的时候运行有错误,把这行注释掉就可以运行了。 所以如果相同错误的,可以考虑这种方法。没有更好。

赞(0) 打赏
转载请注明出处:服务器评测 » Linux 平台下 RMAN 全备和增量备份 Shell 脚本
分享到: 更多 (0)

听说打赏我的人,都进福布斯排行榜啦!

支付宝扫一扫打赏

微信扫一扫打赏