oracle rman 定時備份指令碼

315959312發表於2014-03-20
近期需要出個oracle定時備份的方案,可以恢復到最新狀態,參考http://blog.sina.com.cn/s/blog_7756ebc30100tnqy.html,我又在shell中加工了一下,弄了2個shell指令碼,init.sh, oraclebackup.sh,執行init.sh  param1(備份檔案路徑) param2(歸檔日誌路徑),就可以設定定時備份了,指令碼會設定定時器,詳細內容參見init.sh檔案的開頭說明,下面貼出指令碼程式碼:
init.sh

#!/bin/sh
# oracle自動定時備份程式
#說明:init.sh 和 oraclebackup.sh是oracle自動定時備份的2個shell指令碼。
# 備份工具:RMAN
# 備份方式:增量備份
# 歸檔模式:是
# 使用示例: ./init.sh /home/dev/databasebackup /home/dev/archivelogbackup
# 第一個引數是oracle備份檔案的儲存目錄,第二個引數是歸檔重做日誌的儲存目錄
# 每次備份資料庫時也會備份歸檔重做日誌,然後刪除歸檔重做日誌
# 這2個指令碼需要放到oracle伺服器
# 環境變數中需要提前配置好ORACLE_BASE,ORACLE_HOME,ORACLE_SID
# 安裝後的oracle預設是非歸檔模式
# init.sh指令碼執行過程中需要重啟資料庫
#init.sh指令碼執行流程:
# 1.將2個目錄引數替換到oraclebackup.sh
# 2.將ORACLE_BASE,ORACLE_HOME,ORACLE_SID這3個環境變數替換到oraclebackup.sh
# 3.配置RMAN
# 4.將oracle設定為歸檔模式
# 5.生成定時器檔案
# 6.設定定時器,定時對oracle進行備份,備份檔案預設儲存15天
# 每週日1:00執行0級備份
# 每週一至週三,週五至週六1:00執行2級增量備份
# 每週四1:00執行1級增量備份
# 每週六16:00執行檢測
# 每週日18:00刪除過期的備份資料
#
# 執行完init.sh後,也可以進行手動備份和恢復資料庫
# 進行0級備份:
# oraclebackup.sh -l0  
# 進行1級備份
# oraclebackup.sh -l1  
# 進行2級備份
# oraclebackup.sh -l2 
# 檢測備份完整性
# oraclebackup.sh -c
# 刪除過期的備份,預設儲存15天
# oraclebackup.sh -d
# 恢復資料庫到最新狀態
# oraclebackup.sh -r
#日誌:
# 指令碼執行的log在第一個引數(/home/dev/databasebackup)的rmanlog目錄下,即/home/dev/databasebackup/rmanlog,
# 可以定期檢查這個資料夾下面的log,檢視備份資訊




DATABASE_PATH=""
ARCHIVELOG_PATH=""
ORACLE_BASE_VAL=""
ORACLE_HOME_VAL=""
ORACLE_SID_VAL=""


KEY1="DATABASE_PATH"
KEY2="ARCHIVELOG_PATH"
KEY3="export ORACLE_BASE"
KEY4="export ORACLE_HOME"
KEY5="export ORACLE_SID"


#配置RMAN,備份保留15天,優化備份,自動備份控制檔案,控制檔案的備份位置
TEMPLATE_RMANCMD="connect target /;
        run {
CONFIGURE RETENTION POLICY TO RECOVERY WINDOW OF 15 DAYS;
CONFIGURE BACKUP OPTIMIZATION ON;
CONFIGURE CONTROLFILE AUTOBACKUP ON;
CONFIGURE CONTROLFILE AUTOBACKUP FORMAT FOR DEVICE TYPE DISK TO 'oldpath_database/controlfile_backup/controlfile_%F';
}"

RMANCMD=""


#替換RMAN命令中的路徑引數
function replaceRmanCMD()
{
RMANCMD=`echo ${TEMPLATE_RMANCMD} | sed -n "s#oldpath_database#${DATABASE_PATH}#p"`

echo "==================RMANCMD======================"
echo ${RMANCMD}
echo "==============================================="
}


#執行RMAN命令,配置RMAN
function setRmanConf()
{
rman log=\'${DATABASE_PATH}/rmanlog/paidb_rman_conf.log\' append <     ${RMANCMD}
EOF
}


#把oracle設定為歸檔模式
function setArchiveLog()
{
sqlplus / as sysdba < shutdown immediate;
startup mount;
alter database archivelog;
alter system set control_file_record_keep_time=30 scope=both;
alter system set log_archive_dest_1='location=${ARCHIVELOG_PATH}/archivelog' scope=both;
alter database open;
alter system archive log start;
exit; 
EOF
}


#建立定時器檔案crontabfile,設定定時器
#每週日1:00執行0級備份
#每週一至週三,週五至週六1:00執行2級增量備份
#每週四1:00執行1級增量備份
#每週六16:00執行檢測
#每週日18:00刪除過期的備份資料
function setCrontab()
{
if [ -e ./crontabfile ]
then
rm ./crontabfile
fi

touch ./crontabfile

chmod 777 ./crontabfile

#每週日1:00執行0級備份
echo "0 1 * * 0 `pwd`/oraclebackup.sh -l0" >> crontabfile

#每週一至週三,週五至週六1:00執行2級增量備份
echo "0 1 * * 1-3,5-6 `pwd`/oraclebackup.sh -l2" >> crontabfile

#每週四1:00執行1級增量備份
echo "0 1 * * 4 `pwd`/oraclebackup.sh -l1" >> crontabfile

#每週六16:00執行檢測
echo "0 18 * * 6 `pwd`/oraclebackup.sh -c" >> crontabfile

#每週日18:00刪除過期的備份資料
echo "0 18 * * 0 `pwd`/oraclebackup.sh -d" >> crontabfile

crontab ./crontabfile
}


#建立子目錄,歸檔日誌目錄下建立archivelog
#資料庫備份目錄下建立rmanlog,controlfile_backup,database_backup目錄
#如果已經存在,則不建立
function makeSubDir()
{
if [ ! -d "${ARCHIVELOG_PATH}/archivelog" ]
then
mkdir ${ARCHIVELOG_PATH}/archivelog
fi

if [ ! -d "${ARCHIVELOG_PATH}/rmanlog" ]
then
mkdir ${DATABASE_PATH}/rmanlog
fi

if [ ! -d "${ARCHIVELOG_PATH}/controlfile_backup" ]
then
mkdir ${DATABASE_PATH}/controlfile_backup
fi

if [ ! -d "${ARCHIVELOG_PATH}/database_backup" ]
then
mkdir ${DATABASE_PATH}/database_backup
fi
}


#把資料庫備份目錄引數替換到oraclebackup.sh
function replaceDatabaseBakPath()
{
sed -i "s#^\(${KEY1} *= *\)\([^ ]*\)\( *.*\)#\1${DATABASE_PATH}\3#" ./oraclebackup.sh
}


#把歸檔日誌目錄引數替換到oraclebackup.sh
function replaceArchivelogBakPath()
{
sed -i "s#^\(${KEY2} *= *\)\([^ ]*\)\( *.*\)#\1${ARCHIVELOG_PATH}\3#" ./oraclebackup.sh
}


#把ORACLE_HOME等引數替換到oraclebackup.sh
function replaceOracleHome()
{
sed -i "s#^\(${KEY3} *= *\)\([^ ]*\)\( *.*\)#\1${ORACLE_BASE_VAL}\3#" ./oraclebackup.sh
sed -i "s#^\(${KEY4} *= *\)\([^ ]*\)\( *.*\)#\1${ORACLE_HOME_VAL}\3#" ./oraclebackup.sh
sed -i "s#^\(${KEY5} *= *\)\([^ ]*\)\( *.*\)#\1${ORACLE_SID_VAL}\3#" ./oraclebackup.sh
}


function usage()
{
echo "------------------------------------------------------------------------"
echo 
echo "Example:"
echo "      Sample:    ./init.sh  /aaa/bbb/databaseBackupPath  /aaa/bbb/archivelogBackupPath"
echo 
echo "note: The path must be exist!"
echo "------------------------------------------------------------------------"
}


#指定的路徑不存在
function pathNotExist()
{
echo "************************************************************************"
echo 
echo "Path: ${1} not Exist!"
echo 
echo "************************************************************************" 
}


#環境變數沒找到
function envNotFound()
{
echo "************************************************************************"
echo 
echo "env ${1} not found!"
echo 
echo "************************************************************************" 
}


function check()
{
if [ ! -d "$DATABASE_PATH" ]
then
pathNotExist ${1}
exit 0
fi

if [ ! -d "$ARCHIVELOG_PATH" ]
then
pathNotExist ${2}
exit 0
fi

if [ ! $ORACLE_BASE ]
then
envNotFound "ORACLE_BASE"
exit 0
fi

if [ ! $ORACLE_HOME ]
then
envNotFound "ORACLE_HOME"
exit 0
fi

if [ ! $ORACLE_SID ]
then
envNotFound "ORACLE_SID"
exit 0
fi
}


function main()
{
if (( $# < "2"))
then
usage
exit 0
fi 

DATABASE_PATH=$1

ARCHIVELOG_PATH=$2

DATABASE_PATH=${DATABASE_PATH%/}

ARCHIVELOG_PATH=${ARCHIVELOG_PATH%/}

check

ORACLE_BASE_VAL=$ORACLE_BASE

ORACLE_HOME_VAL=$ORACLE_HOME

ORACLE_SID_VAL=$ORACLE_SID

replaceOracleHome

makeSubDir

replaceDatabaseBakPath

replaceArchivelogBakPath

replaceRmanCMD

setRmanConf

echo "---------&gtstart conf archive log"

setArchiveLog 


echo "---------&gtend conf archive log"

chmod 777 ./oraclebackup.sh

setCrontab


}


main $1 $2


oraclebakcup.sh

#!/bin/sh
export ORACLE_BASE=
export ORACLE_HOME=
export ORACLE_SID=
export PATH=$ORACLE_HOME/bin:$PATH


DATABASE_PATH=""
ARCHIVELOG_PATH=""


#====================================================
#0級備份rman命令
TEMPLATE_RMANCMD_LEVEL0=" connect target /;
        run {
                allocate channel c1 type disk;
                backup incremental level=0 database format 'oldpath_database/database_backup/paidb_level0_%U' tag='level0';
                sql 'alter system archive log current';
                backup archivelog all format 'oldpath_archive/archivelog/paidb_arch_%U' delete input;
                release channel c1;
        }
";


#1級備份rman命令
TEMPLATE_RMANCMD_LEVEL1=" connect target /;
        run {
                allocate channel c1 type disk;
                backup incremental level=1 database format 'oldpath_database/database_backup/paidb_level1_%U' tag='level1';
                sql 'alter system archive log current';
                backup archivelog all format 'oldpath_archive/archivelog/paidb_arch_%U' delete input;
                release channel c1;
        }
";


#2級備份rman命令
TEMPLATE_RMANCMD_LEVEL2=" connect target /;
        run {
                allocate channel c1 type disk;
                backup incremental level=2 database format 'oldpath_database/database_backup/paidb_level2_%U' tag='level2';
                sql 'alter system archive log current';
                backup archivelog all format 'oldpath_archive/archivelog/paidb_arch_%U' delete input;
                release channel c1;
        }
";
#======================替換路徑後的RMAN命令=======================
RMANCMD_LEVEL0=""
RMANCMD_LEVEL1=""
RMANCMD_LEVEL2=""
#==============================================================


#替換0級備份命令中的路徑引數
function replaceRmanCMDl0()
{
RMANCMD_LEVEL0=`echo ${TEMPLATE_RMANCMD_LEVEL0} | sed -n "s#oldpath_database#${DATABASE_PATH}#p"`


RMANCMD_LEVEL0=`echo ${RMANCMD_LEVEL0} | sed -n "s#oldpath_archive#${ARCHIVELOG_PATH}#p"`

echo "##################RMANCMD######################"
echo ${RMANCMD_LEVEL0}
echo "###############################################"
}


#替換1級備份命令中的路徑引數
function replaceRmanCMDl1()
{
RMANCMD_LEVEL1=`echo ${TEMPLATE_RMANCMD_LEVEL1} | sed -n "s#oldpath_database#${DATABASE_PATH}#p"`


RMANCMD_LEVEL1=`echo ${RMANCMD_LEVEL1} | sed -n "s#oldpath_archive#${ARCHIVELOG_PATH}#p"`

echo "##################RMANCMD######################"
echo ${RMANCMD_LEVEL1}
echo "###############################################"
}


#替換2級備份命令中的路徑引數
function replaceRmanCMDl2()
{
RMANCMD_LEVEL2=`echo ${TEMPLATE_RMANCMD_LEVEL2} | sed -n "s#oldpath_database#${DATABASE_PATH}#p"`


RMANCMD_LEVEL2=`echo ${RMANCMD_LEVEL2} | sed -n "s#oldpath_archive#${ARCHIVELOG_PATH}#p"`

echo "##################RMANCMD######################"
echo ${RMANCMD_LEVEL2}
echo "###############################################"
}


#====================================================
#0級備份
function backupLevel0()
{
rman log=\'${DATABASE_PATH}/rmanlog/paidb_rman_level0.log\' append < ${RMANCMD_LEVEL0}
EOF
}


#1級備份
function backupLevel1()
{
rman log=\'${DATABASE_PATH}/rmanlog/paidb_rman_level1.log\' append < ${RMANCMD_LEVEL1}
EOF
}


#2級備份
function backupLevel2()
{
rman log=\'${DATABASE_PATH}/rmanlog/paidb_rman_level2.log\' append < ${RMANCMD_LEVEL2}
EOF
}


#檢查oracle備份檔案,如果有損壞的記錄,會放進V$DATABASE_BLOCK_CORRUPTION檢視中,
#需要DBA定期檢查V$DATABASE_BLOCK_CORRUPTION檢視,塊被修復後,
#V$DATABASE_BLOCK_CORRUPTION中相應的記錄會被自動刪除
function backupcheck()
{
rman log=\'${DATABASE_PATH}/rmanlog/rmancheck.log\' append < connect target /;
run {
#check database
backup validate check logical database;
#check backup set
restore database validate check logical;
#crosscheck backup
crosscheck backup;
}
EOF
}


#刪除過期的備份檔案
function backupDelete()
{
rman log=\'${DATABASE_PATH}/rmanlog/rmandelete.log\' append < connect target /;
run {
delete noprompt obsolete;
delete noprompt expired backup;
}
EOF
}


#恢復資料庫到最新狀態
function backupRestore()
{
rman log=\'${DATABASE_PATH}/rmanlog/rmanrestore.log\' append < connect target /;
run {
restore database;
recover database;
}
EOF
}


#====================================================
#0級備份
function backupl0()
{
replaceRmanCMDl0

backupLevel0 
}


#1級備份
function backupl1()
{
replaceRmanCMDl1
    
    backupLevel1 
}


#2級備份
function backupl2()
{
replaceRmanCMDl2

    backupLevel2 
}


#檢查備份檔案
function backupck()
{
backupcheck 
}


#刪除過期的備份檔案
function backupdel()
{
backupDelete 
}


#恢復資料庫到最新狀態
function backupres()
{
backupRestore
}


#====================================================


function usage()
{
echo "------------------------------------------------------------------------"
echo 
echo "Example:"
echo "      Sample:    ./oraclebackup.sh  -l0|-l1|-l2|-c|-d|-r"
echo 
echo "note: -l0 backup level0 0級備份
-l1 backup level1 1級備份
-l2 backup level2 2級備份
-c  backup check 檢查備份
-d  backup delete 刪除過期備份
-r  backup restore" 恢復資料庫到最新狀態
echo "------------------------------------------------------------------------"
}


function main()
{
if (( $# < "1" ))
then
usage
exit 0
fi

case "$1" in
"-l0")
backupl0
exit 0
;;
"-l1")
backupl1
exit 0
;;
"-l2")
backupl2
exit 0
;;
"-c")
backupck
exit 0
;;
"-d")
backupdel
exit 0
;;
"-r")
backupres
exit 0
;;
esac

usage
}


main $1








來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/12478376/viewspace-1125549/,如需轉載,請註明出處,否則將追究法律責任。

相關文章