逻辑备库RESTART_DELAY研究

逻辑备库中经常会出现由于主库未提交的inactive事务而导致逻辑备库restart delay,而处理方法就是kill掉对应的session,这种情况出现的原因在于我们在主库上面执行一条事务但并未提交,因为开会或各种打断后由于网络或者各种异常导致该会话处于inactive状态,这个时候逻辑备库的restart_delay时间就会停留在事务开始时间,而一种可以重现的方法就是在测试库中未提交事务之前拔掉网线,测试如下:

执行事务
SQL> insert into test select * from user_tables where rownum<=2;

2 rows created.

查看事务状态
SQL> select addr,status,start_time from v$transaction;

ADDR STATUS START_TIME
---------------- ---------------- --------------------
000000009D0CD010 ACTIVE 05/23/11 15:12:41

查看对应会话信息
SQL> select sid,taddr,status,logon_time from v$session where taddr='000000009D0CD010';

SID TADDR STATUS LOGON_TIME
---------- ---------------- -------- -------------------
313 000000009D0CD010 ACTIVE 2011-05-23 15:12:14

这个时候拔掉网线,

查看事务状态
ADDR STATUS START_TIME
---------------- ---------------- --------------------
000000009D0CD010 ACTIVE 05/23/11 15:12:41

查看会话状态
SID TADDR STATUS LOGON_TIME
---------- ---------------- -------- -------------------
313 000000009D0CD010 INACTIVE 2011-05-23 15:12:14

接下来说明一下会话的状态 ,下面是metalink对于inactive session的定义,
- A user starts a program/session, then leaves it running and idle
for an extended period of time.

To automate cleanup of INACTIVE sessions you can create a profile with an appropriate IDLE_TIME setting and assign that profile to the users.
Note:159978.1: How To Automate Disconnection of Idle Sessions,outlines the steps to setup IDLE_TIME for this.

对于session的状态有以下几种
1.active 处于此状态的会话,表示正在执行,处于活动状态。
2.killed 处于此状态的会话,表示出现了错误,正在回滚,当然,也是占用系统资源的,被kill掉的session,状态会被标记为killed,Oracle会在该用户下一次touch时清除该进程。
alter system kill session 'SID,SERIAL#' ;
当在Oracle中kill session以后, Oracle只是简单的把相关session的paddr 指向同一个虚拟地址.此时v$process和v$session失去关联,进程就此中断,然后Oracle就等待PMON去清除这些Session.所以通常等待一个被标记为Killed的Session退出需要花费很长的时间,如果此时被Kill的process,重新尝试执行任务,那么马上会收到进程中断的提示,process退出,此时Oracle会立即启动PMON来清除该session.这被作为一次异常中断处理.

3.inactive 处于此状态的会话表示不是正在执行的,虽然oracle本身会去清除这些进程,但是目前还没有找到文档详细解释oracle清除这些inactive session的文档,但是从相关资料看出这个周期为4-5个小时,这个时间段不足以满足restart本身的时间特性,所以需要寻求方法手动触发这些清除过程,从metalink的文档中提出了两种方法:

1. 修改sqlnet.ora文件,新增expire_time=x(单位是分钟)
但是通过测试此种方法并不能触发oracle清除异常的事务

2. 通过PROFILE的IDLE TIME来清除这些异常事务
ALTER PROFILE DEFAULT LIMIT IDLE_TIME 10;
设置PROFILE策略必须保证resource_limit为true

15:40:27 SYS@ test>show parameter resource_limit;

NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
resource_limit boolean TRUE
该参数可以动态修改:

SQL> alter system set resource_limit=true;

System altered.
执行事务
SQL> insert into test select * from user_tables where rownum<=2;
查看事务状态
SQL> select addr,status,start_time from v$transaction;

ADDR STATUS START_TIME
---------------- ---------------- --------------------
000000009D126130 ACTIVE 05/23/11 15:47:21

查看会话状态

SID TADDR STATUS LOGON_TIME
---------- ---------------- -------- -------------------
299 000000009D126130 ACTIVE 2011-05-23 15:47:06

超过IDLE TIME后查看状态
SQL> select addr,status,start_time from v$transaction;
select addr,status,start_time from v$transaction
*
ERROR at line 1:

此外通过定时脚本检测删除异常的session也是一种可行的方法,
select '------------------------------'||to_char(sysdate,'mm-dd-yyyy hh24:mi:ss')||'-------------------------------------' Time from dual;
select 'Following user forms session, inactive for more than 60 min, are killed' from dual;
set head on
set pagesize 1000
SELECT
p.spid,
s.process,
s.status,
s.machine,
to_char(s.logon_time,'mm-dd-yy hh24:mi:ss') Logon_Time,
s.last_call_et/3600 Last_Call_ET,
s.action,
s.module,
s.sid,
s.serial#
FROM
V\$SESSION s
, V\$PROCESS p
WHERE
s.paddr = p.addr
AND
s.username IS NOT NULL
AND
s.last_call_et/3600 > 1
and
s.status='INACTIVE' order by logon_time;
spool off
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值