逻辑备库RESTART_DELAY研究

逻辑备库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,状态会被标记为killedOracle会在该用户下一次touch时清除该进程。

alter system kill session 'SID,SERIAL#' ;

当在Oraclekill session以后, Oracle只是简单的把相关sessionpaddr 指向同一个虚拟地址.此时v$processv$session失去关联,进程就此中断,然后Oracle就等待PMON去清除这些Session.所以通常等待一个被标记为KilledSession退出需要花费很长的时间,如果此时被Killprocess,重新尝试执行任务,那么马上会收到进程中断的提示,process退出,此时Oracle会立即启动PMON来清除该session.这被作为一次异常中断处理.

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

1. 修改sqlnet.ora文件,新增expire_time=x(单位是分钟)

但是通过测试此种方法并不能触发oracle清除异常的事务

2. 通过PROFILEIDLE TIME来清除这些异常事务

ALTER PROFILE DEFAULT LIMIT IDLE_TIME 10;

设置PROFILE策略必须保证resource_limittrue

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


来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/22503721/viewspace-708226/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/22503721/viewspace-708226/

下面是一个简单的 keepalived 代理 UDP 流量的配置示例: 1. 安装 keepalived: ``` sudo apt-get install keepalived ``` 2. 配置 keepalived: 在 `/etc/keepalived/keepalived.conf` 文件中添加以下配置: ``` vrrp_instance VI_1 { state MASTER interface eth0 virtual_router_id 51 priority 100 virtual_ipaddress { 10.0.0.1/24 dev eth0 } } virtual_server 10.0.0.1 123 { delay_loop 6 lb_algo wlc lb_kind NAT persistence_timeout 50 protocol UDP real_server 192.168.0.2 123 { weight 1 notify_down /etc/keepalived/notify.sh TCP_CHECK { connect_timeout 10 nb_get_retry 3 delay_before_retry 3 connect_port 123 } } real_server 192.168.0.3 123 { weight 1 notify_down /etc/keepalived/notify.sh TCP_CHECK { connect_timeout 10 nb_get_retry 3 delay_before_retry 3 connect_port 123 } } } ``` 其中,`vrrp_instance` 部分配置用于定义虚拟路由器的属性,`virtual_server` 部分配置用于定义要代理的 UDP 流量。在上面的配置中,我们将 keepalived 配置为将来自 10.0.0.1 的 UDP 流量转发到实际的 UDP 服务器(192.168.0.2 和 192.168.0.3)。 3. 创建 notify.sh 脚本 在 `/etc/keepalived/` 目录中创建一个名为 `notify.sh` 的脚本文件,并添加以下内容: ``` #!/bin/bash case $1 in "MASTER") # 在此处添加主服务器状态下需要执行的操作 ;; "BACKUP") # 在此处添加备份服务器状态下需要执行的操作 ;; "FAULT") # 在此处添加故障状态下需要执行的操作 ;; *) echo "unknown state" ;; esac ``` 这个脚本将在主服务器状态切换时被调用,您可以在其中添加自己的逻辑。 4. 重启 keepalived 完成以上步骤后,您可以启动或重启 keepalived,以使配置生效: ``` sudo systemctl restart keepalived ``` 现在,keepalived 将代理来自 10.0.0.1 的 UDP 流量,并将其转发到实际的 UDP 服务器(192.168.0.2 和 192.168.0.3)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值