數(shù)據(jù)庫故障oracle與防火墻
最近有兩次Oracle數(shù)據(jù)庫故障與防火墻有關(guān)。
最近有兩次Oracle數(shù)據(jù)庫故障與防火墻有關(guān)。這里的防火墻是硬件網(wǎng)絡(luò)防火墻,而不是軟件防火墻。
先說說簡單的。一個運(yùn)行在Windows系統(tǒng)上的Oracle 9i,客戶端不能連接數(shù)據(jù)庫,但是用tnsping測試沒有問題。解決問題的辦法很簡單,但是我們?nèi)匀恍枰私庖幌乱疬@個問題的原因。
這個問題首先得從客戶通通過監(jiān)聽連接數(shù)據(jù)庫的整個過程說起,此處指專用服務(wù)器連接模式:
服務(wù)器上的監(jiān)聽進(jìn)程在1521端口上進(jìn)行偵聽
客戶端發(fā)起一個數(shù)據(jù)庫連接請求
監(jiān)聽進(jìn)程fork一個Oracle服務(wù)器進(jìn)程(Server Process),也可稱之為影子進(jìn)程 (Shadow Process)。服務(wù)器進(jìn)程選擇一個大于1024的端口號進(jìn)行偵聽,監(jiān)聽進(jìn)程把這個端口號發(fā)回到客戶端,要求客戶端重新連接這個指定的端口。
客戶端重新連接監(jiān)聽指定的新端口,也就是重新進(jìn)行連接。
客戶端與Server Process直接對話,不再通過監(jiān)聽,進(jìn)行會話認(rèn)證(登錄),執(zhí)行SQL等等。
從上述過程可以看到,客戶端最終連接的端口實(shí)際上并不是1521。由于防火墻一般只開放了幾個端口,對Oracle數(shù)據(jù)庫只開放了1521端口,這樣在客戶端進(jìn)行第二次連接時,不能通過防火墻,導(dǎo)致連接數(shù)據(jù)庫失敗。
值得慶幸的是,只有Windows平臺上的9i及以下版本的Oracle才會有這個問題。Oracle在Linux以及Unix平臺下,多個進(jìn)程間可以對端口進(jìn)行復(fù)用,Oracle Server Process仍然使用的是跟監(jiān)聽進(jìn)程一個端口(1521)。通過在linux使用strace跟蹤客戶端連接數(shù)據(jù)庫的過程可以發(fā)現(xiàn),客戶端只連接了一次,并沒有進(jìn)行第二次連接,與上面描述的流程相比已經(jīng)發(fā)生了變化。在Windows平臺上,10g及以上版本的庫,也同樣利用端口復(fù)用,避免了這樣的問題。
那么Windows上運(yùn)行的Oracle 9i怎么解決這個問題呢?答案很簡單,在Windows注冊表的\HKEY_LOCAL_MACHINE\SOFTWARE\ORACLE\HOMEn(這里n指Oracle Home的序號,只有一個Oracle Home時是0)鍵下面增加一項(xiàng)USE_SHARED_SOCKET,其值為TRUE。然后重啟監(jiān)聽及Oracle服務(wù)(注意要重啟Oracle的服務(wù),而不僅僅是重啟數(shù)據(jù)庫),就可以解決此問題。實(shí)際上10g就是默認(rèn)USE_SHARED_SOCKET為TRUE。
對于這種問題,或者是讓防火墻打開針對數(shù)據(jù)庫主機(jī)的所有端口訪問,也能解決。但是這種方案往往會被負(fù)責(zé)安全的人否決。
下面這個由防火墻導(dǎo)致的問題,就相對復(fù)雜一點(diǎn)了。
某個應(yīng)用經(jīng)常報ORA-3113錯誤,檢查發(fā)現(xiàn)ORA-3113來源于數(shù)據(jù)庫的一個db link。為了方便下面的描述,將應(yīng)用直接連接的數(shù)據(jù)庫稱為DB_A,DB_A通過db link連接的對端的數(shù)據(jù)庫稱為DB_B。在DB_B主機(jī)上沒有發(fā)現(xiàn)任何有關(guān)的trace和日志,應(yīng)用執(zhí)行的SQL也是非常簡單的SELECT語句,返回的數(shù)據(jù)量也不大。但出錯的語句并不是固定的某一個SQL。在應(yīng)用連接的數(shù)據(jù)庫DB_A上做ORA-3113 error stack的trace,也沒有發(fā)現(xiàn)有價值的東西。
導(dǎo)致ORA-3113錯誤的原因很多。大家可以參考ITPUB上的一篇貼子《ORA-03113錯誤分析》。
在這個ORA-3113錯誤的問題中,數(shù)據(jù)庫DB_B沒有任何日志,出現(xiàn)這種情況的一個很可能的原因是,DB_B上的Server Process已經(jīng)中止,但又不是在執(zhí)行SQL過程中出錯異常中止了,比如被KILL掉,網(wǎng)絡(luò)連接中斷等。被KILL掉這個原因,首先被排除,因?yàn)檫@個錯誤出現(xiàn)得很多,每天都有。詢問維護(hù)人員,稱也沒有進(jìn)行過KILL操作。那么最大的可能性應(yīng)該是網(wǎng)絡(luò)了。順著這條線索,我們在DB_A上用netstat -na命令檢查到DB_B的網(wǎng)絡(luò)連接,與DB_B中v$session中的會話進(jìn)行比較,發(fā)現(xiàn)DB_A連接到DB_B的數(shù)據(jù)庫會話,比netstat 命令看到的網(wǎng)絡(luò)連接數(shù)少得多。
這是一個重大的突破。首先要懷疑的是防火墻。因?yàn)榉阑饓?dǎo)致Oracle連接異常的情況非常多。訪問數(shù)據(jù)庫的DBA,這兩個數(shù)據(jù)庫分別在不同的業(yè)務(wù)網(wǎng)絡(luò)中,中間使用了Cisco的防火墻。請防火墻維護(hù)工程師檢查防火墻的設(shè)置,發(fā)現(xiàn)防火墻設(shè)置了TCP連接超時(這個術(shù)語是防火墻工程師告訴給我的,實(shí)際上我個人認(rèn)為這個術(shù)語字面含義跟其實(shí)際的作用相差較大)設(shè)置為1小時。也就是,對于通過防火墻的所有TCP連接,如果在1小時內(nèi)沒有任何活動,就會被防火墻拆除,這樣就會導(dǎo)致連接中斷。在拆除連接時,也不會向連接的兩端發(fā)送任何數(shù)據(jù)來通知連接已經(jīng)拆除。
而出問題的業(yè)務(wù)系統(tǒng),使用的高峰期是在正常的工作時間內(nèi),最高時會導(dǎo)致DB_A會產(chǎn)生數(shù)十個連接到DB_B。但是在業(yè)務(wù)低谷期或經(jīng)過一個晚上,防火墻將拆除大部分甚至是所有的連接。而下一次使用時,應(yīng)用通過連接池選擇DB_A中的一個會話,這個會話的db link之前已經(jīng)連接到DB_B,但是網(wǎng)絡(luò)連接已經(jīng)被防火墻拆除,但是這個會話并不知道,仍然會認(rèn)為這個連接有效,結(jié)果試圖向DB_B提交SQL時,就出現(xiàn)了ORA-3113錯誤。
實(shí)際上,很多使用網(wǎng)絡(luò)連接的應(yīng)用,可以使用稱之為KeepAlive的特性,來保持TCP連接的活動性。在打開一個連接時,通過setsockopt函數(shù),設(shè)置socket為SO_KEEPALIVE,這樣,在OS層,如果一個TCP連接在指定的時間內(nèi)沒有活動,會發(fā)送一個探測包到連接的對端,檢測連接的對端是否仍然存在。如果這個時間小于防火墻中設(shè)置的“超時”時間,防火墻就會檢查到連接中仍然有數(shù)據(jù),就不會斷開這個連接。
操作系統(tǒng)中keep alive的相關(guān)設(shè)置,不同的系統(tǒng)有不同的設(shè)置方法。比如在Linux中,在sysctl中設(shè)置net.ipv4.tcp_keepalive_time = 120,表示探測時間為120秒,即2分鐘。在AIX中,通過no命令將tcp_keepidle參數(shù)設(shè)置為240,表示探測時間為120秒。注意AIX中這個參數(shù)的單位是1/2秒,而在Linux中是1秒。
還好Oracle提供了類似的機(jī)制。也就是DCD(Dead Conneciton Detection)。在$ORACLE_HOME/network/admin/sqlnet.ora文件中增加如下一行:
expire_time=NNN
這里NNN為分鐘數(shù),Oracle數(shù)據(jù)庫會在會話IDLE時間超過這個指定的時間時,檢測這個會話的對端(即客戶端)是否還有效。避免客戶端由于異常退出,導(dǎo)致會話一直存在。
因此,我們可以通過在DB_B數(shù)據(jù)庫中的sqlnet.ora文件中設(shè)置expire_time來解決上面提到的ORA-3113問題。
先說說簡單的。一個運(yùn)行在Windows系統(tǒng)上的Oracle 9i,客戶端不能連接數(shù)據(jù)庫,但是用tnsping測試沒有問題。解決問題的辦法很簡單,但是我們?nèi)匀恍枰私庖幌乱疬@個問題的原因。
這個問題首先得從客戶通通過監(jiān)聽連接數(shù)據(jù)庫的整個過程說起,此處指專用服務(wù)器連接模式:
服務(wù)器上的監(jiān)聽進(jìn)程在1521端口上進(jìn)行偵聽
客戶端發(fā)起一個數(shù)據(jù)庫連接請求
監(jiān)聽進(jìn)程fork一個Oracle服務(wù)器進(jìn)程(Server Process),也可稱之為影子進(jìn)程 (Shadow Process)。服務(wù)器進(jìn)程選擇一個大于1024的端口號進(jìn)行偵聽,監(jiān)聽進(jìn)程把這個端口號發(fā)回到客戶端,要求客戶端重新連接這個指定的端口。
客戶端重新連接監(jiān)聽指定的新端口,也就是重新進(jìn)行連接。
客戶端與Server Process直接對話,不再通過監(jiān)聽,進(jìn)行會話認(rèn)證(登錄),執(zhí)行SQL等等。
從上述過程可以看到,客戶端最終連接的端口實(shí)際上并不是1521。由于防火墻一般只開放了幾個端口,對Oracle數(shù)據(jù)庫只開放了1521端口,這樣在客戶端進(jìn)行第二次連接時,不能通過防火墻,導(dǎo)致連接數(shù)據(jù)庫失敗。
值得慶幸的是,只有Windows平臺上的9i及以下版本的Oracle才會有這個問題。Oracle在Linux以及Unix平臺下,多個進(jìn)程間可以對端口進(jìn)行復(fù)用,Oracle Server Process仍然使用的是跟監(jiān)聽進(jìn)程一個端口(1521)。通過在linux使用strace跟蹤客戶端連接數(shù)據(jù)庫的過程可以發(fā)現(xiàn),客戶端只連接了一次,并沒有進(jìn)行第二次連接,與上面描述的流程相比已經(jīng)發(fā)生了變化。在Windows平臺上,10g及以上版本的庫,也同樣利用端口復(fù)用,避免了這樣的問題。
那么Windows上運(yùn)行的Oracle 9i怎么解決這個問題呢?答案很簡單,在Windows注冊表的\HKEY_LOCAL_MACHINE\SOFTWARE\ORACLE\HOMEn(這里n指Oracle Home的序號,只有一個Oracle Home時是0)鍵下面增加一項(xiàng)USE_SHARED_SOCKET,其值為TRUE。然后重啟監(jiān)聽及Oracle服務(wù)(注意要重啟Oracle的服務(wù),而不僅僅是重啟數(shù)據(jù)庫),就可以解決此問題。實(shí)際上10g就是默認(rèn)USE_SHARED_SOCKET為TRUE。
對于這種問題,或者是讓防火墻打開針對數(shù)據(jù)庫主機(jī)的所有端口訪問,也能解決。但是這種方案往往會被負(fù)責(zé)安全的人否決。
下面這個由防火墻導(dǎo)致的問題,就相對復(fù)雜一點(diǎn)了。
某個應(yīng)用經(jīng)常報ORA-3113錯誤,檢查發(fā)現(xiàn)ORA-3113來源于數(shù)據(jù)庫的一個db link。為了方便下面的描述,將應(yīng)用直接連接的數(shù)據(jù)庫稱為DB_A,DB_A通過db link連接的對端的數(shù)據(jù)庫稱為DB_B。在DB_B主機(jī)上沒有發(fā)現(xiàn)任何有關(guān)的trace和日志,應(yīng)用執(zhí)行的SQL也是非常簡單的SELECT語句,返回的數(shù)據(jù)量也不大。但出錯的語句并不是固定的某一個SQL。在應(yīng)用連接的數(shù)據(jù)庫DB_A上做ORA-3113 error stack的trace,也沒有發(fā)現(xiàn)有價值的東西。
導(dǎo)致ORA-3113錯誤的原因很多。大家可以參考ITPUB上的一篇貼子《ORA-03113錯誤分析》。
在這個ORA-3113錯誤的問題中,數(shù)據(jù)庫DB_B沒有任何日志,出現(xiàn)這種情況的一個很可能的原因是,DB_B上的Server Process已經(jīng)中止,但又不是在執(zhí)行SQL過程中出錯異常中止了,比如被KILL掉,網(wǎng)絡(luò)連接中斷等。被KILL掉這個原因,首先被排除,因?yàn)檫@個錯誤出現(xiàn)得很多,每天都有。詢問維護(hù)人員,稱也沒有進(jìn)行過KILL操作。那么最大的可能性應(yīng)該是網(wǎng)絡(luò)了。順著這條線索,我們在DB_A上用netstat -na命令檢查到DB_B的網(wǎng)絡(luò)連接,與DB_B中v$session中的會話進(jìn)行比較,發(fā)現(xiàn)DB_A連接到DB_B的數(shù)據(jù)庫會話,比netstat 命令看到的網(wǎng)絡(luò)連接數(shù)少得多。
這是一個重大的突破。首先要懷疑的是防火墻。因?yàn)榉阑饓?dǎo)致Oracle連接異常的情況非常多。訪問數(shù)據(jù)庫的DBA,這兩個數(shù)據(jù)庫分別在不同的業(yè)務(wù)網(wǎng)絡(luò)中,中間使用了Cisco的防火墻。請防火墻維護(hù)工程師檢查防火墻的設(shè)置,發(fā)現(xiàn)防火墻設(shè)置了TCP連接超時(這個術(shù)語是防火墻工程師告訴給我的,實(shí)際上我個人認(rèn)為這個術(shù)語字面含義跟其實(shí)際的作用相差較大)設(shè)置為1小時。也就是,對于通過防火墻的所有TCP連接,如果在1小時內(nèi)沒有任何活動,就會被防火墻拆除,這樣就會導(dǎo)致連接中斷。在拆除連接時,也不會向連接的兩端發(fā)送任何數(shù)據(jù)來通知連接已經(jīng)拆除。
而出問題的業(yè)務(wù)系統(tǒng),使用的高峰期是在正常的工作時間內(nèi),最高時會導(dǎo)致DB_A會產(chǎn)生數(shù)十個連接到DB_B。但是在業(yè)務(wù)低谷期或經(jīng)過一個晚上,防火墻將拆除大部分甚至是所有的連接。而下一次使用時,應(yīng)用通過連接池選擇DB_A中的一個會話,這個會話的db link之前已經(jīng)連接到DB_B,但是網(wǎng)絡(luò)連接已經(jīng)被防火墻拆除,但是這個會話并不知道,仍然會認(rèn)為這個連接有效,結(jié)果試圖向DB_B提交SQL時,就出現(xiàn)了ORA-3113錯誤。
實(shí)際上,很多使用網(wǎng)絡(luò)連接的應(yīng)用,可以使用稱之為KeepAlive的特性,來保持TCP連接的活動性。在打開一個連接時,通過setsockopt函數(shù),設(shè)置socket為SO_KEEPALIVE,這樣,在OS層,如果一個TCP連接在指定的時間內(nèi)沒有活動,會發(fā)送一個探測包到連接的對端,檢測連接的對端是否仍然存在。如果這個時間小于防火墻中設(shè)置的“超時”時間,防火墻就會檢查到連接中仍然有數(shù)據(jù),就不會斷開這個連接。
操作系統(tǒng)中keep alive的相關(guān)設(shè)置,不同的系統(tǒng)有不同的設(shè)置方法。比如在Linux中,在sysctl中設(shè)置net.ipv4.tcp_keepalive_time = 120,表示探測時間為120秒,即2分鐘。在AIX中,通過no命令將tcp_keepidle參數(shù)設(shè)置為240,表示探測時間為120秒。注意AIX中這個參數(shù)的單位是1/2秒,而在Linux中是1秒。
還好Oracle提供了類似的機(jī)制。也就是DCD(Dead Conneciton Detection)。在$ORACLE_HOME/network/admin/sqlnet.ora文件中增加如下一行:
expire_time=NNN
這里NNN為分鐘數(shù),Oracle數(shù)據(jù)庫會在會話IDLE時間超過這個指定的時間時,檢測這個會話的對端(即客戶端)是否還有效。避免客戶端由于異常退出,導(dǎo)致會話一直存在。
因此,我們可以通過在DB_B數(shù)據(jù)庫中的sqlnet.ora文件中設(shè)置expire_time來解決上面提到的ORA-3113問題。

責(zé)任編輯:和碩涵
免責(zé)聲明:本文僅代表作者個人觀點(diǎn),與本站無關(guān)。其原創(chuàng)性以及文中陳述文字和內(nèi)容未經(jīng)本站證實(shí),對本文以及其中全部或者部分內(nèi)容、文字的真實(shí)性、完整性、及時性本站不作任何保證或承諾,請讀者僅作參考,并請自行核實(shí)相關(guān)內(nèi)容。
我要收藏
個贊
-
發(fā)電電力輔助服務(wù)營銷決策模型
2019-06-24電力輔助服務(wù)營銷 -
電力線路安全工作的組織措施和技術(shù)措施分別是什么?
-
兩會保電進(jìn)行時丨陜西電力部署6項(xiàng)重點(diǎn)任務(wù)
-
電力線路安全工作的組織措施和技術(shù)措施分別是什么?
-
兩會保電進(jìn)行時丨陜西電力部署6項(xiàng)重點(diǎn)任務(wù)
-
山東特高壓首次完成帶電消缺 確保電力安全穩(wěn)定迎峰度冬
-
發(fā)電電力輔助服務(wù)營銷決策模型
2019-06-24電力輔助服務(wù)營銷 -
繞過安卓SSL驗(yàn)證證書的四種方式
-
網(wǎng)絡(luò)何以可能
2017-02-24網(wǎng)絡(luò)
-
Windows 10首發(fā) 四大安全提升
-
超級安卓漏洞 “寄生獸”影響數(shù)千萬手機(jī)應(yīng)用
-
航空公司首出現(xiàn)操作系統(tǒng)被黑
2015-06-23航空公司
-
“企業(yè)應(yīng)急響應(yīng)和反滲透”之真實(shí)案例分析
-
攜程恢復(fù)正常 安全,我們準(zhǔn)備好了嗎?
2015-05-29攜程 -
一張圖讀懂《2014年消費(fèi)者個人信息網(wǎng)絡(luò)安全報告》