用于Oracle容灾和RAC的测试代码

浏览:
字体:
发布时间:2013-12-17 09:37:15
来源:

因为工作关系,在测试一些软件或演示时,需要一段能很清楚的演示容灾和RAC的自动切换效果的代码.发现达到满意的效果还是有些技巧的. DBMS_OUTPUT并不能实时的反应出效果.而Oracle的管道反而正合用,所以后面整理了下.效果还比较满意.

效果如下:

//

1. 定义一个用于返回运行状态的自定义类型

  --定义类型
CREATE OR REPLACE TYPE  obj_tab_demo AS OBJECT (
id number,
timesta TIMESTAMP(6) WITH TIME ZONE,
 inst       VARCHAR2(16),
 insthost VARCHAR2(64)
);

 --实例化

CREATE OR REPLACE TYPE  o_tab_demo  AS TABLE OF  obj_tab_demo ; 小技巧:

如果你已经执行了,想重建会报 ORA-02303 错误,11g虽有个force,并不好用.删除重建好了.
drop type o_tab_demo
drop type obj_tab_demo

要注意,此时用到这个类型的相关对象状态是失效的.

2. 创建存储过程

-- 相关知识:

-- Oracle管道化表函数 可以返回整个行的集.

-- 管道化表函数必须返回一个集合,在函数中,PIPE ROW语句 被用来返回该集合

--的个元素,此函数必须以一个空的RETURN语句结束,以表明它已经完成.
CREATE OR REPLACE FUNCTION fun_demo(p_num NUMBER)
RETURN o_tab_demo
PIPELINED
IS
  v_instname varchar2(16);
  v_hostname  varchar2(64);
  v_obj obj_tab_demo;
BEGIN
   FOR i in 1 ..p_num LOOP
    --实例序号
   v_inst := userenv('instance');
   -- 主机名
   v_hostname   := sys_context('userenv','host') ;
     -- 可以从v$instance视图中找,也可按上面的方法找出
     -- SELECT instance_name,host_name into v_instname,v_hostname FROM v$instance;
      v_obj := obj_tab_demo(i,systimestamp,v_instname, v_hostname  ); --systimestamp
      PIPE ROW(v_obj);
    END LOOP;
    RETURN;
EXCEPTION
WHEN OTHERS THEN
     DBMS_OUTPUT.PUT_LINE(SQLCODE||' '||SUBSTR(SQLERRM,1,200));
END;

--附注:

-- 如果想保存结果或要求测试INSERT,可以创建一个DEMO表,关在函数中将序号,时间和当前实例都存进去,需要用自治事务处理.

--DEMO表结构 :
create table demo
(
  id number,
  timesta TIMESTAMP(6) WITH TIME ZONE,
  inst VARCHAR2(16),
  insthost VARCHAR2(64)
)

3. 在PL/SQL Developer或SQLPlus中运行测试

a. 得到当前session ID,用处在于,你输入的循环值太大,手工中断时会用到.

SELECT DISTINCT(SID) INTO v_sessionsid FROM V$MYSTAT;

b. 打开output和运行时间开关
set serveroutput on
set timing on

c. 在SQL查询中使用TABLE操作符来使Oracle函数返回Table集合
        col  id for a8
        col  inst  for a10
        col  timesta  for a40
        col  insthost  for a10
        SELECT * FROM TABLE( fun_demo(10000) );4. 如果你认为你已达到测试目地,就可以强行中止未运行完的SELECT了.

如放在工具中执行,很简单,直接在菜单中选择相关项中止即可.

如需手工方式中止,按下面的方法:

a.找出会话ID和序列号,并得到kill命令
 select s.username, s.osuser,
     s.sid, s.serial#,
     p.spid, s.program,
     s.STATUS,
     'alter system kill session '||''''||s.sid||','||s.serial#||',@1'';' as oracle_kill
     from v$session s,v$process p
    where s.paddr = p.addr and s.username is not null        
      and s.sid = 上面查出的session id;b.然后运行 oracle_kill 杀掉会话即可.

5. 统计时间误差,看切换时间.这个是重点

找出上面实时输出的时间点,找到所要的切换时间点,分别给time1和time2 变量.

再运行下面代码,得到时间差.

代码:
DECLARE
 v_time1 TIMESTAMP(6) WITH TIME ZONE;
 v_time2 TIMESTAMP(6) WITH TIME ZONE;
 v_seconds NUMBER;
 v_minutes NUMBER;
 v_hours NUMBER;
 v_days NUMBER;
 v_weeks NUMBER;
BEGIN
 v_time1 := '13-12月-13 10.22.31.765000 上午 +08:00';
 v_time2 := '13-12月-13 10.23.04.546000 上午 +08:00';
SELECT substr((v_time2-v_time1),instr((v_time2-v_time1),' ')+7,2) seconds,
       substr((v_time2-v_time1),instr((v_time2-v_time1),' ')+4,2) minutes,
       substr((v_time2-v_time1),instr((v_time2-v_time1),' ')+1,2) hours,
       trunc(to_number(substr((v_time2-v_time1),1,instr(v_time2-v_time1,' '))))  days,
       trunc(to_number(substr((v_time2-v_time1),1,instr(v_time2-v_time1,' ')))/7) weeks
  INTO v_seconds,v_minutes,v_hours,v_days,v_weeks
  FROM dual;
  DBMS_OUTPUT.PUT_LINE('-------------------------------------------------');
  DBMS_OUTPUT.PUT_LINE('begin: '||v_time1);
  DBMS_OUTPUT.PUT_LINE('end : '||v_time2);
  DBMS_OUTPUT.PUT_LINE('-------------------------------------------------');
  DBMS_OUTPUT.PUT_LINE('seconds : '||v_seconds);
  DBMS_OUTPUT.PUT_LINE('minutes : '||v_minutes);
  DBMS_OUTPUT.PUT_LINE('hours : '||v_hours);
  DBMS_OUTPUT.PUT_LINE('days : '||v_days);
  DBMS_OUTPUT.PUT_LINE('weeks : '||v_weeks);
  DBMS_OUTPUT.PUT_LINE('-------------------------------------------------');
EXCEPTION
WHEN OTHERS THEN
     DBMS_OUTPUT.PUT_LINE(SQLCODE||' '||SUBSTR(SQLERRM,1,200));
END;
/至此,应当就能得到想要的效果了。

>更多相关文章
24小时热门资讯
24小时回复排行
资讯 | QQ | 安全 | 编程 | 数据库 | 系统 | 网络 | 考试 | 站长 | 关于东联 | 安全雇佣 | 搞笑视频大全 | 微信学院 | 视频课程 |
关于我们 | 联系我们 | 广告服务 | 免责申明 | 作品发布 | 网站地图 | 官方微博 | 技术培训
Copyright © 2007 - 2024 Vm888.Com. All Rights Reserved
粤公网安备 44060402001498号 粤ICP备19097316号 请遵循相关法律法规
');})();