database replay基礎學習(r4筆記第90天)
在11g中,database replay是一個很重要的新特性,按照這個特性的說法,可以完整地捕獲資料庫的負載資訊,便於在需要的時候隨時重放。 使用這種方法,可以以二進位制檔案格式捕獲 SQL 級以下的所有資料庫活動,然後在同一資料庫或不同資料庫內進行重放。 基本的流程圖如下:
自己看到這個特性也是很感興趣,然後在測試環境進行了多次測試,可能我學習的方式比較較真,對於很多知識點,都是希望先能簡單模擬,弄出個結果,然後自己才喜歡搗鼓一些細節的內容。 越是這樣做,似乎對於這個特性還是有很多的細節需要注意,總是碰到各種各樣的問題,最後都是不了了之。在很多網站,帖子中也搜了不少的相關文件,但是描述的比較全的帖子還是比較少。特意整理了一下,自己也反覆做了測試,基本能夠保證按照步驟順利完成。 首先我們需要建立一個目錄,然後賦予許可權。
create table n1.test(id number); SQL> create directory dbplay as 'c:testdbreplay' ; 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:testdbreplay"
說明在指定的捕獲目錄下,很可能有之前捕獲的檔案,會有一定的衝突。可以清空或者換一個目錄。
開始捕獲
BEGIN
DBMS_WORKLOAD_CAPTURE.START_CAPTURE (
name => 'dbreplay_test',
dir => 'DBPLAY',
duration => 600);
END;
/
這個時候檢視目錄中的檔案,就會發現生成了幾個資料夾,和一個.start的檔案(檔案為空),這也就標誌著捕獲開始了。
03/29/2015 09:48 PM <DIR> ..
03/29/2015 09:48 PM <DIR> cap
03/29/2015 09:47 PM <DIR> capfiles
03/29/2015 09:47 PM <DIR> 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:testtarget_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:testtarget_replay
03/29/2015 09:14 PM <DIR> cap
03/29/2015 09:14 PM <DIR> capfiles
03/29/2015 09:14 PM <DIR> pp11.2.0.1.0
03/29/2015 09:16 PM <DIR> rep438010913
這個時候我們可以通過wrc來開啟重放客戶端,在另外一個視窗中執行即可。
C:testtarget_replay>wrc system/oracle mode=replay replaydir=c:testtarget_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);