Chinaunix首页 | 论坛 | 博客
  • 博客访问: 10222510
  • 博文数量: 1669
  • 博客积分: 16831
  • 博客等级: 上将
  • 技术积分: 12594
  • 用 户 组: 普通用户
  • 注册时间: 2011-02-25 07:23
个人简介

柔中带刚,刚中带柔,淫荡中富含柔和,刚猛中荡漾风骚,无坚不摧,无孔不入!

文章分类

全部博文(1669)

文章存档

2023年(4)

2022年(1)

2021年(10)

2020年(24)

2019年(4)

2018年(19)

2017年(66)

2016年(60)

2015年(49)

2014年(201)

2013年(221)

2012年(638)

2011年(372)

分类: Oracle

2012-01-30 17:49:19

Linux 平台下 RMAN 全备和增量备份 Shell 脚本
[日期:2011-02-26] 来源:Linux社区  作者:Linux
 
全备份
 
RMAN> run {
2> allocate channel d1 type disk maxpiecesize=1g;
3> backup full database
4> format '/home/oracle/rman/db_%d_%s_%p_%t' tag='test';
5> sql 'alter system archive log current';
6> backup archivelog all delete input;
7> release channel d1;
8> }
 
简化的备份恢复

一.备份所有归档日志文件
RMAN> backup archivelog all delete input;
二: restore archivelog 的各种选项
恢复全部归档日志文件
RMAN> restore archivelog all;
只恢复5到8这四个归档日志文件
RMAN> restore archivelog from logseq 5 until logseq 8;
恢复从第5个归档日志起
RMAN> restore archivelog from logseq 5;
恢复7天内的归档日志
RMAN> restore archivelog from time 'sysdate-7';
sequence between 写法
RMAN> restore archivelog sequence between 1 and 3;
恢复到哪个日志文件为止
RMAN> restore archivelog until logseq 3;
从第五个日志开始恢复
RMAN> restore archivelog low logseq 5;
到第5个日志为止
RMAN> restore archivelog high logseq 5;
三:如果想改变恢复到另外路径下 则可用下面语句
set archivelog destination to 'd:\backup';
   RMAN> run
   2> {allocate channel ci type disk;
   3> set archivelog destination to 'd:\backup';
   4> restore archivelog all;
   5> release channel ci;
   6> }


一. 一些准备知识

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

Oracle 归档与非归档的切换
 
 
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 .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 " < $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 ;
 
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   msglog $RMAN_LOG_FILE append <
 
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 " < $RMAN_LOG_FILE
 
exit $RSTAT
 
将该备份脚本添加到crontab, 然后定时执行:
 
[oracle@db1 u01]$ crontab -l
 
00 1 * * * /u01/scripts/incremental_hotbackup.sh
 
Linux计划任务crond命令用法
 
 
在测试的时候,我们可以手工的修改,然后查看脚本的执行情况即可:
 
[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 ,估计是和平台有关系。 我在调试的时候运行有错误,把这行注释掉就可以运行了。 所以如果相同错误的,可以考虑这种方法。没有更好。
阅读(1475) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~