使用shell指令碼快速得到主備關係

jeanron100發表於2016-08-16
對於備庫的使用,尤其是一主多備的環境,一直以來有一點感覺不大給力,那就是主備庫的關係,總是感覺會少一點什麼。
尤其是在做月度404審計的時候,總是要反覆確認備庫的IP。如果是手工管理的場景中,基本就是檢視log_archive_config的配置,也還需要解析裡面的TNS配置
如果配置了DG Broker,可能情況會好些,輸出的關係是還是比較清楚的。
Configuration - dg_test
  Protection Mode: MaxPerformance
  Databases:
    test   - Primary database
    stest1 - Physical standby database
    stest2 - Physical standby database
Fast-Start Failover: DISABLED
Configuration Status:
SUCCESS
但是這裡有個問題就是備庫的IP是哪個,可能tnsping的結果是主機名的情況,那麼還需要再轉義一次,到/etc/hosts裡面去匹配。
這樣下來,其實這些工作有多難,還真沒有,但是重複的手工操作太多,實在讓人感覺有種雞肋的味道。
既然搭建Data Guard都能實現半自動化了,這個功能不實現還是有些說不過去。
這個輸出應該把備庫的主機名,IP都羅列出來,如果只是配置了IP,就顯示IP和資料庫的db_unique_name並列
這樣一個資料庫的大體情況就會一目瞭然,包括一些必備的引數等。
而執行指令碼只需要輸入主庫的IP即可
比如sh checkdb2.sh 10.127.xxx.xx
改進後的輸出類似下面的形式:
10.127.xxx.xx
.
  Databases:
    test   - Primary database
    stest1 - Physical standby database
    stest2 - Physical standby database
.
10.127.133.16  stest1.cyou.com   stest1
10.127.2.3    stest2.cyou.com   stest2

NAME                 DB_UNIQUE_NAME       DATABASE_ROLE    FORCE_LOGG
-------------------- -------------------- ---------------- ----------
TEST                 test                 PRIMARY          YES

NAME                           VALUE
------------------------------ --------------------------------------------------
db_file_name_convert
db_name                        test
db_unique_name                 test
dg_broker_start                TRUE
local_listener                 TEST
log_file_name_convert
standby_file_management        AUTO

checkdb2.sh的指令碼內容如下:
base_dir=/U01/oracle/auto_dg
ip=$1

. ${base_dir}/autodg.cnf
echo $ip
ORACLE_HOME=`ssh $ip "cat /etc/oratab | tail -1 | awk -F: '{print \\$2}'"   2>&1 `
ssh $ip "mkdir -p /home/oracle/auto_dg/scripts"
scp -r ${base_dir}/scripts/* $ip:/home/oracle/auto_dg/scripts >/dev/null 2>&1
ssh $ip " sh /home/oracle/auto_dg/scripts/getdbinfo.sh"   2>&1 |grep -v stty

這個指令碼本身邏輯很簡單,關鍵是兩個輔助指令碼。
一個是getdbinfo.sh,指令碼在/home/oracle/auto_dg/scripts下
內容如下:
. /home/oracle/.bash_profile
chown -R oracle:oinstall /home/oracle/auto_dg

sudo su -l oracle <<eof
echo .
dgmgrl -silent / " show configuration"  |grep  -i database

echo .
sh /home/oracle/auto_dg/scripts/get_dg_host.sh
EOF

sudo su -l oracle <<eof
sqlplus -s / as sysdba <<eos
col name format a20
col DB_UNIQUE_NAME format a20
col force_logging format a10
col value format a50
set linesize 150
set feedback off
select name,db_unique_name,database_role,force_logging from v\\\$database;
col name format a30
select name,value from v\\\$parameter where upper(name) in ('DB_NAME','DB_UNIQUE_NAME','LOCAL_LISTENER','DG_BROKER_START','STANDBY_FILE_MANAGEMENT','DB_FILE_NAME_CONVERT','LOG_FILE_NAME_CONVERT') order by name;
EOS
echo .
tnsping $1|grep ADDRESS|sed 's/Attempting to contact //' > /home/oracle/auto_dg/tns_port.lst
EOF

而最為關鍵的指令碼則是get_dg_host.sh,指令碼內容如下:

for tmp_ins in `dgmgrl -silent / " show configuration"  |grep  -i "Physical standby database"|sed 's/Physical standby database//g'|sed 's/-//g'`
do
tmp_host=`tnsping ${tmp_ins}|grep ADDRESS|sed 's/Attempting to contact //'|sed 's/(/\n/g'|sed 's/)/\n/g'|grep -i 'HOST\|PORT\|SERVICE_NAME\|SID_NAME' |grep -i HOST| awk -F= '{print $2}'`
#echo ${tmp_host}
tmp_port=`tnsping ${tmp_ins}|grep ADDRESS|sed 's/Attempting to contact //'|sed 's/(/\n/g'|sed 's/)/\n/g'|grep -i 'HOST\|PORT\|SERVICE_NAME\|SID_NAME' |grep -i PORT| awk -F= '{print $2}'`
#echo ${tmp_port}
tmp_con_chk=`nc -w 1 -v ${tmp_host} ${tmp_port}`
#echo ${tmp_con_chk}
if [[ ${tmp_con_chk} =~ "succ" ]]; then
echo  `grep  ${tmp_host} /etc/hosts|awk '{print $1}'`" " ${tmp_host} " " ${tmp_ins}
else
echo 'NEED TO CHECK HOST '${tmp_host}
fi
done
這個指令碼里面會做複雜的校驗,最終能夠生成我們期望的資料行。

</eos
</eof
</eof

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

相關文章