案例分享|Oracle 11g RAC 數據庫鏈接數太高處理辦法

做者 | JiekeXu
java

來源 | JiekeXu之路(ID: JiekeXu_IT)
web

轉載請聯繫受權 | (微信ID:xxq1426321293)sql

你們好,我是 JiekeXu,很高興又和你們見面了,今天分享 Oracle 11g RAC 數據庫鏈接數太高處理辦法 本文發佈於微信公衆號【JiekeXu之路】,歡迎點擊上方藍字關注我,標星或置頂,更多幹貨第一時間到達!

前   言typescript


近期有一套數據庫老是出現以下告警 「嚴重告警:XXX Oracle 服務器:10.10.X.X 數據庫的偵聽器 LISTENER 狀態爲 Inactive 」.這樣的告警咱們已經家常便飯,要麼就是數據庫宕機,要麼就是監聽異常關閉,由於是 RAC 環境,又不是什麼很大問題,便鎮定自若的去處理此問題。數據庫


一 問題過程json


當登錄到數據庫檢查數據庫狀態無異常,查看監聽也是正常,那麼集羣資源狀態也是正常。查看數據庫後臺日誌時發現了錯誤 "ORA-00020:maximum number of processes(2000) exceeded" 鏈接數達到最大值 2000.查看當前數據庫最大鏈接數設置爲 2000,查看數據庫除後臺進程外兩節點數均爲 1940 多,外加 50 多個已經超出 2000 了。ruby


排查數據庫最大鏈接數和當前鏈接數
服務器

SQL> show parameter process 
NAME TYPE VALUE------------------------------------ ----------- ------------------------------aq_tm_processes integer 1cell_offload_processing boolean TRUEdb_writer_processes                  integer     8gcs_server_processes                 integer     4global_txn_processes integer 1job_queue_processes integer 1000log_archive_max_processes integer 4processes                            integer     2000processor_group_name string
SQL> select inst_id,status,count(*) from gv$session where type <> 'BACKGROUNND' group by inst_id,status order by 3;


從當前鏈接以及後臺日誌查看,INACTIVE 非活躍會話 1940 之多,但數據庫 CPU 內存等資源均正常,也沒有異常等待事件,不過下午已經出現過鏈接數太高的問題,根據經驗猜想應用系統的中間件鏈接池以及初始鏈接大小設置有問題,果不其而後面聯繫應用方確認沒有設置鏈接超時。微信


因爲此係統不是核心系統,活躍會話也只有三四個更沒有大事物,簡單查詢後便決定先殺掉鏈接恢復告警,但當時想要經過數據庫殺掉非活躍會話鏈接,但是經過 SID 和 SERIAL# 查殺時不少會話已經不存在了。那麼當時採起的辦法就是經過操做系統 kill 查殺了,又由於活躍會話不多無事務,便使用以下命令所有查殺了。session


注意:生產系統中謹慎操做,尤爲是有大事物時不能直接查殺。

ps -ef | grep LOCAL=NO | grep -v grep | awk '{print $2}' | wc -lps -ef | grep LOCAL=NO | grep -v grep | awk '{print $2}' | xargs kill -9

查殺後鏈接數降低數據庫告警恢復,算是告一段落了,沒有深刻問題根源。


二 問題復現


次日早上十點多,還在查看另外一系統的性能問題時,有人告知此係統又有問題,無疑又是鏈接數問題,登錄到系統後查看果不其然。兩個節點的鏈接數已達 1800 多,經過操做系統 kill -9 緊急殺掉會話後數據庫鏈接數降低,可是出現問題時還沒達到閾值,確定還有其餘沒有來得及的問題存在,這個便要後續排查了。

三 問題排查


發現此數據庫內存管理是自動管理的,SGA、PGA 設置的值不合理,當出現大量鏈接時,PGA  設置不合理,新的會話鏈接則會出現問題應用方反饋出性能問題;另外大量非活躍會話未釋放也沒有從數據庫端限制,未設置超時鏈接 SQLNET.EXPIRE_TIME 參數。

Dead Connection Detection(DCD)

SQLNET.EXPIRE_TIME: 設置 DCD 檢測時間爲 1 分鐘。指定時間間隔(以分鐘爲單位),以發送探測以驗證客戶端/服務端鏈接處於活動狀態。設置一個大於 0 的值可確保不會因爲客戶端異常終止而無限期地斷開鏈接。


Dead Connection Detection (DCD)與Inactive Sessions
https://blog.csdn.net/leshami/article/details/9188379
Dead Connection Detection (DCD)與Inactive Sessions
Dead connections: These are previously valid connections with the database but the connection between the client and server processes has terminated abnormally. Examples of a dead connection: - A user reboots/turns-off their machine without logging off or disconnecting from the database. - A network problem prevents communication between the client and the server.
In these cases, the shadow process running on the server and the session in the database may not terminate.
Implemented by * adding SQLNET.EXPIRE_TIME = <MINUTES> to the sqlnet.ora file
With DCD is enabled, the Server-side process sends a small 10-byte packet to the client process after the duration of the time interval specified in minutes by the SQLNET.EXPIRE_TIME parameter.
If the client side connection is still connected and responsive, the client sends a response packet back to the database server, resetting the timer..and another packet will be sent when next interval expires (assuming no other activity on the connection).
If the client fails to respond to the DCD probe packet * the Server side process is marked as a dead connection and * PMON performs the clean up of the database processes / resources * The client OS processes are terminated
NOTE: SQLNET.RECV_TIMEOUT can be set on the SERVER side sqlnet.ora file. This will set a timeout for the server process to wait for data from the client process.
Inactive Sessions: These are sessions that remain connected to the database with a status in v$session of INACTIVE. Example of an INACTIVE session: - A user starts a program/session, then leaves it running and idle for an extended period of time.

因而乎則在兩個節點中均設置 SQLNET.EXPIRE_TIME=1,這個參數在 RAC 中則須要設置到 Oracle 用戶下 $ORACLE_HOME/network/admin/sqlnet.ora 文件中,。還有個問題就是不肯定這個參數究竟是設置到哪一個用戶下的話,能夠Oracle、grid 兩個用戶都設置了總有一個會生效。

[oracle@JiekeXu ~]$ cd /u01/app/oracle/product/11.2.0/dbhome_1/network/admin/[oracle@JiekeXu admin]$ lltotal 16K-rw-r--r-- 1 oracle oinstall 378 May 18 2019 listener.oradrwxr-xr-x 2 oracle oinstall 4.0K Oct 27 2017 samples-rw-r--r-- 1 oracle oinstall 835 Feb 18 2019 shrept.lst-rw-r----- 1 oracle oinstall 332 May 18 2019 tnsnames.ora[oracle@JiekeXu admin]$ [oracle@JiekeXu admin]$ vi sqlnet.ora[oracle@JiekeXu admin]$ more sqlnet.ora SQLNET.EXPIRE_TIME=1DIAG_ADR_ENABLED=OFF

設置完後我這邊又經過數據庫殺掉了一些鏈接,經過拼接 SQL 殺掉一個小時前的非活躍會話及非後臺進程會話。可是發現數據庫中出現 KILLED 會話達 594 個。會話沒有獲得釋放,節點二便採用系統層面的 kill -9 殺掉會話。

select 'alter system kill session '''||sid||','||serial#||'''; 'from v$session s where s.STATUS='INACTIVE' and type <> 'BACKGROUND' and LOGON_TIME<=(sysdate-1/24);alter system kill session '59,19341';select inst_id,status, count(*) from gv$session where type <> 'BACKGROUND' group by inst_id,status order by 3;
14:03:19 SQL> alter system kill session '1938,3645';
System altered.……………………………省略部分……………………………14:03:19 SQL> alter system kill session '1943,3215';
System altered.
14:03:24 SQL> select 'alter system kill session '''||sid||','||serial#||'''; 'from v$session s where s.STATUS='INACTIVE' and type <> 'BACKGROUND' and LOGON_TIME<=(sysdate-1/24);
'ALTERSYSTEMKILLSESSION'''||SID||','||SERIAL#||''';'--------------------------------------------------------------------------------alter system kill session '59,19341';alter system kill session '458,3637';……………………………省略部分……………………………alter system kill session '1952,5867';alter system kill session '1971,2023';14:06:34 SQL> select inst_id,count(*) from gv$session group by inst_id;
INST_ID COUNT(*)---------- ----------1 11972 1194
14:06:40 SQL> select inst_id,status, count(*) from gv$session where type <> 'BACKGROUND' group by inst_id,status order by 3;
INST_ID STATUS COUNT(*)---------- -------- ----------2 ACTIVE 11 ACTIVE 41 INACTIVE 5431 KILLED 5942 INACTIVE 1138
節點 2 這裏又經過 kill -9 殺掉會話,節點 2 的非活躍會話獲得釋放,可是節點 1 的 KILLED 的會話仍是沒明顯的降低 。
SQL> select inst_id,status, count(*) from gv$session where type <> 'BACKGROUND' group by inst_id,status order by 3;
INST_ID STATUS COUNT(*)---------- -------- ----------1 ACTIVE 32 ACTIVE 41 INACTIVE 3971 KILLED 5922 INACTIVE 671

後面應用方根據建議設置了中間件 Weblogic 鏈接池超時爲 180s 最小鏈接數爲 1 後,節點一 KILLED 也獲得了釋放,數據庫的鏈接也降低到 400 左右了,算是一個正常範圍值。


內存調整


前面說過內存管理爲自動管理,這裏須要將其調整爲手動管理,因爲是生產環境不可以隨時重啓則須要停機窗口,這裏先將須要調整的內存參數以及合理的值列出來。

SQL> show parameter target
NAME TYPE VALUE------------------------------------ ----------- ------------------------------archive_lag_target integer 0db_flashback_retention_target integer 1440fast_start_io_target integer 0fast_start_mttr_target integer 0memory_max_target big integer 39168Mmemory_target big integer 39168Mparallel_servers_target integer 1024pga_aggregate_target big integer 0sga_target big integer 0SQL> show parameter sga
NAME TYPE VALUE------------------------------------ ----------- ------------------------------lock_sga boolean FALSEpre_page_sga boolean FALSEsga_max_size big integer 39168Msga_target big integer 0SQL> show parameter pga
NAME TYPE VALUE------------------------------------ ----------- ------------------------------pga_aggregate_target big integer 0SQL>SQL> select * from v$sgastat where name = 'free memory' and pool = 'shared pool';
POOL NAME BYTES------------ -------------------------- ----------shared pool free memory 856007376
--如下爲調整步驟sqlplus / as sysdba create pfile='/tmp/pfile1028.ora' from spfile;alter system set shared_pool_size=5G scope=spfile sid='*';alter system set db_cache_size=15G scope=spfile sid='*';alter system set large_pool_size=1G scope=spfile sid='*'alter system set java_pool_size=128M scope=spfile sid='*';alter system set streams_pool_size=256M scope=spfile sid='*';
alter system set memory_max_target=0 scope=spfile sid='*';alter system set memory_target=0 scope=spfile sid='*';
alter system set sga_max_size=30g scope=spfile sid='*';alter system set sga_target=30G scope=spfile sid='*';alter system set pga_aggregate_target=14G scope=spfile sid='*';

AIX 操做系統內存 64G,數據庫內存 38.25G,將其調整爲 30G,PGA 調整爲 14G,shared_pool 5G,db_cache 15G,large_pool 1G,java_pool 128G,streams_pool 256M。這些值都是一個近似的值,一個較爲合理的值,並不保證 100% 完美正確,在 AWR 報告中 Advisory Statistics 部分,也會有相關的建議值,以下即是一個較爲合理的 shared_pool 的值。設置完這些值後重啓數據庫系統,將會有一個很大的提高。


最後說一下利用 Profile 超時設置,這個沒有使用過,網上有方法便晚上回來測試一番 。

首先查詢數據庫是否開啓 resource limit 限制,若是沒有開啓,則開啓這個參數。

SYS@JiekeXu>col name format a15SYS@JiekeXu>col value format a10SYS@JiekeXu>SELECT name, value FROM gv$parameter WHERE name = 'resource_limit';
NAME VALUE--------------- ----------resource_limit FALSESYS@JiekeXu>set time on00:44:34 SYS@JiekeXu>00:44:35 SYS@JiekeXu>ALTER SYSTEM SET RESOURCE_LIMIT=TRUE;
System altered.
00:44:40 SYS@JiekeXu>SELECT name, value FROM gv$parameter WHERE name = 'resource_limit';
NAME VALUE--------------- ----------resource_limit  TRUE
--而後建立空閒 1 分鐘停止空閒例程的 Profile00:44:49 SYS@JiekeXu>CREATE PROFILE app_user LIMIT IDLE_TIME 1;
Profile created.--設置 scott 用戶的 Profile00:46:27 SYS@JiekeXu>alter user scott profile app_user;
User altered.--固然也可使用 默認的 Profile 00:46:58 SYS@JiekeXu>ALTER PROFILE DEFAULT LIMIT IDLE_TIME 1;
Profile altered.

而後使用客戶端工具 SQLPlus 遠程鏈接,查詢業務數據等待 1 分鐘後在繼續查詢則會報錯 ORA-02396。

[oracle@JiekeXu ~]$ more /u01/app/oracle/product/11.2.0/dbhome_1/network/admin/tnsnames.ora# tnsnames.ora Network Configuration File: /u01/app/oracle/product/11.2.0/dbhome_1/network/admin/tnsnames.ora# Generated by Oracle configuration tools.
JiekeXu = (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.3.101)(PORT = 1521)) (CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME = JiekeXu) ) )
[oracle@JiekeXu ~]$ sqlplus scott/scott@JiekeXu
SQL*Plus: Release 11.2.0.4.0 Production on Wed Oct 28 00:56:29 2020
Copyright (c) 1982, 2013, Oracle. All rights reserved.

Connected to:Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit ProductionWith the Partitioning, OLAP, Data Mining and Real Application Testing options
SCOTT@JiekeXu>set time on00:56:35 SCOTT@JiekeXu>select sysdate from dual;
SYSDATE---------28-OCT-20
00:56:45 SCOTT@JiekeXu>00:56:45 SCOTT@JiekeXu>select sysdate from dual;select sysdate from dual*ERROR at line 1:ORA-02396: exceeded maximum idle time, please connect again

01:12:48 SCOTT@JiekeXu>


今天的分享就到這裏了,若是本文對您有一點兒幫助,請多支持「在看」與轉發,不求小費了哪怕是一個小小的贊,您的鼓勵都將是我最大的動力,讓我有一直寫下去的動力,最後一塊兒加油,奧利給



Oracle 12c 及以上版本補丁更新說明及下載方法(收藏版)

Oracle 11.2.0.4 RAC 最新補丁下載(11.2.0.4.200714)

11g RAC 在線存儲遷移實現 OCR 磁盤組完美替換

如何經過 Shell 監控異常等待事件和活躍會話 

個人 OCM 之路|書寫無悔青春追夢永不止步

Oracle 19c 之多租戶 PDB 鏈接與訪問(三)

案例:RMAN 備份控制文件報錯 ORA-00230

Oracle 12C 最新補丁下載與安裝操做指北

DBA 經常使用的軟件工具備哪些(分享篇)?

Oracle 相關認證證書查詢及真僞辨別

Oracle 11g 臨時表空間管理

Oracle 每日一題系列合集


一鍵三連分享、在看與點贊」,給我充點兒電吧~

本文分享自微信公衆號 - JiekeXu之路(JiekeXu_IT)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。

相關文章
相關標籤/搜索