甲骨人
管理Oracle Session是后台DBMS采用Oracle的信息管理系统的一个重要工作。如果管理不当,会对系统的性能和运行的稳定性产生非常大的影响。那么以下是我们在生产工作当中经常使用的一些数据字典。
(一)session相关视图
(1)视图
v$session
v$active_session_history
dba_hist_active_session_history
注意:如果是rac数据库,v$session和v$active_hist_session_history仅获得单节点的信息,可以使用gv$sessiongv$active_session_history来获取所有节点的信息。g代表的是global 全局参数。inst_id 列代表节点。
(2)session数据字典的介绍
(2.1)v$session
v$session视图记录了当前连接到数据库的session信息,记录的是实时的数据,当有新的会话连接到数据库时,v$session就会产生一条新的session记录,一旦会话断开,记录消除,所以v$session的信息是实时动态变化的。
查看激活的session:
select * from v$session where type='USER' and status='ACTIVE';
v$session 数据字典表描述
Column | Description |
SADDR | session address |
SID | Session identifier |
SERIAL# | session序列号,当某个session结束,另一个新开始的session使用了前者的sid,则此数值自加1 |
AUDSID | auditing session ID,具有唯一性 |
PADDR | session对应的操作系统进程地址 |
USER# | Oracle user number |
USERNAME | Oracle user name |
COMMAND | 当前session正在执行的sql命令类型,具体编号代表什么可以查看v$sqlcommand |
lOCKWAIT | 正在等待的会话需要的的锁的地址,如果没有锁,则为空。(oracle:address of the lock the session is waiting for;NULL if none) |
STATUS | session的状态: --ACTIVE:当前session正在执行SQL; --INACTIVE:等待操作,即等待执行SQL语句; --KILLED:session被标注为KILLED、 --等等… |
SERVER | server类型有: --DECICATED --SHARED --PSEUDO --POLLED --NONE |
SCHEMA | schema用户id |
SCHEMANAME | schema用户名 |
OSUSER | 连接到数据库的操作系统用户名 |
PROCESS | 操作系统进程编号 |
MACHINE | 连接到数据库的机器名称 |
PORT | 连接到数据库的客户端端口 |
TERMINAL | 连接到数据库的终端名称 |
PROGRAM | 客户端执行的客户端程序 |
TYPE | session类型 |
SQL_ADDRESS | 与“SQL_HASH_VALUE”一起去确认当前正在被执行的SQL语句 |
SQL_HASH_VALUE | 与“SQL_ADDRESS”一起去确认当前正在被执行的SQL语句 |
SQL_ID | 当前正在被执行的SQL语句的ID |
LOGON_TIME | 登录时间 |
LAST_CALL_ET | 如果session状态为active,则该值表示session成为active到现在的时间; 通过该列可以确定会话的非活动时间,对于清理长时间不活动的会话,非常有用 |
SEQ# | 唯一标识session当前或最后等待的数目(每次等待都递增) |
EVENT# | event number |
EVENT | session正在等待的事件 |
(2.2)v$active_session_history
v$active_session_history是记录了数据库活跃会话的采样,如果是多节点,则用gv$active_session_history来查看所有节点的信息。数据库是每隔1秒钟,会进行一次采样,将活跃会话记录到该数据字典中,每个活跃会话记录一行。该视图是ASH的核心,用以记录活动SESSION的历史等待信息,这部分内容记录在内存中,期望值是记录一个小时的内容。
关于活跃会话的定义,大致如下:会话在CPU进行运算或者是非空闲等待的会话都属于活跃会话。官方解释:A database session is considered active if it was on the CPU or was waiting for an event that didn't belong to the Idle
wait class. Refer to the V$EVENT_NAME
view for more information on wait classes.
(2.3)dba_hist_active_sess_history
数据字典gv$active_session_history会每秒钟将数据库所有节点的活跃会话采样一次,但是数据是存放在内存中的,无法长久保存。而dba_hist_active_sess_history则会将gv$active_session_history里的数据每10秒采样一次并持久化保存。
(3)视图数据流向
(二)session相关视图的用途
(1)使用v$session来查看实时阻塞会话
以前处理异常锁的方式如下:
select /*+no_merge(a) no_merge(b)*/
(select username from v$session where sid = a.sid) blocker,
a.sid,
'is blocking',
(select username from v$session where sid = b.sid) blockee,
b.sid
from v$lock a, v$lock b
where a.block = 1
and b.request > 0
and a.id1 = b.ID1
and a.id2 = b.id2;
2.根据1的sid,serial#杀死会话
alter system kill session 'sid,serial#';
以下sql可以层级展示出阻塞的会话
SELECT LPAD(' ',5*LEVEL-1)||S."USERNAME" as username,
LPAD(' ',5*LEVEL-1)||S."SID" AS sid,
S."SERIAL#",
S."SQL_ID",
S."WAIT_CLASS",
S."EVENT",
S."P1",
S."P2",
S."P3",
S."SECONDS_IN_WAIT"
FROM V$SESSION S
WHERE S."BLOCKING_SESSION" IS NOT NULL
OR S.SID IN(SELECT DISTINCT BLOCKING_SESSION FROM V$SESSION)
START WITH S."BLOCKING_SESSION" IS NULL
CONNECT BY PRIOR S."SID" = S."BLOCKING_SESSION";
2)使用v$active_session_history、dba_hist_active_sess_history
1)定位哪些程序执行该SQL
select to_char(sample_time,'yyyy-mm-dd hh24:mi:ss') timekey,
ash.session_id,
ash."SESSION_SERIAL#",
ash."MODULE"
--count(*) as sql_count
from dba_hist_active_sess_history ash
where ash.instance_number = 1
and ash."SQL_ID" = '6ac0x1yudr8gq'
and ash.sample_time between to_date('2018-12-23 08:00:00','yyyy-mm-dd hh24:mi:ss')
and to_date('2018-12-23 09:00:00','yyyy-mm-dd hh24:mi:ss')
group by to_char(sample_time,'yyyy-mm-dd hh24:mi:ss'),
ash.session_id,
ash."SESSION_SERIAL#",
ash."MODULE"
order by timekey;
(2)定位该语句的执行频率
select to_char(sample_time,'yyyy-mm-dd hh24:mi:ss') timekey,
--ash.session_id,
--ash."SESSION_SERIAL#",
--ash."MODULE"
count(*) as sql_count
from dba_hist_active_sess_history ash
where ash.instance_number = 1
and ash."SQL_ID" = '6ac0x1yudr8gq'
and ash.sample_time between to_date('2018-12-23 08:00:00','yyyy-mm-dd hh24:mi:ss')
and to_date('2018-12-23 09:00:00','yyyy-mm-dd hh24:mi:ss')
group by to_char(sample_time,'yyyy-mm-dd hh24:mi:ss')
--ash.session_id,
--ash."SESSION_SERIAL#",
--ash."MODULE"
order by timekey;