在11g中,database replay是一个很重要的新特性,按照这个特性的说法,可以完整地捕获数据库的负载信息,便于在需要的时候随时重放。
使用这种方法,可以 以二进制文件格式捕获 SQL 级以下的所有数据库活动,然后在同一数据库或不同数据库内进行重放。
基本的流程图如下:
自己看到这个特性也是很感兴趣,然后在测试环境进行了多次测试,可能我学习的方式比较较真,对于很多知识点,都是希望先能简单模拟,弄出个结果,然后自己才喜欢捣鼓一些细节的内容。
越是这样做,似乎对于这个特性还是有很多的细节需要注意,总是碰到各种各样的问题,最后都是不了了之。在很多网站,帖子中也搜了不少的相关文档,但是描述的比较全的帖子还是比较少。特意整理了一下,自己也反复做了测试,基本能够保证按照步骤顺利完成。
首先我们需要创建一个目录,然后赋予权限。
create table n1.test(id number);
SQL> create directory dbplay as 'c:\test\dbreplay' ;
Directory created.
SQL> grant read,write on directory dbplay to n1;
Grant succeeded.
然后使用dbms_workload_capture来准备开始捕获数据库层面的负载情况,在这个例子中我们指定时长为600秒,也可以中途终止。也可以指定对于某个schema进行细粒度的捕获。
BEGIN
DBMS_WORKLOAD_CAPTURE.START_CAPTURE (
name => 'dbreplay_test',
dir => 'dbplay',
duration => 600);
END;
/
这个时候我们会碰到错误。
ERROR at line 1:
ORA-20222: Invalid DB State or Input. Input "dbplay" is not a valid DIRECTORY
object!
这个问题算比较清晰的,就是目录名的问题,只需要改为大写即可。
如果碰到如下的错误。
ERROR at line 1:
ORA-15505: cannot start workload capture because instance 1 encountered errors
while accessing directory "c:\test\dbreplay"
说明在指定的捕获目录下,很可能有之前捕获的文件,会有一定的冲突。可以清空或者换一个目录。
开始捕获
BEGIN
DBMS_WORKLOAD_CAPTURE.START_CAPTURE (
name => 'dbreplay_test',
dir => 'DBPLAY',
duration => 600);
END;
/
这个时候查看目录中的文件,就会发现生成了几个文件夹,和一个.start的文件(文件为空),这也就标志着捕获开始了。
03/29/2015 09:48 PM ..
03/29/2015 09:48 PM cap
03/29/2015 09:47 PM capfiles
03/29/2015 09:47 PM wcr_cap_0000f.start
在捕获期间,我们尝试运行下面的一个脚本,来进行大量的数据插入,这个语句会进行大量的硬解析,存在一定的性能隐患。
begin
for x in 1..200000 loop
insert into n1.test values(x);
commit;
end loop;
end;
/
如果时间在600秒内,完成后就会自动结束,我们也可以在中途进行手动结束捕获。
BEGIN
DBMS_WORKLOAD_CAPTURE.FINISH_CAPTURE();
END;
/
技术捕获后,就会发现.start文件就会自动清除。
我们可以使用如下的脚本来进行捕获情况的监控。
select id,name,status,capture_size from DBA_WORKLOAD_CAPTURES;
最后我们使用如下的方法来进行文件的预处理,处理之后就会生成一个pp开头的目录,我的数据库版本是11.2的,文件就为: pp11.2.0.1.0
BEGIN
DBMS_WORKLOAD_REPLAY.PROCESS_CAPTURE (
capture_dir => 'DBPLAY');
END;
/
这个时候,捕获工作就完成了。
如果在工作中,我们可以在测试环境中进行这些信息的重放。这个时候就需要把捕获目录中的文件都拷贝到测试机器上。
当然为了演示方便,也可以在当前的环境进行重放。
在测试机器上,我们需要创建对应的目录,把捕获文件都拷贝过来。
SQL> create or replace directory target_replay as 'c:\test\target_replay';
Directory created.
SQL> grant read,write on directory target_replay to n1;
Grant succeeded.
这个时候我们需要清空表中的数据,这样就能够很 清楚的看到重放的过程中数据的变化。
truncate table n1.test;
开始进行初始化
BEGIN
DBMS_WORKLOAD_REPLAY.INITIALIZE_REPLAY (
replay_name => 'target_replay_test',
replay_dir => 'TARGET_REPLAY');
END;
/
BEGIN
DBMS_WORKLOAD_REPLAY.PREPARE_REPLAY (synchronization => TRUE);
END;
/
这个时候查看目录结构,会发现又多了一个目录rep开头的,这个是replay初始化的时候生成的。
Directory of C:\test\target_replay
03/29/2015 09:14 PM cap
03/29/2015 09:14 PM capfiles
03/29/2015 09:14 PM pp11.2.0.1.0
03/29/2015 09:16 PM rep438010913
这个时候我们可以通过wrc来开启重放客户端,在另外一个窗口中运行即可。
C:\test\target_replay>wrc system/oracle mode=replay replaydir=c:\test\target_replay
Workload Replay Client: Release 11.2.0.1.0 - Production on Sun Mar 29 21:18:20 2
Copyright (c) 1982, 2009, Oracle and/or its affiliates. All rights reserved.
Wait for the replay to start (21:18:20)
可以看到客户端中已经开始等待重放了。
不用着急,我们在另外一个窗口中开始重放。
BEGIN
DBMS_WORKLOAD_REPLAY.START_REPLAY ();
END;
/
这个时候不间断的查看test表中的数据,就会发现数据在一点一点的插入。如果存在性能问题,也可以有针对性的分析。
SQL> select count(*)from n1.test;
COUNT(*)
----------
91458
SQL> /
COUNT(*)
----------
159206
SQL> /
COUNT(*)
----------
175586
SQL> /
COUNT(*)
----------
200000
我们可以最后指定重放完毕。客户端中就会触发退出。
BEGIN
DBMS_WORKLOAD_REPLAY.CANCEL_REPLAY ();
END;
/
Wait for the replay to start (21:18:20)
Replay started (21:19:16)
Replay finished (21:21:11)
我们可以通过如下的语句来监控重放的情况
select id,name,status,user_calls from DBA_WORKLOAD_REPLAYS;
如果我们想得到捕获过程中的报告,可以使用如下的方式完成。
set long 100000;
set pagesize 40000;
select dbms_workload_replay.report(2,'TEXT') from dual;
最后就是这些信息的清理,如果已经完成了重放,分析完成了,就可以删除这些捕获或者重放的配置信息。传入的参数就是对应的id,在DBA_WORKLOAD_CAPTURES,DBA_WORKLOAD_REPLAYS中可以得到对应的id
exec dbms_workload_replay.DELETE_REPLAY_INFO(1);
exec dbms_workload_capture.DELETE_CAPTURE_INFO(1);
使用这种方法,可以 以二进制文件格式捕获 SQL 级以下的所有数据库活动,然后在同一数据库或不同数据库内进行重放。
基本的流程图如下:
自己看到这个特性也是很感兴趣,然后在测试环境进行了多次测试,可能我学习的方式比较较真,对于很多知识点,都是希望先能简单模拟,弄出个结果,然后自己才喜欢捣鼓一些细节的内容。
越是这样做,似乎对于这个特性还是有很多的细节需要注意,总是碰到各种各样的问题,最后都是不了了之。在很多网站,帖子中也搜了不少的相关文档,但是描述的比较全的帖子还是比较少。特意整理了一下,自己也反复做了测试,基本能够保证按照步骤顺利完成。
首先我们需要创建一个目录,然后赋予权限。
create table n1.test(id number);
SQL> create directory dbplay as 'c:\test\dbreplay' ;
Directory created.
SQL> grant read,write on directory dbplay to n1;
Grant succeeded.
然后使用dbms_workload_capture来准备开始捕获数据库层面的负载情况,在这个例子中我们指定时长为600秒,也可以中途终止。也可以指定对于某个schema进行细粒度的捕获。
BEGIN
DBMS_WORKLOAD_CAPTURE.START_CAPTURE (
name => 'dbreplay_test',
dir => 'dbplay',
duration => 600);
END;
/
这个时候我们会碰到错误。
ERROR at line 1:
ORA-20222: Invalid DB State or Input. Input "dbplay" is not a valid DIRECTORY
object!
这个问题算比较清晰的,就是目录名的问题,只需要改为大写即可。
如果碰到如下的错误。
ERROR at line 1:
ORA-15505: cannot start workload capture because instance 1 encountered errors
while accessing directory "c:\test\dbreplay"
说明在指定的捕获目录下,很可能有之前捕获的文件,会有一定的冲突。可以清空或者换一个目录。
开始捕获
BEGIN
DBMS_WORKLOAD_CAPTURE.START_CAPTURE (
name => 'dbreplay_test',
dir => 'DBPLAY',
duration => 600);
END;
/
这个时候查看目录中的文件,就会发现生成了几个文件夹,和一个.start的文件(文件为空),这也就标志着捕获开始了。
03/29/2015 09:48 PM ..
03/29/2015 09:48 PM cap
03/29/2015 09:47 PM capfiles
03/29/2015 09:47 PM wcr_cap_0000f.start
在捕获期间,我们尝试运行下面的一个脚本,来进行大量的数据插入,这个语句会进行大量的硬解析,存在一定的性能隐患。
begin
for x in 1..200000 loop
insert into n1.test values(x);
commit;
end loop;
end;
/
如果时间在600秒内,完成后就会自动结束,我们也可以在中途进行手动结束捕获。
BEGIN
DBMS_WORKLOAD_CAPTURE.FINISH_CAPTURE();
END;
/
技术捕获后,就会发现.start文件就会自动清除。
我们可以使用如下的脚本来进行捕获情况的监控。
select id,name,status,capture_size from DBA_WORKLOAD_CAPTURES;
最后我们使用如下的方法来进行文件的预处理,处理之后就会生成一个pp开头的目录,我的数据库版本是11.2的,文件就为: pp11.2.0.1.0
BEGIN
DBMS_WORKLOAD_REPLAY.PROCESS_CAPTURE (
capture_dir => 'DBPLAY');
END;
/
这个时候,捕获工作就完成了。
如果在工作中,我们可以在测试环境中进行这些信息的重放。这个时候就需要把捕获目录中的文件都拷贝到测试机器上。
当然为了演示方便,也可以在当前的环境进行重放。
在测试机器上,我们需要创建对应的目录,把捕获文件都拷贝过来。
SQL> create or replace directory target_replay as 'c:\test\target_replay';
Directory created.
SQL> grant read,write on directory target_replay to n1;
Grant succeeded.
这个时候我们需要清空表中的数据,这样就能够很 清楚的看到重放的过程中数据的变化。
truncate table n1.test;
开始进行初始化
BEGIN
DBMS_WORKLOAD_REPLAY.INITIALIZE_REPLAY (
replay_name => 'target_replay_test',
replay_dir => 'TARGET_REPLAY');
END;
/
BEGIN
DBMS_WORKLOAD_REPLAY.PREPARE_REPLAY (synchronization => TRUE);
END;
/
这个时候查看目录结构,会发现又多了一个目录rep开头的,这个是replay初始化的时候生成的。
Directory of C:\test\target_replay
03/29/2015 09:14 PM cap
03/29/2015 09:14 PM capfiles
03/29/2015 09:14 PM pp11.2.0.1.0
03/29/2015 09:16 PM rep438010913
这个时候我们可以通过wrc来开启重放客户端,在另外一个窗口中运行即可。
C:\test\target_replay>wrc system/oracle mode=replay replaydir=c:\test\target_replay
Workload Replay Client: Release 11.2.0.1.0 - Production on Sun Mar 29 21:18:20 2
Copyright (c) 1982, 2009, Oracle and/or its affiliates. All rights reserved.
Wait for the replay to start (21:18:20)
可以看到客户端中已经开始等待重放了。
不用着急,我们在另外一个窗口中开始重放。
BEGIN
DBMS_WORKLOAD_REPLAY.START_REPLAY ();
END;
/
这个时候不间断的查看test表中的数据,就会发现数据在一点一点的插入。如果存在性能问题,也可以有针对性的分析。
SQL> select count(*)from n1.test;
COUNT(*)
----------
91458
SQL> /
COUNT(*)
----------
159206
SQL> /
COUNT(*)
----------
175586
SQL> /
COUNT(*)
----------
200000
我们可以最后指定重放完毕。客户端中就会触发退出。
BEGIN
DBMS_WORKLOAD_REPLAY.CANCEL_REPLAY ();
END;
/
Wait for the replay to start (21:18:20)
Replay started (21:19:16)
Replay finished (21:21:11)
我们可以通过如下的语句来监控重放的情况
select id,name,status,user_calls from DBA_WORKLOAD_REPLAYS;
如果我们想得到捕获过程中的报告,可以使用如下的方式完成。
set long 100000;
set pagesize 40000;
select dbms_workload_replay.report(2,'TEXT') from dual;
最后就是这些信息的清理,如果已经完成了重放,分析完成了,就可以删除这些捕获或者重放的配置信息。传入的参数就是对应的id,在DBA_WORKLOAD_CAPTURES,DBA_WORKLOAD_REPLAYS中可以得到对应的id
exec dbms_workload_replay.DELETE_REPLAY_INFO(1);
exec dbms_workload_capture.DELETE_CAPTURE_INFO(1);