STATSPACK自動出力

はじめに

STATSPACKを手動でレポート出力するのは時間がかかるため、毎日、前日のレポートを自動出力する処理を作成した。

内容

前提

実行環境は以下となる。

  • OSバージョン
    • Windows Server 2016 Standard
  • Oracle Databaseバージョン
    • Oracle Database 12C

処理構成

・バッチ:1つ
⇒メイン処理
タスクスケジューラなどで、このバッチを定期的に実行する。

・VBS:1つ
⇒日付加工用処理

・SQLファイル:2つ
⇒スナップショット情報を取得する処理
⇒STATSPACKを出力する処理

メイン処理

REM STATSPACK出力処理
SET BAT_NAME=CREATE_STATSPACK.BAT
SET BAT_PATH=フォルダパスを指定する
SET WORK_PATH=%BAT_PATH%WORK\
SET REPORT_PATH=%BAT_PATH%REPORT\

REM DAY_BEFORE1.TXTが存在するか確認
IF EXIST %WORK_PATH%DAY_BEFORE1.TXT (GOTO CHECK) ELSE (GOTO ERROR)
IF ERRORLEVEL 1 GOTO ERROR

:CHECK
REM DAY_BEFORE2.TXTが存在するか確認
IF EXIST %WORK_PATH%DAY_BEFORE2.TXT (GOTO JOB) ELSE (GOTO ERROR)
IF ERRORLEVEL 1 GOTO ERROR

:JOB
REM 前日日付を取得
WSCRIPT %BAT_PATH%DAY_BEFORE.VBS
IF ERRORLEVEL 1 GOTO ERROR

REM 前日日付を変数にセット
FOR /F "USEBACKQ" %%A IN (TYPE %WORK_PATH%DAY_BEFORE1.TXT) DO SET DAY_BEFORE1=%%A
IF ERRORLEVEL 1 GOTO ERROR

REM 前日日付の"/"なしを変数にセット
FOR /F "USEBACKQ" %%B IN (TYPE %WORK_PATH%DAY_BEFORE2.TXT) DO SET DAY_BEFORE2=%%B
IF ERRORLEVEL 1 GOTO ERROR

REM 前日日付を元にSTATSPACKのスナップショットIDとIDの該当時間を取得
SQLPLUS /NOLOG @%BAT_PATH%CREATE_STATSPACK.SQL %DAY_BEFORE1%
IF ERRORLEVEL 1 GOTO ERROR

REM レポート出力
FOR /F "TOKENS=1,2,3,4" %%C IN (%WORK_PATH%CREATE_STATSPACK.TXT) DO ( 

SQLPLUS /NOLOG @%BAT_PATH%AUTO_SPREPORT.SQL %%C %%D %DAY_BEFORE2%_%%E_%%F

)

REM 前日日付のフォルダが既に存在する場合は削除する
RMDIR /S /Q %REPORT_PATH%%DAY_BEFORE2%

REM ファイルを格納するフォルダを作成
MKDIR %REPORT_PATH%%DAY_BEFORE2%
IF ERRORLEVEL 1 GOTO ERROR

REM STATSPACKレポートを作成したフォルダに移動する
MOVE %BAT_PATH%*.LST %REPORT_PATH%%DAY_BEFORE2%
IF ERRORLEVEL 1 GOTO ERROR

REM フォルダサイズが少し大きいため、圧縮する
POWERSHELL COMPRESS-ARCHIVE -FORCE %REPORT_PATH%%DAY_BEFORE2% %REPORT_PATH%%DAY_BEFORE2%.ZIP
IF ERRORLEVEL 1 GOTO ERROR

REM 圧縮後、不要になったフォルダを削除
RMDIR /S /Q %REPORT_PATH%%DAY_BEFORE2%
IF ERRORLEVEL 1 GOTO ERROR

REM データ保存期間は1年としているため、1年前の圧縮ファイルを削除
FORFILES /P %REPORT_PATH% /D -365 /M "*.ZIP" /C "CMD /C DEL @FILE"

:SUCCESS
ECHO 正常終了,%DATE% %TIME:~0,8% > %BAT_PATH%LOG\CREATE_STATSPACK.LOG
GOTO END

:ERROR
ECHO 異常終了,%DATE% %TIME:~0,8% > %BAT_PATH%LOG\CREATE_STATSPACK.LOG
GOTO END

:END

EXIT

日付加工用処理

strFile = "ファイルパスを指定する"

'ファイルシステムオブジェクト作成
Set objFS = CreateObject("Scripting.FileSystemObject")

' ファイルオープン
Set objText = objFS.OpenTextFile(strFile, 2)

' 書き込み※/ありの日付
objtext.Write(Date() - 1)

' ファイルクローズ
objText.Close

strFile2 = "ファイルパスを指定する"

'ファイルシステムオブジェクト作成
Set objFS2 = CreateObject("Scripting.FileSystemObject")

' ファイルオープン
Set objText2 = objFS2.OpenTextFile(strFile2, 2)

d = Date() - 1

' 書き込み※/なしの日付
objtext2.Write(Replace(d, "/", ""))

' ファイルクローズ
objText2.Close

スナップショット取得処理

WHENEVER SQLERROR EXIT SQL.SQLCODE ROLLBACK
CONNECT perfstat/パスワード@サービス名

SET FEEDBACK OFF
SET HEADING OFF
SET VERIFY OFF
SET PAGESIZE 0
SET LINESIZE 100
SET FEED OFF
SET TRIMS ON

SPOOL テキストを出力するパス

WITH WK AS (
SELECT SNAP_ID ,ROW_NUMBER() OVER (ORDER BY SNAP_ID) AS SEQ ,TO_CHAR(SNAP_TIME, 'HH24') AS SNAP_TIME
FROM PERFSTAT.STATS$SNAPSHOT
WHERE TO_CHAR(TO_DATE(SNAP_TIME ,'YYYY/MM/DD')) = TO_CHAR(TO_DATE( '&1' ,'YYYY/MM/DD'))
)
SELECT TRIM(A.SNAP_ID) || '	' || TRIM(B.SNAP_ID) || '	' || TRIM(A.SNAP_TIME) || '	' || TRIM(B.SNAP_TIME)
FROM WK A
LEFT JOIN WK B
ON A.SEQ+1 = B.SEQ
WHERE B.SNAP_ID IS NOT NULL;

SPOOL OFF

EXIT

STATSPACK出力処理

WHENEVER OSERROR EXIT 99
WHENEVER SQLERROR EXIT 99
CONNECT perfstat/パスワード@サービス名

SET LINESIZE 300
SET PAGESIZE 0
SET TAB OFF
SET ECHO OFF
SET HEAD OFF
SET FEEDBACK OFF
SET VERIFY OFF
SET TRIMSPOOL ON
SET ARRAYSIZE 5000
SET TERM OFF

DEFINE begin_snap="&1"
DEFINE end_snap="&2"
DEFINE report_name="&3"
 
@?/rdbms/admin/spreport.sql

EXIT

注意点

以下、3点の注意に留意すること。

①前日以外の出力について
処理は前日のスナップショットを出力するものであるため、当日のスナップショットを基に出したいなどが発生する場合、日付を決めているVBSを修正するか、VBSをコメントアウトして、WORKファイルに直に日付を入れて対応することになる。

②DB再起動の影響について
STATSPACKの仕様で、DBを再起動した時間のスナップショットは作成されないため、DBを再起動した時間帯のレポートは出力されないので注意が必要。

③出力したレポートについて
レポートは1年間保持で、それ以降は削除されるようになっているが、使ってるサーバやPCの容量によては、レポートファイルのサイズが容量を圧迫する可能性があるため、注意が必要。

まとめ

STATSPACKは障害やパフォーマンス調査に便利だが、出力が面倒なため、自動化することをお勧めする。

コメント

タイトルとURLをコピーしました