ORACLE會話鏈接進程三者總結

概念介紹html

     通俗來說,會話(Session) 是通訊雙方從開始通訊到通訊結束期間的一個上下文(Context)。這個上下文是一段位於服務器端的內存:記錄了本次鏈接的客戶端機器、經過哪一個應用程序、哪一個用戶登陸等信息.java

 

     鏈接(Connection):鏈接是從客戶端到ORACLE實例的一條物理路徑。鏈接能夠在網絡上創建,或者在本機經過IPC機制創建。一般會在客戶端進程與一個專用服務器或一個調度器之間創建鏈接。sql

 

     會話(Session) 是和鏈接(Connection)是同時創建的,二者是對同一件事情不一樣層次的描述。簡單講,鏈接(Connection)是物理上的客戶端同服務器的通訊鏈路,會話(Session)是邏輯上的用戶同服務器的通訊交互。數據庫

 

     ORACLE中一個用戶登陸ORACLE服務器的前提,就是該用戶具備ORACLE的 「CREATE SESSION」權限。ORACE容許同一個用戶在同一個客戶機上創建多個同服務器的會話,每一個SESSION都表明了用戶與服務器的一個交互。就像你用IE瀏覽器打開博客園網站,而後你再打開一個IE窗口,又打開一個博客園網站。兩個IE窗口就至關於兩個SESSION, 而物理鏈路就至關於鏈接(Connection)。後臺進程PMON會每隔一段時間,就會檢測用戶鏈接情況,若是鏈接已斷開,PMON會清理現場,釋放相關的資源。c#

     在一條鏈接上能夠創建0個、一個或多個會話。各個會話是單獨並且獨立的,即便它們共享同一條數據庫物理鏈接也是如此。一個會話中的提交不會影響該鏈接上的任何其餘會話。實際上,還能夠有鏈接而無相應的會話。另外,一個會話能夠有鏈接也能夠沒有鏈接。使用高級Oracle Net特性(如鏈接池)時,客戶能夠刪除一條物理鏈接,而會話依然保留(可是會話會空閒)。客戶在這個會話上執行某個操做時,它會從新創建物理鏈接。瀏覽器

    在專用服務器中,一個會話對應一個服務器進程(Process),若是數據庫運行在共享服務器方式,一個服務器進程能夠爲多個會話服務。服務器

下面是一段關於鏈接(connection)、會話、進程的英文描述網絡

A connection is a physical circuit between you and the database. A connection might be one of many types -- most popular begin DEDICATED server and SHARED server. Zero, one or more sessions may be established over a given connection to the database as show above with sqlplus. A process will be used by a session to execute statements. Sometimes there is a one to one relationship between CONNECTION->SESSION->PROCESS (eg: a normal dedicated server connection). Sometimes there is a one to many from connection to sessions (eg: like autotrace, one connection, two sessions, one process).session

A process does not have to be dedicated to a specific connection or session however, for example when using shared server (MTS), your SESSION will grab a process from a pool of processes in order to execute a statement. When the call is over, that process is released back to the pool of processes.工具

 

會話&連接

 

在具體的應用場景中鏈接(connction) 和 會話(session) 有不少狀況:

1. SQL*PLUS 登陸 ORACLE

這種場景比較容易理解,一個鏈接對應一個Session。

2. PL/SQL Developer工具登陸ORACLE

PL/SQL Developer工具——>首選項——>鏈接下,你能夠設置會話方式,以下圖所示:

 

若是設置選項選擇多路會話,:PL/SQL Developer 登陸ORACLE,每打開一個窗口,將建立一個新的會話,而設置選項選擇單路會話,則新打開的窗口會共用一個會話。具體你能夠參考PLSQL Developer8.0用戶指南:

多路會話:每一個測試窗口、SQL窗口和命令窗口都將有它本身的會話,另外的一個會話將被用於編譯。這是最靈活的設置,明顯地會致使最大數量的數據庫會話。另外可能的缺點是,在更新被提交以後,它們只在X窗口中能夠看到,而在Y窗口看不到。

雙路會話:測試窗口、SQL窗口和命令窗口將共享一個會話,另一個會話將被用於編譯。這個模式的缺點是每次只有一個窗口能夠運行程序。

單路會話:全部的窗口和全部的編譯都使用同一個會話,這使事務管理變得很困難。在這個模式中調試器被禁用使用。若是你被限制只能使用一個數據庫會話,那麼你只能使用這個設置了。

 

會話&進程

 

 

在Oracle中如何查看參數sessiones或processes的值呢?通常使用show parameter命令查看。

SQL> show parameter processes;
 
NAME                                 TYPE                             VALUE
------------------------------------ -------------------------------- ---------------
aq_tm_processes                      integer                          0
db_writer_processes                  integer                          1
gcs_server_processes                 integer                          0
job_queue_processes                  integer                          10
log_archive_max_processes            integer                          2
processes                            integer                          850
SQL> show parameter session;
 
NAME                                 TYPE                             VALUE
------------------------------------ -------------------------------- -----------
java_max_sessionspace_size           integer                          0
java_soft_sessionspace_limit         integer                          0
license_max_sessions                 integer                          0
license_sessions_warning             integer                          0
logmnr_max_persistent_sessions       integer                          1
session_cached_cursors               integer                          20
session_max_open_files               integer                          10
sessions                             integer                          940
shared_server_sessions               integer
SQL>

方法2:查詢v$parameter

select name, type, value ,display_value, isses_modifiable, issys_modifiable
from v$parameter
 where name='sessions';
 
 
select name, type, value ,display_value, isses_modifiable, issys_modifiable
from v$parameter
 where name='processes';

 

方法3:查詢v$resource_limit;

 

 

 

Oracle的sessions和processes的數量關係是:

Oracle 11g R1以及以前版本

             sessions=(1.1 * processes) + 5

Oracle 11g R2

             sessions=(1.5 * processes) + 22

以下例子所示,在Oracle 10g 版本中,processes與sessions的關係以下所示:

SQL> select * from v$version;
 
BANNER
----------------------------------------------------------------
Oracle Database 10g Release 10.2.0.4.0 - 64bit Production
PL/SQL Release 10.2.0.4.0 - Production
CORE    10.2.0.4.0      Production
TNS for Linux: Version 10.2.0.4.0 - Production
NLSRTL Version 10.2.0.4.0 - Production

 

 

SELECT (1.1 *850)+ 5 FROM DUAL; 其值恰好爲940

 

通常修改參數processes後,sessions參數也會隨之變化,可是有一個奇怪的現象時,以下所示,我將processes從

850改成120後,重啓數據庫實例,發現sessions的值並無隨之變化。這個現象通常發生在改小processes參數。爲何這樣呢?

 

 

共享服務器模式,一個會話可能由多個服務進程輪流爲之服務,一個進程可能爲多個會話服務。簡單地說,進程和會話之間有一種多對多的關係。

 

會話管理

 

1:查看當前全部用戶的會話(SESSION):

SELECT * FROM V$SESSION 
WHERE USERNAME IS NOT NULL
ORDER BY LOGON_TIME , SID;

其中Oracle內部進程的USERNAME爲空

 

2:查看當前用戶的全部SESSION:

SELECT * FROM V$SESSION
WHERE USERNAME = USER
ORDER BY LOGON_TIME, SID;

 

3:查看當前窗口/當前用戶的會話信息

SELECT SID, SERIAL#, STATUS FROM V$SESSION WHERE AUDSID=USERENV('SESSIONID');

 

4:查看全部ACTIVE會話(活動會話)

SELECT * FROM V$SESSION 
WHERE USERNAME IS NOT NULL AND STATUS='ACTIVE'
ORDER BY LOGON_TIME, SID;

 

5:查看當前會話的ID能夠經過以下腳本:

SELECT * FROM V$MYSTAT WHERE ROWNUM =1

查看當前用戶的SPID

SELECT P.SPID, S.SID, S.SERIAL#
FROM V$PROCESS P
INNER JOIN V$SESSION S ON P.ADDR = S.PADDR
WHERE S.AUDSID=USERENV('SESSIONID');

 

6:查看數據庫容許最大會話數

SQL> SHOW PARAMETER SESSIONS;
 
NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
java_max_sessionspace_size           integer     0
java_soft_sessionspace_limit         integer     0
license_max_sessions                 integer     0
license_sessions_warning             integer     0
logmnr_max_persistent_sessions       integer     1
sessions                             integer     225
shared_server_sessions               integer    
 
 
SQL> SELECT NAME, TYPE, VALUE FROM V$PARAMETER WHERE NAME LIKE 'session%';
 
NAME                       TYPE                 VALUE
---------                 ----------             -----------
sessions                          3                225
session_cached_cursors            3                20
session_max_open_files            3                10

7:查看曾經的最大會話數:

 
SQL>
SQL> SELECT SESSIONS_MAX,SESSIONS_WARNING,SESSIONS_CURRENT,SESSIONS_HIGHWATER 
  2  FROM v$license;
 
SESSIONS_MAX SESSIONS_WARNING SESSIONS_CURRENT SESSIONS_HIGHWATER
------------ ---------------- ---------------- ------------------
           0                0              512                553

SESSIONS_HIGHWATER表示曾經的最大會話數512

 

8:查詢那些應用的鏈接數此時是多少

SELECT  B.PROGRAM , COUNT(1)
FROM V$PROCESS A, V$SESSION B
WHERE A.ADDR = B.PADDR
      AND  B.USERNAME IS NOT NULL
GROUP BY B.PROGRAM;

 

會話狀態:

會話有ACTIVE、INACTIVE、KILLED、CACHED、SNIPED五個狀態,通常比較常見的有ACTIVE、INACTIVE、KILLED三個狀態。

 

ACTIVE   :處於此狀態的會話,表示正在執行,處於活動狀態。

INACTIVE :處於此狀態的會話表示不是正在執行的

KILLED   :處於此狀態的會話,表示出現了錯誤或進程被殺掉,正在回滾,固然,這個狀態的會話也佔用系統資源的。還有一點就是,    KILLED的狀態通常會持續較長時間,若是你想快速殺掉回話,能夠參考我之前的一篇文章ORACLE快速完全Kill掉的會話

CACHED   : Session temporarily cached for use by Oracle*XA

SNIPED   : Session inactive, waiting on the client。 標記爲SNIPED的進程被釋放有兩種條件:

         一、相關的terminal再一次試圖登陸及執行sql

         二、手動的在操做系統後臺kill掉相應的spid

關於會話信息

經過以下SQL你能夠查詢你的每一個應用程序到底在等待什麼,從而針對這些信息對數據庫的性能進行調整。

COL USERNAME FOR A12;
COL PROGRAM  FOR A32;
COL EVENT    FOR A26;
SELECT S.USERNAME
      ,S.PROGRAM
      ,S.STATUS
      ,SE.EVENT
      ,SE.TOTAL_WAITS
      ,SE.TOTAL_TIMEOUTS
      ,SE.TIME_WAITED
      ,SE.AVERAGE_WAIT
FROM V$SESSION S, V$SESSION_EVENT SE
WHERE S.SID=SE.SID AND SE.EVENT NOT LIKE 'SQL*Net%'
  AND S.STATUS ='ACTIVE' AND S.USERNAME IS NOT NULL;

 

2.ORACLE中查詢被鎖的表並釋放session

SELECT A.OWNER
  ,A.OBJECT_NAME
  ,B.XIDUSN
  ,B.XIDSLOT
  ,B.XIDSQN
  ,B.SESSION_ID
  ,B.ORACLE_USERNAME
  ,B.OS_USER_NAME
  ,B.PROCESS
  ,B.LOCKED_MODE
  ,C.MACHINE
  ,C.STATUS
  ,C.SERVER
  ,C.SID
  ,C.SERIAL#
  ,C.PROGRAM
FROM ALL_OBJECTS A,V$LOCKED_OBJECT B,SYS.GV_$SESSION C
WHERE  A.OBJECT_ID = B.OBJECT_ID  AND B.PROCESS = C.PROCESS  ORDER BY 1,2;

 

3.查看佔用系統IO較大的session

SELECT se.sid
      ,se.serial#
      ,pr.spid
      ,se.username
      ,se.status
      ,se.terminal
      ,se.program
      ,se.module
      ,se.sql_address
      ,st.event
      ,st.p1text
      ,si.physical_reads
      ,si.block_changes
FROM v$session se,v$session_wait st,v$sess_io si,v$process pr
WHERE st.sid=se.sid  AND st.sid=si.sid
  AND se.paddr=pr.ADDR AND se.sid>6
  AND st.wait_time=0 AND st.event NOT LIKE '%SQL%' 
  ORDER BY physical_reads DESC;

 

4.找出耗cpu較多的session

select a.sid
      ,spid
      ,status
      ,substr(a.program,1,40) prog
      ,a.terminal
      ,osuser
      ,value/60/100 value
from v$session a,v$process b,v$sesstat c
where c.statistic#=12 and c.sid=a.sid and a.paddr=b.addr
   order by value desc
相關文章
相關標籤/搜索