2012年11月29日 星期四

第二十四回 dbv 和 backup validate

上上週小弟一個系統在  v$database_block_corruption 中出了幾個 corruption list ,找出了所在位置的物件,問了開發者,是個不重要的 table ,因此就只做將之 truncate 掉後就沒有再理會。

但是之後雖然每天的備份都成功,但是 v$database_block_corruption 中的 list 卻不會被清除,因為該空間雖然己經歸還給系統,但是在該 datafile 使用 dbv 去驗證時還是會出現有 corruption block 的現象,除非有人重新使用這塊空間,系統才會將之 format 。在之後的備份的驗證才不會重新被驗證到。證明該 block 己經是良好的 block 。

開了 SR 後, Support 要我依照 336133.1的引導,具體說來,該份文件就是指導你如何暫時建立一個 dummy 物件將該空間使用掉後,由系統 FORMAT 後,在下次的 backup validate 或者是備份成功後,就會由 v$database_block_corruption 的 list 裏消失,雖然我一開始只有 truncate table 的方式也是可以,但是該 list 除非在重新被使用到之前,區塊損壞的記錄是不會消失的。

所以我就依據文件的引導,指定了一個 table 到該損壞的 datafile 去讓他成長,文件提供了一個 trigger ,可以直接在做 insert 動作時發現該 block 己被修復,事實上該 trigger 不建立,整個流程一樣是 work 的。

因為我 block corruption 的部份有數十個,如果有建立 trigger 的話,有可能會發生,只修了其中一部份區塊,但其餘區塊未被修復。所以第二次 test run 時,我就沒建立 trigger 了。一直將 table 塞到滿為止。

後來使用 dbv 指令確認該檔案沒有損壞區塊後,再重新執行 backup validate datafile [number] ; 完成後,v$database_block_corruption 中的 list 就會被清除了。

2012年5月24日 星期四

第二十三回 SAP 系統主機變更筆記

因為有時有些需求,需要移動或複製一套 SAP 環境出來,目前己經做了好幾次,但不常做,所以筆記一下。

 OS 環境:確認有對應的 UID,GID,和 Username , Group Name , Home Directory 下必須有對應的 Profile 及 ENV
DB 環境:確認資料庫完整複製且可正常啟動,當然包含 ORACLE_HOME 及 SAP 相關的檔案結構。
SAP 環境:確認 /sapmnt 及 /usr/sap 下目錄有完整

因應 Hostname 變更的修改 /etc/host 下需要有變更後 hostname 的 Entry /etc/services 下需要新增對應的 sapMS 記錄,不然啟動時 Message Server 會找不到

以下列指令分別在 /home /usr/sap /sapmnt 下找出所有檔名包含舊 hostname 在內的檔案
find . –name '*old_hostname*'

找到後,將舊名部份 mv 為新名稱

以下列指令分別在 /home /usr/sap /sapmnt 下找出所有檔案內容包含舊 hostname 在內的檔案
find . -type f | xargs grep old_hostname|egrep -v 'err|trc|log|_evt|dev_|ERR|cofile'

通常比較重要的會有下列幾個
/sapmnt/P01/profile/DEFAULT.PFL
 /sapmnt/P01/profile/START_DVEBMGS00_old_hostname
/sapmnt/P1/profile/oracle/tnsnames.ora

 請記得 TNSNAMES 及 Listener 是位於 oracle home 之下 /oracle/P01/102_64/network/admin/tnsnames.ora
 /oracle/P01/102_64/network/admin/listener.ora

將找到的檔案以 VI 編輯,把找的到的 old hostname 更改為你新的 hostname ENV 和 PROFILE 內容再確認有沒有漏掉的部份

此時就可啟動 Oracle Listener

再啟動 Oracle Database

上述二者均正常啟動便完成大半了

再來啟動 SAP 如果正常啟動就完成了,接下來只要去官方申請 License ,將 key 填入 slicense 中。 基本上 system clone 的前段也是用類似方式,後面就用 SAP 提供方式將 SID 改掉,但我們這次的需求並不需要變更 SID。

詳細狀況請再查 SAP Notes 。

2012年4月17日 星期二

第二十二回 Oracle DB Online Backup 到其他主機

建立 DataGuard 時就必須複製整套 DB 資料,有人是使用 RMAN Duplicate 來做,我是不習慣用啦,因為前置還得搞通 TNS 那些東西,還必須確保備份也是正常的,所以就直接從 Source Database 複製是最快的。只是會消耗一點 Production 主機的效能和網路頻寬。而且這個方法只要 RSH 或 SSH 有 Trust 設過就可以使用。

測試過 400GB 資料在 1000Mbps 網路下,只需要 2 小時不到就可以完成了。如果你是要即時備份,當然是 Disk 快照最方便的。因為透過我這個方法,你還必須確保複製過程的 Archivelog 都必須存在,事後還需要做 Recovery 。這也算是窮人的 snapshot 吧。只是人家 snapshot 是以秒在算,這個可能都要幾個小時起跳。

首先一般資料庫在規畫時都會將 Datafile 放在特定目錄,所以在 Remote 端 Create Filesystem 時大部份人只會開一層,然後 Datafile 就放在下面,但有些套裝軟體比較雞婆(像SAP),每個 datafile 在 create 時會再建一層目錄,因此用 Scripts 做時就將這個因素也考慮進去,所有關聯目錄會依 Source 端也一併建好,如果用 RMAN 做的話,沒將整個目錄結構設對的話是倒不回來的。

整個 Scripts 內容如下:

#!/usr/bin/ksh

#===================================================================================
# 平常不使用時可將 exit 註解拿掉,以免誤執行此 Scripts,蓋到你的 Target 端資料庫
#exit
#===================================================================================

#參數初始
export ORACLE_SID=DB1
workdir="/orahome/jobs/dbdr"
target_dir=""
target_system="db_host_target"
remote_cmd=rsh
run_date=`date +%m%d`
logfile="/orahome/jobs/logs/dg_init$ORACLE_SID.log.$run_date"

#切換 SSH 或 RSH 用的 copy 工具,配合上面 remote_cmd 參數
case $remote_cmd in
rsh)
copy_method=rcp
break
;;
ssh)
copy_method=scp
break
;;
esac

date > $logfile

#先抓 Tablespace 名稱
echo "get Tablespace information...." >> $logfile
cd $workdir
echo "set term off" >$workdir/get_tablespace_name.sql
echo "set pagesize 60" >$workdir/get_tablespace_name.sql
echo "set head off" >>$workdir/get_tablespace_name.sql
echo "set feedback off" >>$workdir/get_tablespace_name.sql
echo "spool $workdir/tablespace.lst" >>$workdir/get_tablespace_name.sql
echo "select name from v\$tablespace where name not in (select distinct tablespace_name from dba_temp_files);" >>$workdir/ge
t_tablespace_name.sql
echo "spool off" >>$workdir/get_tablespace_name.sql
echo "exit" >>$workdir/get_tablespace_name.sql
sqlplus "/ as sysdba" @$workdir/get_tablespace_name.sql

#切換 Backup Mode 後抓出每個 Tablespace 內置的 Datafile ,開始複製到遠端
for i in `cat $workdir/tablespace.lst`
do
get_datafile="$workdir/get_datafile_name.sql"
echo " " >> $logfile
echo "==============================================================" >> $logfile
date >> $logfile
echo "$i transfer to backup mode" >> $logfile
echo "" > $get_datafile
#echo "select ts# from v\$tablespace where name = '$i';" >> $get_datafile
echo "alter tablespace $i begin backup;" >> $get_datafile
echo "set linesize 120" >> $get_datafile
echo "set pagesize 200" >> $get_datafile
echo "set term off" >> $get_datafile
echo "set head off" >> $get_datafile
echo "set feedback off" >> $get_datafile
echo "spool $workdir/ora_datafile_$i.lst" >> $get_datafile
echo "select name from v\$datafile where ts#=( select ts# from v\$tablespace where name = '$i');" >>$get_datafile
echo "spool off" >>$get_datafile
echo "exit" >>$get_datafile
sqlplus "/ as sysdba" @get_datafile_name.sql

for list in `cat $workdir/ora_datafile_$i.lst`
do

target_dir=`dirname $list`

result=$(rsh $target_system "test -d ${target_dir};echo \$?")

if [ result -ne 0 ] ; then
echo "create `dirname $list` on target filesystem..." >> $logfile
$remote_cmd $target_system mkdir -p $target_dir
fi

echo "copy $list to target filesystem..." >> $logfile
$copy_method $list $target_system:$target_dir
done

echo "alter tablespace $i end backup;" > $get_datafile
echo "exit" >>$get_datafile
sqlplus "/ as sysdba" @get_datafile_name.sql
echo "$i tablespace transfer complete" >> $logfile
echo "$i transfer to online mode" >> $logfile
date >> $logfile
echo "==============================================================" >> $logfile
echo " " >> $logfile
done

# Datafile 全部傳完後,寫個 LOG
echo "database transfer complete...." >> $logfile

#接下來是 online redo log
echo "==============================================================" >> $logfile
echo "set linesize 120" >> $get_datafile
echo "set pagesize 200" >> $get_datafile
echo "set term off" >> $get_datafile
echo "set head off" >> $get_datafile
echo "set feedback off" >> $get_datafile
echo "spool $workdir/ora_datafile.lst" >> $get_datafile
echo "select member from v\$logfile;" >>$get_datafile
echo "spool off" >>$get_datafile
echo "exit" >>$get_datafile
sqlplus "/ as sysdba" @get_datafile_name.sql

for list in `cat $workdir/ora_datafile.lst`
do

target_dir=`dirname $list`

result=$(rsh $target_system "test -d ${target_dir};echo \$?")

if [ result -ne 0 ] ; then
echo "create `dirname $list` for online REDO Log on target filesystem..." >> $logfile
$remote_cmd $target_system mkdir -p $target_dir
fi

done

# 最後是 Controlfile ,會直接複製到 Remote 端的對應位置,所以 Memory 配置夠的話,直接啟動就是
# standby database mode了。就可以開始 Dataguard 設定。

echo "backup controlfile transfer...." >> $logfile
echo "alter database create standby controlfile as '$workdir/ctrlf_bk_$run_date';" > $get_datafile
echo "exit" >>$get_datafile
sqlplus "/ as sysdba" @$get_datafile
echo "set linesize 120" > $get_datafile
echo "set pagesize 200" >> $get_datafile
echo "set term off" >> $get_datafile
echo "set head off" >> $get_datafile
echo "set feedback off" >> $get_datafile
echo "spool $workdir/ora_datafile.lst" >> $get_datafile
echo "select name from v\$controlfile;" >>$get_datafile
echo "spool off" >>$get_datafile
echo "exit" >>$get_datafile
sqlplus "/ as sysdba" @$get_datafile

for list in `cat $workdir/ora_datafile.lst`

do
target_dir=`dirname $list`
result=$(rsh $target_system "test -d ${target_dir};echo \$?")
if [ result -ne 0 ] ; then
echo "create `dirname $list` for Controlfile file on target filesystem..." >> $logfile
$remote_cmd $target_system mkdir -p $target_dir
fi
#echo $target_dir
#echo $list
$copy_method $workdir/ctrlf_bk_$run_date $target_system:$list
done

rm $workdir/ctrlf_bk_$run_date
echo "backup controlfile transfer complete...." >> $logfile
echo "==============================================================" >> $logfile


缺點及注意事項
1. 前置處理 SSH 和 RSH 必須設定完成可不需密碼 Remote Login 到遠端。
2. Orache Home ,這個當然要自己裝嘍,不然設法 Copy 過去改,就不多寫了,因為這個東西也不是每次必 Copy 的
3. Initial File 和 SPFILE當然還是得自己先手動設置,只要複製過去就可以了
4. Archive Log 的部份,因為這隻是為了 Dataguard 做的,事後本來就會去設定傳遞 Archive Log
所以就沒雞婆繼續改下去
5. Temp File 沒有特別去處理,Target 端啟動後,要自行重新建立 Temp File
6. 兩邊的 shell 必須是 sh 或 ksh ,如果像 SAP 預設是使用 csh ,請先更改 default shell ,不然不能正常執行
7. 請測試過再用正式環境來玩,搞錯自己把自己的檔案蓋掉,不負任何責任。
8. 這個只是為了有需求一次複製整個資料庫使用(如軟體上線前或需要一個環境測試,又沒有 Disk snapshot 的功能時),不是為了平常備份做的,真的日常備份請用磁帶機。除非你覺得硬碟太便宜。