SQL Tuning Setのキャプチャから退避までのスクリプト(やっつけ) Tweet
Previously on Mac De Oracleは
DBMS_SQLTUNE.PACK_STGTAB_SQLSETって、例外投げんのかよwという備忘録でした、
今回は
以下のURLで紹介されているSTS (SQL Tuning Set)へSQLの性能統計や実行計画をキャプチャしちゃおう!
Oracle DatabaseのSTS(SQL Tuning Set) を活用して、SQLの性能統計や実行計画をキャプチャする。 / ora_gonsuke777
というSTS機能を利用した応用編w (という名のやっつけスクリプト) を書いたので、備忘録
STSでSQLの実行計画や性能統計をキャプチャするのはいいのですが、キャプチャするデータが多い場合、SYSAUX表領域を圧迫したり、拡張したりしてしまうことがあります。
本番環境で表領域サイズにドキドキする日々を送るのも嫌なので、一定期間STSヘキャプチャしたあとSTSを退避、削除したいよね。という方向の話が湧いてきたりしますw
で、書いたやっつけスクリプトが以下。(11g2と12cR1でテスト済み)
STSをキャプチャする時間、インターバル、そして、STSを退避するためのステージング表を作成するスキーマ名と、エクスポートに必要なディレクトリオブジェクト名を
パラメータに取ります。キャプチャする時間とインターバルは秒を指定します。エクスポートは、DBMS_DATAPUMPパッケージを利用しています。
今回利用したパッケージの詳細は以下を参照のこと:)
Oracle® Database PL/SQLパッケージおよびタイプ・リファレンス 11g リリース2(11.2) B56262-06
- DBMS_SQLTUNEサブプログラムの要約
- 46 DBMS_DATAPUMP
なお、本スクリプト実施前に、DataPump Export向けディレクトリオブジェクトを、ステージング表を作成するユーザを作成しておく必要があります。
(後半の実行例は、STS_EXP_DIRディレクトリオブジェクト、STSUSRユーザを事前に作成)
sts_capture.sql
SET SERVEROUTPUT ON
/*
Arguments :
&1 - Schema name for sts staging table
&2 - Directory object name for Data Pump Export
&3 - Duration for SQLSET capturing (sec)
&4 - Sampling interval for SQLSET (sec)
*/
DECLARE
-- for STS capturing and packing
vStsName VARCHAR2(30) := 'STS' || TO_CHAR(SYSDATE, 'YYYYMMDDHH24MISS');
cTimeLimit CONSTANT POSITIVE := &3;
cInterval CONSTANT POSITIVE := &4;
cCaptureOpt CONSTANT VARCHAR2(20) := 'MERGE';
cStagingSchema CONSTANT VARCHAR2(30) := UPPER('&1');
v4Debug VARCHAR2(50);
-- for DataPump Export Job
cDirectory CONSTANT VARCHAR2(20) := UPPER('&2');
IsSkipExport BOOLEAN := false;
i NUMBER;
vDataPumpJobHandle NUMBER;
vProgress_ratio NUMBER;
vJobState VARCHAR2(30);
oLogEntry ku$_LogEntry;
oStatus ku$_Status;
BEGIN
DBMS_OUTPUT.ENABLE;
-- STS名にInstance#を付加
-- (RAC環境での複数ノードでの実行を考慮してインスタンス番号を付加)
v4Debug := 'Build STSNAME';
FOR instance_rec IN (SELECT TO_CHAR(instance_number) AS inum FROM v$instance) LOOP
vStsName := vStsName || instance_rec.inum;
END LOOP;
-- SQLSETの作成
v4Debug := 'CREATE_SQLSET';
DBMS_SQLTUNE.CREATE_SQLSET (
sqlset_name => vStsName
,sqlset_owner => NULL
);
-- カーソルキャッシュからSTSへ定期キャプチャ
v4Debug := 'CAPTURE_CURSOR_CACHE_SQLSET';
DBMS_SQLTUNE.CAPTURE_CURSOR_CACHE_SQLSET (
sqlset_name => vStsName
,time_limit => cTimeLimit
,repeat_interval => cInterval
,capture_option => cCaptureOpt
,capture_mode => DBMS_SQLTUNE.MODE_REPLACE_OLD_STATS
,basic_filter =>
'parsing_schema_name NOT IN (
''SYS'', ''SYSTEM'', ''APEX_050000'', ''APEX_040000'', ''SYSMAN''
)'
,sqlset_owner => NULL
);
-- STSエクスポート向けステージング表の作成
v4Debug := 'CREATE_STGTAB_SQLSET';
DBMS_SQLTUNE.CREATE_STGTAB_SQLSET (
table_name => vStsName
,schema_name => cStagingSchema
,db_version => NULL
);
-- STSをステージング表へパック
v4Debug := 'PACK_STGTAB_SQLSET';
BEGIN
DBMS_SQLTUNE.PACK_STGTAB_SQLSET (
sqlset_name => vStsName
,sqlset_owner => NULL
,staging_table_name => vStsName
,staging_schema_owner => cStagingSchema
,db_version => NULL
);
EXCEPTION
WHEN OTHERS THEN
IF sqlcode = -15701 THEN
IsSkipExport := true;
DBMS_OUTPUT.PUT_LINE('*** Info - No data packed from SQLSET ***');
ELSE
RAISE;
END IF;
END;
IF IsSkipExport = false
THEN
-- ステージング表を表モードでエクスポート
-- エクスポートのモード等の設定
v4Debug := 'OPEN';
vDataPumpJobHandle
:= DBMS_DATAPUMP.OPEN (
operation => 'EXPORT'
,job_mode => 'TABLE'
,remote_link => NULL
,job_name => vStsName
,version => 'LATEST'
);
-- エスポートダンプファイルとログファイルの設定
v4Debug := 'ADD_FILE - dumpfile';
DBMS_DATAPUMP.ADD_FILE (
handle => vDataPumpJobHandle
,filename => vStsName || '.dmp'
,directory => cDirectory
,filetype => DBMS_DATAPUMP.KU$_FILE_TYPE_DUMP_FILE
);
v4Debug := 'ADD_FILE - logfile';
DBMS_DATAPUMP.ADD_FILE (
handle => vDataPumpJobHandle
,filename => vStsName || '.log'
,directory => cDirectory
,filetype => DBMS_DATAPUMP.KU$_FILE_TYPE_LOG_FILE
);
-- メターデータフィルタの設定
-- エクスポート対象表のスキーマ
v4Debug := 'METADATA_FILTER - schema name';
DBMS_DATAPUMP.METADATA_FILTER (
handle => vDataPumpJobHandle
,name => 'SCHEMA_LIST'
,value => '''' || cStagingSchema || ''''
);
-- エクスポート対象表
v4Debug := 'METADATA_FILTER - table name';
DBMS_DATAPUMP.METADATA_FILTER (
handle => vDataPumpJobHandle
,name => 'NAME_LIST'
,value => '''' || vStsName || ''''
);
-- DataPump Exportジョブの実行
v4Debug := 'START_JOB';
DBMS_DATAPUMP.START_JOB (
handle => vDataPumpJobHandle
);
-- DataPump Exportジョブ状況監視と終了判定
-- ジョブ終了または停止されるまでループして待機
v4Debug := 'JOB_STATE';
vProgress_ratio := 0;
vJobState := 'UNDEFINED';
WHILE (vJobState != 'COMPLETED') AND (vJobState != 'STOPPED') LOOP
DBMS_DATAPUMP.GET_STATUS (
vDataPumpJobHandle
,DBMS_DATAPUMP.KU$_STATUS_JOB_ERROR
+ DBMS_DATAPUMP.KU$_STATUS_JOB_STATUS
+ DBMS_DATAPUMP.KU$_STATUS_WIP
,-1
,vJobState
,oStatus
);
-- 処理中(Work-In-Progress : WIP)または、
-- エラーのいずれかのメッセージを受け取ったら表示
IF (BITAND(oStatus.mask, DBMS_DATAPUMP.KU$_STATUS_WIP) != 0)
THEN
oLogEntry := oStatus.wip;
ELSE
IF (BITAND(oStatus.mask, DBMS_DATAPUMP.KU$_STATUS_JOB_ERROR) != 0)
THEN
oLogEntry := oStatus.error;
ELSE
oLogEntry := NULL;
END IF;
END IF;
IF oLogEntry IS NOT NULL
THEN
i := oLogEntry.FIRST;
WHILE i IS NOT NULL LOOP
DBMS_OUTPUT.PUT_LINE(oLogEntry(i).LogText);
i := oLogEntry.NEXT(i);
END LOOP;
END IF;
END LOOP;
-- Data Pump Exportジョブ終了
DBMS_DATAPUMP.DETACH(vDataPumpJobHandle);
END IF;
-- ステージング表の削除
v4Debug := 'Drop staging table';
EXECUTE IMMEDIATE 'DROP TABLE ' || cStagingSchema || '.' || vStsName || ' PURGE';
-- SQLSETの削除
v4Debug := 'DROP_SQLSET';
DBMS_SQLTUNE.DROP_SQLSET (
sqlset_name => vStsName
);
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE(sqlerrm());
DBMS_OUTPUT.PUT_LINE(v4Debug);
RAISE;
END;
/
EXIT
STSが空ではない場合の実行例
キャプチャ処理は600秒実行しキャプチャ間隔は120秒、キャプチャ終了後、STSUSRスキーマにステージング表を作成、STSをステージング表へパック、ステージング表を指定したディレクトリオブジェクト以下にDataPump Exportしています。
[oracle@guppy ˜]$ sqlplus system@orcl @sts_capture stsusr sts_exp_dir 10*60 2*60
SQL*Plus: Release 12.1.0.2.0 Production on Fri Oct 6 15:13:53 2017
Copyright (c) 1982, 2014, Oracle. All rights reserved.
Enter password:
Connected to:
Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production
With the Partitioning, OLAP, Advanced Analytics and Real Application Testing options
old 4: cTimeLimit CONSTANT POSITIVE := &3;
new 4: cTimeLimit CONSTANT POSITIVE := 10*60;
old 5: cInterval CONSTANT POSITIVE := &4;
new 5: cInterval CONSTANT POSITIVE := 2*60;
old 7: cStagingSchema CONSTANT VARCHAR2(30) := UPPER('&1');
new 7: cStagingSchema CONSTANT VARCHAR2(30) := UPPER('stsusr');
old 11: cDirectory CONSTANT VARCHAR2(20) := UPPER('&2');
new 11: cDirectory CONSTANT VARCHAR2(20) := UPPER('sts_exp_dir');
Starting "SYS"."STS201710061513571":
Estimate in progress using BLOCKS method...
Processing object type TABLE_EXPORT/TABLE/TABLE_DATA
Total estimation using BLOCKS method: 1.062 MB
Processing object type TABLE_EXPORT/TABLE/TABLE
Processing object type TABLE_EXPORT/TABLE/INDEX/STATISTICS/INDEX_STATISTICS
Processing object type TABLE_EXPORT/TABLE/STATISTICS/TABLE_STATISTICS
Processing object type TABLE_EXPORT/TABLE/STATISTICS/MARKER
. . exported "STSUSR"."STS201710061513571" 51.55 KB 1 rows
Master table "SYS"."STS201710061513571" successfully loaded/unloaded
******************************************************************************
Dump file set for SYS.STS201710061513571 is:
/home/oracle/exp/STS201710061513571.dmp
Job "SYS"."STS201710061513571" successfully completed at Fri Oct 6 15:26:50 2017 elapsed 0 00:00:47
PL/SQL procedure successfully completed.
STSが空の場合の例
ステージング表へのSTSのパックやDataPump Exportの実行をパイパス。STSが空であることを表示して終了します。
なお、以下の例ではキャプチャ時間と間隔は意図的に短くしてあります。
[oracle@guppy ˜]$ sqlplus system@orcl @sts_capture stsusr sts_exp_dir 2*60 60
SQL*Plus: Release 12.1.0.2.0 Production on Fri Oct 6 16:04:55 2017
Copyright (c) 1982, 2014, Oracle. All rights reserved.
Enter password:
Connected to:
Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production
With the Partitioning, OLAP, Advanced Analytics and Real Application Testing options
old 4: cTimeLimit CONSTANT POSITIVE := &3;
new 4: cTimeLimit CONSTANT POSITIVE := 2*60;
old 5: cInterval CONSTANT POSITIVE := &4;
new 5: cInterval CONSTANT POSITIVE := 60;
old 7: cStagingSchema CONSTANT VARCHAR2(30) := UPPER('&1');
new 7: cStagingSchema CONSTANT VARCHAR2(30) := UPPER('stsusr');
old 11: cDirectory CONSTANT VARCHAR2(20) := UPPER('&2');
new 11: cDirectory CONSTANT VARCHAR2(20) := UPPER('sts_exp_dir');
*** Info - No data packed from SQLSET ***
PL/SQL procedure successfully completed.
このスクリプトをshellに組み込んでcronでも定期実行したりDBMS_SCHEDULERで定期実行するのも良いかな。
オレオレサンプルなので、より便利に改造して使ってね。v
| 固定リンク | 0
コメント