我们可以捕获生产环境的工作量,在测试环境上重放,从而在不影响生产环境的前提下做一些改动测试。
捕获:需要Oracle版本为10.2.0.4或更高.
重放:需要Oracle版本为11g Release 1或更新.
本文环境:RHEL6.4 + Oracle 11.2.0.4
下面介绍一下执行Database Replay的Workflow。
-- 创建目录replay_dir存放捕获信息 create or replace directory replay_dir as '/oradata/replay_dir'; -- 开始捕获工作量,10分钟后停止 begin dbms_workload_capture.start_capture(name => 'jydb_replay_1', dir => 'REPLAY_DIR', duration => 600); end;
/
注:如果duration参数不指定,那么就在执行finish_capture成功后停止捕获。
conn system/oracle@productDB -- 数据表空间 create tablespace dbs_d_jingyu datafile size 30M autoextend off; -- 临时表空间 create temporary tablespace temp_jingyu tempfile size 30M autoextend off; -- 索引表空间(可选) create tablespace dbs_i_jingyu datafile size 30M autoextend off; -- 假设创建用户 jingyu 密码 jingyu,默认临时表空间 temp_jingyu, 默认数据表空间 dbs_d_jingyu。 CREATE USER jingyu IDENTIFIED BY jingyu TEMPORARY TABLESPACE temp_jingyu DEFAULT TABLESPACE dbs_d_jingyu QUOTA UNLIMITED ON dbs_d_jingyu; -- 赋予普通业务用户权限 grant resource, connect to jingyu; -- 赋予DBA用户权限 grant dba to jingyu; -- 业务用户登录 conn jingyu/jingyu@productDB -- 删除T1,T2两张表 drop table t1 cascade constraints purge; drop table t2 cascade constraints purge; -- 创建T1,T2两张表 create table t1( id number not null, n number, contents varchar2(4000) ) tablespace dbs_d_jingyu; create table t2( id number not null, t1_id number not null, n number, contents varchar2(4000) ) tablespace dbs_d_jingyu; -- 初始化向T1,T2表插入随机测试数据 execute dbms_random.seed(0); set timing on insert into t1 select rownum, rownum, dbms_random.string('a',50) from dual connect by level <= 100 order by dbms_random.random; commit; insert into t2 select rownum, rownum, rownum, dbms_random.string('b',50) from dual connect by level <= 10000 order by dbms_random.random; commit; -- 查询T1,T2表数据量 select count(1) from t1; select count(1) from t2; begin for i in 1..1000 loop execute immediate 'select t1.id from t1, t2 where t1.id = t2.t1_id and t1.n = 19'; end loop; end;
/ -- 查询v$sql信息 select t.EXECUTIONS, t.SQL_TEXT from v$sql t where sql_text like 'select t1.id from t1, t2 where t1.id = t2.t1_id and t1.n = 19';
-- 停止捕获工作量 exec dbms_workload_capture.finish_capture();
首先将目录中生成的文件全部迁移到测试环境B目录/u02/replay_dir中。
-- 以下步骤是在测试环境B执行 -- 创建目录replay_dir create or replace directory replay_dir as '/u02/replay_dir';
-- 预处理工作量 begin dbms_workload_replay.process_capture(capture_dir => 'REPLAY_DIR');
dbms_workload_replay.initialize_replay('jydb_replay_1', 'REPLAY_DIR');
dbms_workload_replay.PREPARE_REPLAY(); end;
/
-- 重放工作量 (发现有问题)
exec dbms_workload_replay.start_replay();
-- 报错信息
* ERROR at line 1:
ORA-20223: No replay clients have connected yet! Please issue START_REPLAY()
after one or more WRC replay clients have been started!
ORA-06512: at "SYS.DBMS_WORKLOAD_REPLAY", line 5748 ORA-06512: at line 1 --查询 SELECT * FROM v$option WHERE parameter = 'Real Application Testing';
上述报错因为没有WRC重放客户端,至少有1个WRC重放客户端。
wrc mode=calibrate replaydir=/u02/replay_dir
[oracle@JY-DB01 replay_dir]$ wrc mode=calibrate replaydir=/u02/replay_dir
wrc system/oracle@testDB mode=replay replaydir=/u02/replay_dir
[oracle@JY-DB01 admin]$ wrc system/oracle@testDB mode=replay replaydir=/u02/replay_dir
-- 开始重放 exec dbms_workload_replay.start_replay();
-- 暂停重放 exec dbms_workload_replay.pause_replay();
-- 继续重放 exec dbms_workload_replay.resume_replay();
-- 终止重放 exec dbms_workload_replay.cancel_replay();
-- t1表数量 应该是100 select count(1) from jingyu.t1; -- t2表数量 应该是10000 select count(1) from jingyu.t2; -- 查询v$sql信息 应该是1000 select t.EXECUTIONS, t.SQL_TEXT from v$sql t where sql_text like 'select t1.id from t1, t2 where t1.id = t2.t1_id and t1.n = 19';
-- 查询捕获信息 SELECT DBMS_WORKLOAD_CAPTURE.get_capture_info('REPLAY_DIR') FROM dual; -- 提取报告 BEGIN DBMS_WORKLOAD_CAPTURE.export_awr (capture_id => 18); END;
/ -- 查询dba_workload_captures select id, name from dba_workload_captures; -- 删除捕获信息 exec dbms_workload_capture.delete_capture_info(&i);
输入上面查询dba_workload_captures的id值进行删除。
-- 查询dba_workload_replays
COLUMN name FORMAT A30 SELECT id, name FROM dba_workload_replays;
-- 收集报告
declare
capture_dir_id number;
curr_replay_id number;
replay_report clob;
begin
capture_dir_id := dbms_workload_replay.get_replay_info(dir => 'REPLAY_DIR'); select max(id) into curr_replay_id from dba_workload_replays where capture_id = capture_dir_id;
replay_report := dbms_workload_replay.report(replay_id => curr_replay_id, format => DBMS_WORKLOAD_REPLAY.TYPE_HTML); end;
/
--删除重放信息
exec dbms_workload_replay.delete_replay_info(&i);
输入上面查询dba_workload_replays的id值进行删除。
另,在确定不需要的时候可以系统删除重放目录下文件
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/196700/viewspace-2136562/ ,如需转载,请注明出处,否则将追究法律责任。