Oracle session的sid与serial的简单学习

发布时间 2023-10-11 23:20:13作者: 济南小老虎

Oracle session的sid与serial的简单学习


ITPUB vage的说法

这样说吧,Oracle允许的会话数(或者说连接数)是固定的,比如是3000个。假设每个会话要占1K字节,哪一共就需要3000K。
这3000K就是一个小内存池,可以称为会话池。会话池中每个1K保存一个会话的信息,可以称为一个会话Slot。
假设编号为100的会话Slot(也就是Sid为100),有一个会话连接,Oracle将会话信息保存在100号Slot(也就是新建立的连接会话号为100),此时serail#为1。
当此会话断开连接后,过一会,又有一个会话连接,Oracle又将会话信息保存在100号Slot(也就是会话号又是100),此时Serail#为2。
Serial#,代表第几次使用同一个会话Slot。

http://www.itpub.net/thread-1600999-1-1.html

自己的理解

之前总结过 Oracle其实是有 专用模式和共享模式的
但是官方说的 session=1.1*process+5的经验值设置大法并没有直接说明 是专用模式下还是共享模式.

按照理解. 专用模式下面 process的数据量应该肯定会大于session的数量 因为session和process 是需要一对一的. 但是process 并没有必须创建session的创景.

在按照vage大神的说法. sid 其实就是一个slot 槽的概念, 其实没有实际的意义, 不相同是应该,相同的话是运气. 
决定具体执行SQL以及SQL结果的是 serial#的数值,以及游标的信息. 

在java 的连接池模式下. 理论上我一个线程的多个短促事务非常有可能使用到相同的sid, serial# 在部分情况下可能指向的是连接的会话.

cursor 会指向会话内的一个具体的SQL执行,用于返回结果集. 

sid 与数据库里面的process 相关(理论上使用PGA的内存空间)
serial 与会话相关. 表名是谁在连接, 并且可能还没有显示的进行终止
会话终止了. process会进入等待被使用的状态. sid就会变成空闲. 然后下一个会话进来时 可能使用相关的sid 但是serial会 +1 进行区分. 

然后没执行一条SQL会对应一个cursor.
这里面oracle的一些参数就跟linux的参数比较类似了. 

process和session 的最大值只的是整个系统的
open_cursor的最大值 指的却是每一个 session 的. 
所以理论上一个数据库能够支撑的游标总数可能是 open_cursor*max_session. 是比较恐怖的.

cursor和process一样都是需要占用内存进行存储结果的.
cursor 可能还会跟library cache相关联. 

一条SQL进入数据库, 会先进行md5的处理
如果library cache中有相同的md5 那么就是soft parse 如果没有就是hard parse
soft 比 hard 性能和速度要好很多, 这个里面就是 绑定变量让SQL的 md5值保持一致来减少CPU消耗提高并发性能的根本原理. 

然后如果cursor中会有,相同SQL的执行记录, 那么就会 soft soft parse. 速度更快消耗更少, 但是会让session占用更多的内存,
也就是session_cursor 类型的参数来决定能够储存 解析过SQL多少的能力.  也是空间换时间的逻辑. 

parse 完后其实就是进入了 CBO的逻辑 这里与今天的思考没关系,就不展开了(我也没闹明白)

部分实验

可以使用
select session_ID,COUNT(1) from v$active_session_history GROUP BY session_ID ORDER BY 1 DESC  
查看当前数据库的最大的SID的值
比如我这边服务器就显示: 6389

select * from gv$parameter where name like '%session%'
查看对应的参数发现结果为:
6784

理论上肯定与最大值比较接近, 其实是session就是一个艰难的数值类型. 
select session_ID,COUNT(1) from v$active_session_history GROUP BY session_ID ORDER BY 2 DESC  

按照 没有被刷出ASH内存的表中统计的序列号的多少看 可以发现那个session使用量最大.
当然了. 不一定是序号的总数 有可能是序号被统计的次数比较多, ASH表是每十秒取样一次. 并不是精确数值. 

select * from v$active_session_history where session_id = '2121' order by session_serial# desc 
发现这个最大的是一个 后台进程 !-_-! 理论上很多后台进程 除非服务器重启后者是其他严重异常才会退出. 

简单总结

数据库非常复杂. 边学边记...