会话和连接数的简单分析

概念介绍

通俗来讲,会话(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的公路也可能不只一条。

某一次运送白菜,可以在真正上路时才开通某一条道路

一次运送不会影响别的运送的状态

对应数据库

扫描二维码关注公众号,回复: 8563347 查看本文章

A代表客户端进程

B代表服务器端进程

公路代表连接,

运送一次白菜代表一个会话

一个连接可以进行多次的会话

一个会话可以不依赖于某个连接,甚至没有连接(当我准备好了,真正开始运送时再建立连接)

一个会话不会影响别的会话

会话&链接

在具体的应用场景中连接(connction) 和 会话(session) 有很多情况:

  1. SQL*PLUS 登录 ORACLE

这种场景比较容易理解,一个连接对应一个Session。

  1. 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 P R O C E S S A , 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 S E S S I O N S , 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,VKaTeX parse error: Expected group after '_' at position 23: …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 s e s s i o n s e , v session se,v session_wait st,v s e s s i o s i , 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 s e s s i o n a , 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

发布了19 篇原创文章 · 获赞 17 · 访问量 653

猜你喜欢

转载自blog.csdn.net/Gao068465/article/details/103704382