使用 RMAN 同步數據庫
一.概述
二 操作步驟
(一).把生產庫置爲歸檔模式
(二).啓動rman做數據庫0級備份
(三).修改生產庫數據庫到未歸檔
(四).拷貝備份集到測試庫
(五).在測試庫上的操作
一.概述因項目組遇到要2臺數據庫同步的問題,決定使用rman來實現此功能,生產庫運行在非歸檔模式,所以操作起來相對麻煩些,生產庫最多允許丟失半天數據,晚上可以重啓數據,這樣就爲我們使用rman創造了必要條件,先來理清一下操作步驟:
1. 首先shutdown生產庫(node1) ,並修改成歸檔模式。
2. 使用rman做一個0級備份集,並設置控制文件爲自動備份。
3. 修改生產庫爲非歸檔模式,並置爲open狀態。
4. 到測試庫上面,修改數據庫爲歸檔模式,因沒有性能要求,不需要再改回非歸檔,方便恢復操作。
5. 拷貝備份集到測試庫(node2),備份集的存放位置和生產庫保持一致。
6. 啓動測試庫到nomount狀態。
7. 啓動rman,第一步先恢復controlfile.裏面包含了重要的備份信息。
8. 更改數據庫到mount狀態.
9. 恢復數據庫 restore database,注意,此步驟只會使用最近的一次0級備份,而不會應用增量或差異備份。
10. Recover database,此步驟會首先應用所有的差異或增量備份,然後恢復歸檔日誌,當然在恢復歸檔時會出現錯誤,在此可以忽略掉。
11. 使用resetlogs關鍵字打開數據庫,數據庫同步完成。
以後每天按上面操作寫成腳本自動執行即可,需要注意的地方是把0級備份改爲1級或2級即可,這樣就可以每半月做一次0級備份,每天晚上做一次1級或2級備份,然後恢復到測試庫,以此來實現2數據庫的同步.
二 操作步驟 (一).把生產庫置爲歸檔模式.1. [oracle@primary orcl]$ Sqlplus ‘/as sysdba’
2. Sql>shutdown immediate;
3. Sql>startup mount;
4. Sql>alter database archivelog;
5. Sql>alter database open;
6. Sql>quit
(二).啓動rman做數據庫0級備份1. [oracle@primary orcl]$ rman target /
2. RMAN>CONFIGURE CONTROLFILE AUTOBACKUP ON;
3. RMAN> backup incremental level 0 database format 'full_db_%d_%s_%t_%p';
--第一次同步操作時用該語句。
RMAN>quit;
日常同步備份時使用1級備份
4. [oracle@primary orcl]$ rman target /
5. RMAN>CONFIGURE CONTROLFILE AUTOBACKUP ON;
6. RMAN> backup incremental level 1 database format 'increment _db_%d_%s_%t_%p';
7. RMAN>quit;
(三).修改生產庫數據庫到未歸檔.1. [oracle@primary orcl]$ Sqlplus ‘/as sysdba’
2. Sql>alter database noarchivelog;
3. Sql>alter database open;
4. Sql>quit;
(四).拷貝備份集到測試庫拷貝備份集文件到測試庫,並和生產庫相同位置,可以使用sftp或ftp等工具完成。
(五).在測試庫上的操作1. [oracle@primary orcl]$ Sqlplus ‘/as sysdba’
2. Sql>startup nomount;
3. Sql>quit;
4. [oracle@primary orcl]$ rman target /
5. RMAN> restore controlfile from/opt/oracle11g/u01/dbs/c-1190421672-20080819-01';
--該處可修改爲實際備份集。
6. RMAN> alter database mount;
7. RMAN> restore database;
8. RMAN> recover database;
9. RMAN>alter database open resetlogs;
注意,所有的增量或差異備份都是用recover database來恢復的,如果丟失增量備份,需用下面方法啓動數據庫,將可能導致丟失大量數據:
啓動sqlplus,使用下面語句清除丟失的增量備份.
Sql>recover database using backup controlfile until cancel;
ORA-00279: ü 1839635 ( 08/18/2008 23:25:21 ú) 1 ±è
ORA-00289: ¨é: /archive/1_74_662640938.dbf
ORA-00280: ü 1839635 ( 1) ò #74
Specify log: {<RET>=suggested | filename | AUTO | CANCEL}
Cancel <需要手工輸入後回車>
Media recovery cancelled.
最後執行resetlogs關鍵字啓動數據庫。
SQL> alter database open resetlogs;
Database altered.
備份及同步腳本:
rman_backup_v1.1.sh
#!/bin/sh
export ORACLE_HOME=/opt/oracle11g/u01
export ORACLE_SID=primary
export LD_LIBRARY_PATH=${ORACLE_HOME}/lib:${ORACLE_HOME}/ctx/lib
export PATH=$PATH:${ORACLE_HOME}/bin
export NLS_LANG="American_america.zhs16gbk"
export ORACLE_OWNER=oracle
export backup_dir=/home/oracle/backup/backup
export log=/home/oracle/backup/log
rsync_dir=$backup_dir #sync dir
controlfile_dir=$backup_dir/controlfile
username=oracle #target OS ,oracle user
password=go2north #target oracle user password
target_host=172.16.5.27
today_backup=`date +'%Y-%m-%d'`
today=`date +'%Y%m%d'`
white=$(echo -e "\e[39;40m")
green=$(echo -e "\e[36;40m")
red=$(echo -e "\e[31;40m")
blue=$(echo -e "\e[33;40m")
backup_status=2 #data backup status ,0: backup faild,1: 1 level increment backup,2 : 0 level backup
# Begin change restore variable
restore_status=true
last_restore_file=increment_db_ORCL_76_663449691_1
last_restore_date=(2008-08-22 19:36)
last_recover_time="2008-08-28 15:12:08"
last_restore_time=2
last_restore_num=3
# End change restore variable
#sed -i '/^# Begin change restore variable/,/^# End change restore variable/s/t=[0-9]\+/t='$((t+1))'/' $0
#sed -i 's/t=[0-9]\+/t='$((t+1))'/' $0
restore_file=`ls -lt --full-time $backup_dir/ | grep -i 'increment_db_*' | awk '{print $9}'|head -1`
controlfile=`ls -lt --full-time $controlfile_dir | grep -i 'c-*' | awk '{print $9}'| head -1`
recover_time=`ls -lt --full-time $backup_dir/ | grep -i 'increment_db_*' | awk '{print substr($7,1,5)}'| head -1`
recover_date=(`ls -lt --full-time $backup_dir/ | grep -i 'increment_db_*' | awk '{print $6 " " substr($7,1,5)}' | head -1`)
recover_times=`date +'%Y-%m-%d %H:%M:%S'`
function update_backup_info()
{
sed -i '/^# Begin change restore variable/,/^# End change restore variable/s/restore_status=.*/restore_status=true/' $0
sed -i '/^# Begin change restore variable/,/^# End change restore variable/s/last_restore_file=.*/last_restore_file='"${restore_file}"'/' $0
sed -i '/^# Begin change restore variable/,/^# End change restore variable/s/last_recover_time=.*/last_recover_time='"\"${recover_times}\""'/' $0
sed -i '/^# Begin change restore variable/,/^# End change restore variable/s/last_restore_date=.*/last_restore_date='"(${recover_date[*]})"/ $0
sed -i '/^# Begin change restore variable/,/^# End change restore variable/s/last_restore_time=.*/last_restore_time='$((last_restore_time+1))'/' $0
sed -i '/^# Begin change restore variable/,/^# End change restore variable/s/last_restore_num=.*/last_restore_num='$((last_restore_num+1))'/' $0
}
function restore_database()
{
echo "************* recover database start ****************"
cat << EOF | $ORACLE_HOME/bin/sqlplus '/as sysdba'
shutdown immediate;
startup nomount;
EOF
cat << EOF | $ORACLE_HOME/bin/rman target / |tee $log/rman_restore_db_`date +'%y%m%d%H%M'`.log
run {
allocate channel c01 type disk;
allocate channel c02 type disk;
allocate channel c03 type disk;
restore controlfile from "$controlfile_dir/$controlfile";
alter database mount;
recover database;
release channel c01;
release channel c02;
release channel c03;
}
alter database open resetlogs;
EOF
if [ "$?" = 0 ];then
echo "*******************restore be completed!************************"
backup_status=9
update_backup_info
exit 0
else
echo "******************restore database failed,please contact oracle dba*******"
sed -i '/^# Begin change restore variable/,/^# End change restore variable/s/last_recover_time=.*/last_recover_time='"\"${recover_times}\""'/' $0
sed -i '/^# Begin change restore variable/,/^# End change restore variable/s/restore_status=.*/restore_status=false/' $0
fi
return "$backup_status"
}
#delete backup file on the weekend again
#file_info=`ls -l $backup_dir/ | grep -i 'increment_backup_*.gz'|wc -l`
#if [ $file_count -gt 7 ]
#then
# del_files=`ls -lR $backup_dir| egrep -i "increment_db_|full_db_"|grep \`date -d "7 days ago" +'%Y-%m-%d'\`|awk "{print $9}"`
# rm -f $del_files;
# if [ $? = 0 ]
# then
# echo "removing $del_files"
# fi
#else
# echo "No last file"
#
#fi
###########################################
if [ "$last_restore_file" != "$restore_file" -o "${last_restore_date[1]}" != "$recover_time" ]; then
restore_database
fi
if [ "$1" = "repeat" ] ; then
restore_database
fi
if [ "$restore_status" = "true" -o "${last_restore_date[0]}" = ${recover_date[0]} ]; then
echo "Today's sync already completed!"
echo "Last restore file: $backup_dir/$last_restore_file"
echo "Last restore time: $last_restore_time"
echo "The number of times the database be restored today: $last_restore_num"
echo "The total number of times the database have ever been restore: $last_recover_time"
sed -i '/^# Begin change restore variable/,/^# End change restore variable/s/last_recover_time=.*/last_recover_time='"\"${recover_times}\""'/' $0
else
sed -i '/^# Begin change restore variable/,/^# End change restore variable/s/last_restore_time=.*/last_restore_time=0/' $0
sed -i '/^# Begin change restore variable/,/^# End change restore variable/s/restore_status=.*/restore_status=false/' $0
sed -i '/^# Begin change restore variable/,/^# End change restore variable/s/last_recover_time=.*/last_recover_time='"\"${recover_times}\""'/' $0
fi