一. 一些准備知識
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 " [email protected] < $RMAN_LOG_FILE
exit $RSTAT