- 編寫ip切換腳本 - 主機 & 备机
[oracle@DB196 shell]$ mkdir -p /home/oracle/log/
[oracle@DB196 shell]$ pwd
/u01/app/oracle/product/12.2.0/db_1/shell
[oracle@DB196 shell]$ ls
myip.sh
[oracle@DB196 shell]$ cat myip.sh
#!/bin/bash
logfile=/home/oracle/log/vip_switch.log
echo '' | tee -a $logfile
if [ $# -ne 4 ]
then
echo Usage: $0 add/del hostname ssh_port vip | tee -a $logfile
exit 1;
fi
action=$1
hostname=$2
ssh_port=$3
vip=$4
function get_gateway {
if [ $# -ne 2 ] ; then
return 1
fi
local v_str="ssh -p $1 root@$2 ip route show | grep default | awk -F' ' '{print \$3}'"
echo $(date "+%Y-%m-%d %H:%M:%S") "------------------>" $v_str >> $logfile
local tmp_gateway=$(ssh -p $1 root@$2 ip route show | grep default | awk -F' ' '{print $3}')
echo $tmp_gateway
}
function get_linkname {
if [ $# -ne 2 ] ; then
return 1
fi
local v_str="ssh -p $1 root@$2 ip link | grep -E '^[0-9]' | grep BROADCAST | awk -F': ' '{print \$2}'"
echo $(date "+%Y-%m-%d %H:%M:%S") "------------------>" $v_str >> $logfile
local tmp_linkname=$(ssh -p $1 root@$2 ip link | grep -E '^[0-9]' | grep BROADCAST | awk -F': ' '{print $2}')
echo $tmp_linkname
}
function get_netport {
if [ $# -ne 3 ] ; then
return 1
fi
local v_str="ssh -p $1 root@$2 ip addr show $3 | grep $3 | grep -v 'secondary' | grep 'brd' | grep 'scope global' | awk -F' ' '{print \$2}' | awk -F/ '{print \$2}'"
echo $(date "+%Y-%m-%d %H:%M:%S") "------------------>" $v_str >> $logfile
local tmp_netport=$(ssh -p $1 root@$2 ip addr show $3 | grep $3 | grep -v 'secondary' | grep 'brd' | grep 'scope global' | awk -F' ' '{print $2}' | awk -F/ '{print $2}')
echo $tmp_netport
}
function get_current_vip {
if [ $# -ne 4 ] ; then
return 1
fi
local v_str="ssh -p $1 root@$2 ip addr show $3 | grep $3 | grep 'scope global' | grep $4 | awk -F' ' '{print \$2}' | awk -F/ '{print \$1}'"
echo $(date "+%Y-%m-%d %H:%M:%S") "------------------>" $v_str >> $logfile
local tmp_current_vip=$(ssh -p $1 root@$2 ip addr show $3 | grep $3 | grep 'scope global' | grep $4 | awk -F' ' '{print $2}' | awk -F/ '{print $1}')
echo $tmp_current_vip
}
function set_vip {
if [ $# -ne 6 ] ; then
return 1
fi
local v_str="ssh -p $1 root@$2 ip addr $3 $4/$5 dev $6"
echo $(date "+%Y-%m-%d %H:%M:%S") "------------------>" $v_str | tee -a $logfile
ssh -p $1 root@$2 ip addr $3 $4/$5 dev $6
}
function send_ping {
if [ $# -ne 4 ] ; then
return 1
fi
local v_str="ssh -p $1 root@$2 ping $3 -c 1 -I $4 1>/dev/null"
echo $(date "+%Y-%m-%d %H:%M:%S") "------------------>" $v_str | tee -a $logfile
ssh -p $1 root@$2 ping $3 -c 1 -I $4 1>/dev/null
}
function send_arp {
if [ $# -ne 4 ] ; then
return 1
fi
local v_str="ssh -p $1 root@$2 /sbin/arping -I $3 -f $4 -s $5 -w 2 1>/dev/null"
echo $(date "+%Y-%m-%d %H:%M:%S") "------------------>" $v_str | tee -a $logfile
ssh -p $1 root@$2 /sbin/arping -I $3 -f $4 -s $5 -q -w 2 1>/dev/null;
}
gateway=$(get_gateway $ssh_port $hostname)
if [ $? = 1 ] ; then
exit 1;
fi
echo $(date "+%Y-%m-%d %H:%M:%S") "------------------- gateway = [$gateway]" | tee -a $logfile
linkname=$(get_linkname $ssh_port $hostname)
if [ $? = 1 ] ; then
exit 1;
fi
echo $(date "+%Y-%m-%d %H:%M:%S") "------------------- linkname = [$linkname]" | tee -a $logfile
netport=$(get_netport $ssh_port $hostname $linkname)
if [ $? = 1 ] ; then
exit 1;
fi
echo $(date "+%Y-%m-%d %H:%M:%S") "------------------- netport = [$netport]" | tee -a $logfile
current_vip=$(get_current_vip $ssh_port $hostname $linkname $vip)
if [ $? = 1 ] ; then
exit 1;
fi
echo $(date "+%Y-%m-%d %H:%M:%S") "------------------- current_vip = [$current_vip]" | tee -a $logfile
if [ "${current_vip}" = "$vip" ]; then
echo $(date "+%Y-%m-%d %H:%M:%S") "------------------- current_vip is [${current_vip}] = [$vip]" | tee -a $logfile
if [ "$action" = "add" ]; then
send_ping $ssh_port $hostname $gateway $vip
echo $(date "+%Y-%m-%d %H:%M:%S") "------------------- [ $0 $@ ] NONE " | tee -a $logfile
exit 0;
elif [ "$action" = "del" ]; then
set_vip $ssh_port $hostname $action $vip $netport $linkname
exit $?;
else
exit 0;
fi
else
echo $(date "+%Y-%m-%d %H:%M:%S") "------------------- current_vip is [${current_vip}] !=[$vip]" | tee -a $logfile
if [ "$action" = "add" ]; then
set_vip $ssh_port $hostname $action $vip $netport $linkname
send_arp $ssh_port $hostname $linkname $gateway $vip
exit 0;
elif [ "$action" = "del" ]; then
echo $(date "+%Y-%m-%d %H:%M:%S") "------------------- [ $0 $@ ] NONE " | tee -a $logfile
exit 0;
else
exit 0;
fi
fi
[oracle@DB196 shell]$ chmod u+x myip.sh
- 创建 myip_user (主庫 sys下)
begin
dbms_scheduler.create_credential
(
credential_name => 'myip_user',
username => 'oracle',
password => 'xag#1234'
);
end;
- 創建oracle 中 調用 shell 腳本 scheduler job (主庫 sys下)
begin
dbms_scheduler.create_job(job_name => 'IP_JOB', job_type => 'EXECUTABLE',number_of_arguments => 4
,job_action => '/u01/app/oracle/product/12.2.0/db_1/shell/myip.sh'
,comments => 'ENABLE VIP(IP_JOB)',auto_drop => false);
end;
4.创建 my_ip_conig 存储过程
CREATE OR REPLACE PROCEDURE my_ip_conig(p_action in varchar2,p_hostname in varchar2,p_sshport in varchar2,p_vip in varchar2)
IS
BEGIN
dbms_scheduler.set_job_argument_value(job_name => 'IP_JOB',argument_position => 1,argument_value => p_action);
dbms_scheduler.set_job_argument_value(job_name => 'IP_JOB',argument_position => 2,argument_value => p_hostname);
dbms_scheduler.set_job_argument_value(job_name => 'IP_JOB',argument_position => 3,argument_value => p_sshport);
dbms_scheduler.set_job_argument_value(job_name => 'IP_JOB',argument_position => 4,argument_value => p_vip);
--dbms_scheduler.enable('IP_JOB');
dbms_scheduler.run_job('IP_JOB');
END;
- 创建 pr_vip_check 存储过程
create or replace procedure pr_vip_check as
v_pir_host varchar2(30);
v_stby_status varchar2(30);
v_database_role varchar2(30);
begin
select nvl(max(database_role),'NONE') into v_database_role from v$database t where t.DATAGUARD_BROKER='ENABLED';
if v_database_role='PRIMARY' then
select utl_inaddr.get_host_name into v_pir_host from dual;
select nvl(max(t."STATUS"),'NONE') into v_stby_status from v$archive_dest_status t where t.STATUS !='INACTIVE' and t.TYPE='PHYSICAL';
if v_pir_host='xag120' and v_stby_status='VALID' then
my_ip_conig('del','xag120','22','192.168.40.123');
my_ip_conig('add','xag121','22','192.168.40.123');
my_ip_conig('del','xag121','22','192.168.40.122');
my_ip_conig('add','xag120','22','192.168.40.122');
elsif v_pir_host='xag120' and v_stby_status!='VALID' then
my_ip_conig('del','xag121','22','192.168.40.123');
my_ip_conig('add','xag120','22','192.168.40.123');
my_ip_conig('del','xag121','22','192.168.40.122');
my_ip_conig('add','xag120','22','192.168.40.122');
elsif v_pir_host='xag121' and v_stby_status='VALID' then
my_ip_conig('del','xag121','22','192.168.40.123');
my_ip_conig('add','xag120','22','192.168.40.123');
my_ip_conig('del','xag120','22','192.168.40.122');
my_ip_conig('add','xag121','22','192.168.40.122');
elsif v_pir_host='xag121' and v_stby_status!='VALID' then
my_ip_conig('del','xag120','22','192.168.40.123');
my_ip_conig('add','xag121','22','192.168.40.123');
my_ip_conig('del','xag120','22','192.168.40.122');
my_ip_conig('add','xag121','22','192.168.40.122');
end if;
else
null;
end if;
end;
- 測試腳本
begin
pr_vip_check;
end;
- 創建db啟動或db角色改變時觸發器
create or replace TRIGGER tr_vip_check
after startup or db_role_change on database
begin
pr_vip_check;
end;
- 創建vip 輪詢檢查的job
begin
dbms_scheduler.create_job(
job_name => 'VIP_CHECK', --job名
job_type => 'STORED_PROCEDURE', --job类型
job_action => 'pr_vip_check', --存储过程名
start_date => sysdate, --开始执行时间
repeat_interval => 'FREQ=SECONDLY;INTERVAL=60', --下次执行时间,每60秒执行存储过程pc_sam
comments => 'CHECK VIP', --注释
auto_drop => false, --job禁用后是否自动删除
enabled => true);
end;
- 創建scheduler job 查詢視圖
CREATE OR REPLACE VIEW V_XAG_JOB2 AS
SELECT JOB_NAME,JOB_ACTION job,to_char(START_DATE,'yyyy-mm-dd hh24:mi:ss') as START_DATE
,REPEAT_INTERVAL,ENABLED,to_char(LAST_START_DATE,'yyyy-mm-dd hh24:mi:ss') as LAST_START_DATE
,to_char(NEXT_RUN_DATE,'yyyy-mm-dd hh24:mi:ss') as NEXT_RUN_DATE
,COMMENTS
FROM user_scheduler_jobs order by JOB_NAME;
10.查詢
[oracle@xag120 ~]$ sql / as sysdba
SQL> set sqlformat ansiconsole
SQL> select * from V_XAG_JOB2 where job_name in('IP_JOB','VIP_CHECK');
JOB_NAME JOB START_DATE REPEAT_INTERVAL ENABLED LAST_START_DATE NEXT_RUN_DATE COMMENTS
IP_JOB /u01/app/oracle/product/12.2.0.1/db_1/shell/myip.sh FALSE ENABLE VIP(IP_JOB)
VIP_CHECK pr_vip_check 2020-07-18 23:00:10 FREQ=SECONDLY;INTERVAL=60 TRUE 2020-07-18 23:03:10 2020-07-18 23:04:10 CHECK VIP