1 / 9
概念介紹
通俗來講,會話(Session) 是通信雙方從開始通信到通信結束期間的一個背景關系(Context)。這個背景關系是一段位于服務器端的記憶體:記錄了本次連接的客戶端機器、通過哪個應用程式、哪個用戶登錄等資訊.
連接(Connection):連接是從客戶端到ORACLE實體的一條物理路徑。連接可以在網路上建立,或者在本機通過IPC機制建立。通常會在客戶端行程與一個專用服務器或一個調度器之間建立連接。
會話(Session) 是和連接(Connection)是同時建立的,兩者是對同一件事情不同層次的描述。簡單講,連接(Connection)是物理上的客戶端同服務器的通信鏈路,會話(Session)是邏輯上的用戶同服務器的通信互動。
ORACLE中一個用戶登錄ORACLE服務器的前提,就是該用戶具有ORACLE的 “CREATE SESSION”權限。ORACE允許同一個用戶在同一個客戶機上建立多個同服務器的會話,每個SESSION都代表了用戶與服務器的一個互動。就像你用IE瀏覽器打開博客園網站,然后你再打開一個IE視窗,又打開一個博客園網站。兩個IE視窗就相當于兩個SESSION, 而物理鏈路就相當于連接(Connection)。后臺行程PMON會每隔一段時間,就會檢測用戶連接狀況,如果連接已斷開,PMON會清理現場,釋放相關的資源。
在一條連接而無相應的會話。另外,一個會話可以有連接也可以沒有連接。使用高級Oracle Net特性(如連接池)時,客戶可以洗掉一條物理連接,而會話依然保留(但是會話會空閑)。客戶在這個會話上執行某個操作時,它會重新建立物理連接。
在專用服務器中,一個會話對應一個服務器行程(Process),如果資料庫運行在共享服務器方式,一個服務器行程可以為多個會話服務。
下面用通俗易懂的方式來解釋連接和會話。
有A/B兩個城市,需要從A運送白菜到B城
我們先建設一條公路
2 / 9
然后運送白菜過去,包括準備白菜和運送白菜以及回傳等一系列的動作。
一條公路,可以運送0-n次的白菜
當然從A到B的公路也可能不只一條。
某一次運送白菜,可以在真正上路時才開通某一條道路
一次運送不會影響別的運送的狀態
對應資料庫
A代表客戶端行程
B代表服務器端行程
公路代表連接,
運送一次白菜代表一個會話
一個連接可以進行多次的會話
一個會話可以不依賴于某個連接,甚至沒有連接(當我準備好了,真正開始運送時再建立連接)
一個會話不會影響別的會話
會話&鏈接
在具體的應用場景中連接(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視窗和命令視窗將共享一個會話,另外一個會話將被用于編譯。
3 / 9
這個模式的缺點是每次只有一個視窗可以運行程式。
單路會話:所有的視窗和所有的編譯都使用同一個會話,這使事務管理變得很困難。在這個模式中除錯器被禁用使用。如果你被限制只能使用一個資料庫會話,那么你只能使用這個設定了。
會話&行程
在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
4 / 9
from v$parameter
where name='sessions';
select name, type, value ,display_value, isses_modifiable, issys_modifiable
from v$parameter
where name='processes';
方法3:查詢v$resiyrce_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
5 / 9
一般修改引數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'
6 / 9
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;
7 / 9
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的行程被釋放有兩種條件:
1、相關的terminal再一次試圖登錄及執行sql
2、手動的在作業系統后臺kill掉相應的spid
關于會話資訊
通過如下SQL你可以查詢你的每個應用程式到底在等待什么,從而針對這些資訊對資料庫的性能進行調整。
8 / 9
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
9 / 9
,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
uj5u.com熱心網友回復:
感謝分享,建議記錄在博客中。uj5u.com熱心網友回復:
我是來看評論的uj5u.com熱心網友回復:
好的,初次使用這個分享自己的學習成果,正在學習使用中
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/21230.html
標籤:基礎和管理
上一篇:誰有Oracle的Support Identifier,求大神幫忙下載meb-4.0 ,做個測驗,官網的測驗版只能下載最新的4.1.3
下一篇:這么寫查詢的效率怎樣?
