環境介紹
1)客戶環境11.2.0.4 兩節點 rac,集群重啟后,集群資源一切正常,應用cs架構,連接數據庫報錯,提示連接對象不存在 2)分析報錯原因,連接數據庫方式:ip:Port/service_name方式連接數據庫 IP地址是scan_ip(客戶未使用dns服務器,scan ip正常在節點一,實際情況在節點二,這個不影響scan的使用,本地節點二,使用scan ip可以連接) 端口號是默認1521,且測試本地可以連接 service_name,節點一 xx,節點二xx2,不一致,存在問題(默認rac搭建后,service_name參數兩節點保存一致,人為調整可能不一致) 3)分析結論,應用連接只連接service_name=xx,只連接rac節點一,客戶通過service_name實現,業務分割。
(當節點一主機 or 實例一 shutdown后,scan ip and service_name均飄逸至節點二,可以繼續為應用提供服務)
本次集群重啟后,優先啟動節點二,scan ip掛載在節點二,然而節點一未shutdown,service_name 節點一服務名未飄逸,造成應用無法連接。 4)恢復操作,節點二,關閉scan ip服務,使其資源飄逸至節點一,至此操作結束
一、案例環境構建
1.1 環境介紹,linux5.6,database 11.2.0.3 release 1.2 測試流程
rac安裝初始化后,service_name名稱,及每個節點監聽的service_name名稱
數據庫參數修改service_name,造成節點1,2使用不同的service_name進行監聽,讓scan ip依附在節點二的Public Network card
模擬應用連接報錯,使用scan_ip + port+ service_name_node1 進行連接
1.3 rac安裝初始化后,service_name
1)數據庫參數,兩個實例參數均為jx
SQL> show parameter "service_names"
NAME TYPE VALUE
------------------------------------
service_names string jx
2)節點監聽的service_name
節點一:jx1:/u01/app/oracle$ lsnrctl status
(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=192.168.60.100)(PORT=1521))) --public ip
(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=192.168.60.152)(PORT=1521))) --vip
Service "jx" has 1 instance(s).
Instance "jx1", status READY
節點二:jx2:/u01/app/oracle$ lsnrctl status
(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=192.168.60.101)(PORT=1521)))
(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=192.168.60.153)(PORT=1521)))
Service "jx" has 1 instance(s).
Instance "jx2", status READY
1.4 數據庫參數修改service_name
1)節點一,數據庫參數service_name=jx不改變
2)如果使用一個錯誤的sid進行修改參數會如何?
參數提示修改成功,但其實並未生效,rac sid=instance_name,如下錯誤操作
SQL> alter system set service_names='jx2' sid='2';
System altered.
3)節點二,數據庫參數service_name=jx2
SQL> show parameter instance_name
NAME TYPE VALUE
------------------------------------ ---------------------- ------------------------------
instance_name string jx2
SQL> alter system set service_names='jx2' sid='jx2';
System altered.
再次查詢驗證
SQL> show parameter service_name
NAME TYPE VALUE
------------------------------------ ----------------------
service_names string jx2
4)service_name修改后,什么時候生效
jx2:/u01/app/oracle$ lsnrctl status
Service "jx" has 1 instance(s).
Instance "jx2", status READY, has 1 handler(s) for this service...
Service "jx2" has 1 instance(s).
Instance "jx2", status READY, has 1 handler(s) for this service...
立即生效,並且歷史的service_name服務還可以使用jx,不符合本次測試場景,節點二,關閉service_name=jx
5)集群命令,關閉監聽注冊監聽的service資源,failed測試環境無法操作
由於集群資源歷史原因未注冊,因此無法通過集群命令關閉節點二中的,service "jx"資源
jx2:/u01/app/grid$ srvctl status service -d jx -s jx
PRCR-1001 : 資源 ora.jx.jx.svc 不存在
手工重新rac集群層面注冊service name
srvctl add service
-d <db_unique_name> 數據庫的唯一名稱
-s <service> 服務名
-r "<preferred_list>" 逗號分隔的首選實例列表
-a "<available_list>" 逗號分隔的備用實例列表
-P {NONE | BASIC | PRECONNECT} TAF 策略規范
BASIC: 是指在感知到節點故障時才創建到其他實例的連接。
PRECONNECT:是在最初建立連接時就同時建立到所有實例的連接,當發生故障時,立刻就可以切換到其他鏈路上。
jx2:/u01/app/oracle$ srvctl add service -d jx -s jx -r "jx1,jx2" -P BASIC
PRCD-1210 : 服務名jx不能與數據庫默認服務名jx相同
6)節點2監聽資源重啟
#錯誤示范,如下命令關閉集群所有監聽資源
jx2:/u01/app/grid$ srvctl stop listener
jx2:/u01/app/grid$ srvctl status listener
監聽程序 LISTENER 已啟用
監聽程序 LISTENER 未運行
jx2:/u01/app/grid$ srvctl start listener
jx2:/u01/app/grid$ crsctl stat res -t
ora.LISTENER.lsnr
ONLINE ONLINE jx1
ONLINE ONLINE jx2
#正確方式,關閉一個節點監聽資源
jx2:/u01/app/grid$ srvctl stop listener -help ,只關閉一個節點
jx2:/u01/app/grid$ srvctl stop listener -n jx2
jx2:/u01/app/grid$ crsctl stat res -t
ora.LISTENER.lsnr
ONLINE ONLINE jx1
OFFLINE OFFLINE jx2
再次啟動節點2 監聽資源
jx2:/u01/app/grid$ srvctl start listener -n jx2
jx2:/u01/app/grid$ srvctl status listener
監聽程序 LISTENER 已啟用
監聽程序 LISTENER 正在節點上運行: jx1,jx2
監聽節點2,重啟監聽程序,本以為節點2 service_name=jx2,節點2的監聽程序無法監聽jx服務名稱
Service "jx" has 1 instance(s).
Instance "jx2", status READY, has 1 handler(s) for this service...
Service "jx2" has 1 instance(s).
Instance "jx2", status READY, has 1 handler(s) for this service...
7)修改默認的jx這服務名,讓其不在節點2出現呢?
修改jx服務名,配置主備模式,平時只在節點一注冊,失敗,原因資源不存在
jx2:/u01/app/grid$ srvctl modify service -d jx -s jx -i jx1 -a jx2 -P basic
PRCR-1001 : 資源 ora.jx.jx.svc 不存在
jx2:/u01/app/grid$ srvctl remove service -d jx -s jx
PRCR-1001 : 資源 ora.jx.jx.svc 不存在
將節點一,也修改service_name,使用節點一的service_name 測試模擬實際報錯,不使用數據庫默認的Jx進行測試
8)通過集群命令增加一個service
讓jx這個服務名,正常情況下只在節點1,節點一shutdown,飄逸至備用節點2,實現實驗環境
jx2:/u01/app/oracle$ srvctl add service -d jx -s jx1 -r jx1 -a jx2 -P BASIC
jx2:/u01/app/oracle$ srvctl start service -d jx -s jx1
node1: listener status 資源狀態
Service "jx1" has 1 instance(s).
Instance "jx1", status READY, has 1 handler(s) for this service...
實驗環境確認
service_name node1=jx1 node2=jx2
監聽服務名 node1=jx,jx1 node2=jx,jx2
9)確認scan ip 在節點呢2上
jx2:/u01/app/11.2.0/grid/network/admin$ cat /etc/hosts
192.168.60.154 jx-scan
jx2:/u01/app/oracle$ /sbin/ifconfig -a
eth0:1 Link encap:Ethernet HWaddr 00:0C:29:8F:B5:EA
inet addr:192.168.60.154 Bcast:192.168.60.255 Mask:255.255.255.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
應用測試連接:無報錯,本次實驗還原失敗
jx2:/u01/app/oracle$ sqlplus sys/oracle@192.168.60.154:1521/jx1 as sysdba
jx1:/u01/app/oracle$ ps -ef|grep LOCAL
oracle 24139 1 0 17:55 ? 00:00:00 oraclejx1 (LOCAL=NO)
jx2:/u01/app/11.2.0/grid/network/admin$ ps -ef|grep LOCAL
失敗原因,猜測一,數據庫版本問題11.2.0.3 與11.2.0.4 版本存在差異
猜測二,service_name配置問題,本次測試使用的service_name是手工添加,與客戶生產環境service_name存在差異
10)集群關閉scan資源,啟動scan 資源再節點一提供服務
jx1:/u01/app/grid$ srvctl status scan
SCAN VIP scan1 已啟用
SCAN VIP scan1 正在節點 jx2 上運行
jx1:/u01/app/grid$ srvctl status scan_listener
SCAN 監聽程序 LISTENER_SCAN1 已啟用
SCAN 監聽程序 LISTENER_SCAN1 正在節點 jx2 上運行
jx1:/u01/app/grid$ crsctl stat res -t
ora.LISTENER_SCAN1.lsnr
1 ONLINE ONLINE jx2
jx1:/u01/app/grid$ srvctl relocate scan -i 1 -n jx1
jx1:/u01/app/grid$ srvctl status scan
SCAN VIP scan1 已啟用
SCAN VIP scan1 正在節點 jx1 上運行
jx1:/u01/app/grid$ srvctl status scan_listener
SCAN 監聽程序 LISTENER_SCAN1 已啟用
SCAN 監聽程序 LISTENER_SCAN1 正在節點 jx1 上運行
二、測試service_name 飄逸
數據庫默認service_name
測試db層,修改參數 sid 一個實例,數據庫shutdown,能否自動漂移
測試db層,修改所有實例都注冊相同service_name
修改集群service,主某個節點,主節點shutdown,service_name自動飄逸備用節點
1)數據庫默認service_name jx2:/u01/app/oracle$ sqlplus sys/oracle@192.168.60.154:1521/jx as sysdba SQL> 2)測試db層,修改參數 sid 一個實例,數據庫shutdown,能否自動漂移 測試jx2,使用的是數據庫參數修改命令,測試數據庫shutdown,節點一能否監聽注冊這個資源 節點2::關閉數據庫 測試連接節點2,失敗 jx2:/u01/app/oracle$ sqlplus sys/oracle@192.168.60.154:1521/jx2 as sysdba 服務名並沒有飄逸至節點一,因此節點一監聽程序無法注冊這個服務,帶來應用無法通過這個服務名稱進行訪問 3)測試db層,修改整個集群都存在service_name,則均被注冊,與數據庫默認service_name,同理無需注冊 4)測試集群編輯的service,能否切換 節點2:啟動數據庫 節點1:關閉數據庫
節點2集群alert日志記錄如下 2018-12-23 18:23:33.714: [crsd(2638)]CRS-2767:Resource state recovery not attempted for 'ora.jx.db' as its target state is OFFLINE 2018-12-23 19:06:19.865: [crsd(2638)]CRS-2765:Resource 'ora.jx.jx1.svc' has failed on server 'jx1'. 2018-12-23 19:06:19.865: [crsd(2638)]CRS-2771:Maximum restart attempts reached for resource 'ora.jx.jx1.svc'; will not restart. jx2:/u01/app/oracle$ lsnrctl status Service "jx1" has 1 instance(s). Instance "jx2", status READY, has 1 handler(s) for this service... jx2:/u01/app/oracle$ sqlplus sys/oracle@192.168.60.154:1521/jx1 as sysdba SQL> select spid from v$process where addr=(select paddr from v$session where sid=(select sid from v$mystat group by sid)
and username='SYS' and STATUS='ACTIVE'); SPID ------------------------------------------------ 28081 SQL> host ps -ef|grep 28081 oracle 28081 1 0 19:07 ? 00:00:00 oraclejx2 (LOCAL=NO)
三、測試集群管理service部分用法
查詢資源狀態
jx1:/u01/app/oracle$ srvctl status service -d jx -s jx1
服務 jx1 正在實例 jx1 上運行
添加service資源 手工重新rac集群層面注冊service name srvctl add service -d <db_unique_name> 數據庫的唯一名稱 -s <service> 服務名 -r "<preferred_list>" 逗號分隔的首選實例列表 -a "<available_list>" 逗號分隔的備用實例列表 -P {NONE | BASIC | PRECONNECT} TAF 策略規范 BASIC: 是指在感知到節點故障時才創建到其他實例的連接。 PRECONNECT:是在最初建立連接時就同時建立到所有實例的連接,當發生故障時,立刻就可以切換到其他鏈路上。 jx2:/u01/app/oracle$ srvctl add service -d jx -s jx3 -r "jx1,jx2" -P BASIC 啟動添加的集群服務
srvctl start service -d jx -s jx3
--對應數據庫alert,最終還是修改service_name參數,但是集群層面可以實現,主備模式,手工修改數據庫參數無法實現主備
Sun Dec 23 19:27:52 2018
ALTER SYSTEM SET service_names='jx1','jx3' SCOPE=MEMORY SID='jx1';
關閉服務
jx1:/u01/app/oracle$ srvctl stop service -d jx -s jx3 -i jx1
jx1:/u01/app/oracle$ srvctl stop service -d jx -s jx3 -i jx2
刪除服務
jx1:/u01/app/oracle$ srvctl remove service -d jx -s jx3
讓jx這個服務名,正常情況下只在節點1,節點一shutdown,飄逸至備用節點2,實現實驗環境
jx2:/u01/app/oracle$ srvctl add service -d jx -s jx4 -r jx1 -a jx2 -P BASIC
jx2:/u01/app/oracle$ srvctl start service -d jx -s jx4
資源回切
jx1:/u01/app/oracle$ srvctl relocate service -d jx -s jx4 -i jx1 -t jx2
jx1:/u01/app/oracle$ srvctl relocate service -d jx -s jx4 -i jx2 -t jx1
修正,添加SCAN啟動方式
srvctl start scan_listener 啟動方式: 默認啟動節點1,使用-i 指定第幾個scan_listener默認scan_listener1,使用-n 指定節點名稱,可以在指定節點啟動scn srvctl start scan 啟動方式: 默認啟動節點1,使用-i 指定第幾個scan_listener默認scan_listener1,使用-n 指定節點名稱,可以在指定節點啟動scn 關閉scan_listener方式: 可以在scan_listener注冊的節點使用lsnrctl stop scan_listener1 or srvctl stop scan_listener -i 1 (1->scan_listener1) or srvctl stop scan -i 1 -f 將另一個節點(節點二jx2)的scan_listener1漂移到本地jx1進行注冊 srvctl relocate scan -i 1 -n jx1
