IBM InfoSphere Information Server DataStageのジョブ実行履歴リポジトリについて






# 1. はじめに
IBM InfoSphere Information Server DataStage（以下、DataStageと表記）は、IBMが提供するETLツールです。GUIビルダーによるETLプログラムの開発が可能で、すでに多くのユーザーでの採用実績があります。IBMが提供する公式ドキュメント（Information Center）以外での情報が少ないために、私が仕事で得た知見を発信していくことができればと思います。
今回はETLプログラム（ジョブ）の開発に関する内容ではなく、運用設計についてのお話となります。

なお、今回はDataStageのV11.7.1を前提としています。また、本記事はIBMの正式なレビューを受けたものでは無いことをご了承ください。


# 2. DataStageのジョブ実行履歴リポジトリ概要

IBM Information Server Datastage(以下"DataStage")では、ジョブの実行履歴情報を2種類のリポジトリに保管しています。このリポジトリに保管された情報は、DataStageの管理コンソールやクライアントアプリで参照するほかに、CLIやSQLでアクセスすることもできます。ジョブの開始・終了時刻やメッセージ出力の他に、実行時間、処理したデータ量やサーバーリソースの使用状況などの統計情報も記録されているので、ジョブの実行状況について様々な分析が可能です。一方、これらの実行履歴情報はデフォルト設定では過去データのメンテナンスがされないため、データの蓄積によりDataStage自体の動作が遅くなり不安定になるという問題が発生します。

当資料では、DataStageのジョブ実行履歴情報の種類や活用方法、過去データのメンテナンス方法について解説します。

# 3. ジョブ実行履歴情報リポジトリのアーキテクチャ
DataStageのジョブ実行履歴情報リポジトリは2種類に分かれます。UVの独自データベース（UVlog）とオペレーションデータベース（DSODB）です。
![2023-01-16 10_07_49-DataStage_uvlog_DSODB運用.pptx - PowerPoint.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3113783/8d8a4d89-ee1a-a726-6c1f-c5701c9e43ed.png)

## 3-1. UVlog
- 独自形式のデータベース（実体はバイナリファイル）に保管される。
- 過去データ削除機能あり（自動実行/手動実行の選択が可能。自動実行はデフォルトではオフ）
- 情報の表示や過去データ削除は、DataStageのCLI（dsjobコマンド）で実行する


## 3-2. DSODB（DataStage Operation Database）
- リポジトリ層（Db2）のデータベースで管理
- 過去データ削除機能あり（削除の自動実行機能は無いので、作りこみが必要）
- 情報の表示はSQLで実行、過去データ削除はDataStageのCLI（istool ODBAdmin）またはSQLで実行する




# 4. UVlogの詳細

## 4-1. 構成
UVlogの実体は、以下のディレクトリに配置されたバイナリーファイルです、
/opt/IBM/InformationServer/Server/Projects/プロジェクト名/RT_LOGnn（nnは任意の英数字）


## 4-2. UVlogの表示方法
UVlogの内容を整形して表示するためには、DataStageのCLI（dsjobコマンド）を使用します。dsjobコマンドはDataStageのジョブを制御するための汎用的なコマンドで、以下のような機能を持っています。

- ジョブの開始・停止
- プロジェクト、ジョブ、ステージ、リンク、パラメーターのリスト
- 情報の取得
- ログ・ファイルへのアクセス
- レポートの生成

https://www.ibm.com/docs/en/iis/11.5?topic=interface-commands-controlling-infosphere-datastage-jobs

dsjobコマンドでUVlogを表示する場合、以下のサブコマンドを使用します。

ログのサマリーを表示する
~~~
dsjob -logsum プロジェクト名 ジョブ名
~~~
ログの詳細を表示する。
~~~
dsjob -logdetail プロジェクト名 ジョブ名 ログエントリのID
~~~
dsjobコマンドでUVlogを表示する場合、「直近のN日以内（N時間以内）」などの時間指定のオプションはありません。
UVlogの過去データ削除を実装する場合、過去データを整形してファイルに出力する→過去データを削除するといった流れにしたい場合があります。その場合、何らかの方法でログ出力の重複を排除する必要があります。
一案ですが、以下のような方法が考えられます。
(1) 一旦、"-logsum"オプションを使用してジョブログのサマリーを中間ファイルに出力
(2) ジョブログのサマリーの中から、表示したい日付のログエントリを抜き出し、そのIDを取得
(3) "-logdetail"オプションでログエントリのIDを指定して希望するログを取得

または、Linuxのuniqコマンドを使用して重複を排除する方法もあるでしょう。


## 4-3. UVlogの過去データ削除

以下の2つの方法があります。

### 方法1：手動実行
"dsjob -purge" コマンドを実行することで、過去データを手動で削除することが可能です。スクリプトに組み込むことにより、cronなどから定期実行させるorジョブ起動の度に実行することが可能です。

### 方法2：自動実行
DataStageの管理用CLI（dsadminコマンド）を使用して、プロジェクト毎にUVlogの過去データ自動削除を設定することができます。
~~~
＊ディレクトリへ移動 (環境変数DSHOME -> /opt/IBM/InformationServer/Server/DSEngine)
$ cd $DSHOME

＊ログ自動パージ設定を行う
$ bin/dsadmin –autopurgelog TRUE –days 3 プロジェクト名　　　← 適用したい変換プロジェクト名

＊変更後の設定確認
$ bin/dsadmin –listproperties プロジェクト名 | grep –e Purge –e Days –e Prev
PurgeEnabled=1
DaysOld=3
PrevRuns=0　　　　　← 左記のようになっていればOK（Purge設定:有効化／日数指定:3日間）
~~~

上記の設定を実行すると、自動削除が有効化されます。



なお、自動削除が実行されるタイミングですが、DataStageサーバーの日付が変わって最初に当該プロジェクトのジョブが実行され、完了した直後となります。基本的には自動削除を使用したほうが運用が楽だと思いますが、同一時刻に実行されるジョブ数が非常に多い場合（例えば、毎時0分に実行されるなど）には、自動削除処理同士が競合してエラーが発生する可能性があります。その場合は、手動削除処理を使用してタイミングをずらすことで対処が可能となります。

![2023-01-16 10_09_59-DataStage_uvlog_DSODB運用.pptx - PowerPoint.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3113783/0056ae7f-0eed-49e5-50d9-92b9915552e5.png)


# 5.DSODBの詳細

## 5-1. DSODB（DataStage Operation Database）の構成
DSODBにはジョブのメッセージ出力だけではなく、実行時間、処理したデータ量やサーバーリソースの使用状況などの統計情報も記録されているので、ジョブの実行状況について様々な分析が可能です。

デフォルトでは、DSODBはリポジトリ層（Db2）の"XMETA"というデータベースに格納されています。XMETAにはDataStageの様々な管理情報が格納されていますが、DSODBは"DSODB"スキーマ以下のテーブルに格納されています。


https://www.ibm.com/docs/ja/iis/11.5?topic=reference-operations-database-schema

DSODBスキーマのテーブルのうち、ジョブの実行状況分析に有効と考えられるものを挙げておきます。

 |テーブル |説明 |
 |--------|------|
 |JobExec |JobRun 表内のジョブ実行によって使用されたジョブ・バージョンの詳細が含まれています |
 |JobRun |すべてのジョブ実行の詳細が含まれています |
 |JobRunLog |JobRun 表内のジョブ実行によって出されたすべてのイベントが含まれています|
 |JobRunParamsView |JobRun表内のすべてのジョブ実行でのパラメータ名とパラメータ値が含まれています |
 |JobRunStage |すべてのジョブ実行におけるすべてのステージ処理の詳細が含まれています |
 |JobRunTotalRowsUsage |JobRunUsage表内の、各スナップショットによって消費および生成された行の数が表示されます |
 |ResourceUsageSystem |ResourceUsage表内のすべてのシステムについての過去のシステム・リソース使用状況に関する情報が表示されます |




## 5-2. DSODBのアクセス例

information centerにも情報の参照例がいくつか記載されています。

https://www.ibm.com/docs/ja/iis/11.5?topic=jobs-extracting-monitoring-data-from-operations-database


例えば、ジョブの実行数を開始時間ごとにカウントするためには、以下のようなSQLを実行します。（2022/05/10 00:00から23:59までで範囲を指定しています）

~~~
select to_char(runstarttimestamp,'YYYY/MM/DD HH24:MI') ,count(*) from DSODB.JOBRUN
group by to_char(runstarttimestamp,'YYYY/MM/DD HH24:MI') having to_char(runstarttimestamp,'YYYY/MM/DD HH24:MI') > '2022/05/10 00:00' and to_char(runstarttimestamp,'YYYY/MM/DD HH24:MI') < '2022/05/10 23:59'
~~~

他にも、JobRunテーブルの "ElapsedRunSecs" 列や "TotalRowsConsumed" 列の情報を参照することで、ジョブの実行時間や処理したデータの行数などの変動を時系列で把握することができます。




## 5-3. DSODBの過去データ削除

DataStageでは、DSODBの過去データを自動的に削除する機能はありません。そのため、シェルスクリプトなどを利用した作りこみが必要になります。DSODBの過去データが多くなると、管理コンソールなどの表示が遅くなったり、DataStageの動作が不安定になる可能性があります。

https://www.ibm.com/docs/ja/iis/11.5?topic=database-deleting-historical-data-from-operations

### 方法1：
istool ODBAdminコマンドの使用
~~~
istool ODBAdmin purgedb server area selector time_range output
~~~
以下のコマンドは、最新3日分よりも古いDSODBの過去データを削除します。

~~~
istool.sh ODBAdmin purgedb -domain サーバーのホスト名:ポート番号 -server サーバーのホスト名 -username ユーザー名 -password パスワード -full -engine サーバーのホスト名 -upto 3 -days -verbose
~~~
注意点：istool.sh ODBAdmin purgedbで過去データを削除する場合、コマンドは5分程度でタイムアウトしてしまいます（削除処理はバックグラウンドで継続処理されます）。


### 方法2：
SQL文を使用して、直接過去データを削除する

以下のSQLは、ジョブ終了日次が2022/05/10 00:00よりも古い過去データを削除する例です。

~~~
db2 "DELETE FROM DSODB.JobRun
 WHERE RunEndTimestamp < '2022-05-10-0.00.00'";
~~~
JobRunテーブルのエントリを削除すると、JobRunLogやJobRunStageなどの"JobRun**"テーブルの関連するエントリも自動的に削除されます。

また、DSODBのデータで定常的に増加し続けるものとしては、上記"JobRun**"テーブルの他に"ResourceUsage"テーブルもあります。以下のようなSQLを使用して、過去データを削除すると良いでしょう。

~~~
"DELETE FROM DSODB.ResourceUsage 
  WHERE StartTimeStamp < '2022-08-16-23.59.59';"
~~~

## 5-4. DSODB過去データの退避方法

DSODBの過去データは、DB2のexportコマンドで退避します。
DataStageサーバーの外部に検索用（過去データ保管用）データベースを構築して、そこにimportする、あるいは、CSVファイルをCloudのObject Storageに格納して、直接SQLでクエリーをかけるという方法も考えられます。

以下のSQLは、JoubRunLogテーブルから、ジョブ開始時刻が2022/07/12 00:00から23:59のエントリをexportする例です。
JoubRunLogテーブルにはタイムスタンプ情報が含まれていませんので、JobRunテーブルのRunStartTimeStamp列を検索条件に使用し、RUNID列を外部キーとして使用しています。
~~~
db2 "EXPORT TO DSODB.JobRunLog_2022-07-12.csv OF DEL MODIFIED BY timestampformat=\"yyyy-mm-dd hh:mm:ss.UUUUUU\"
SELECT
     P.RUNID
 ,   P.EVENTID
 ,   P.LOGTIMESTAMP
 ,   P.LOGTYPE
 ,   P.MESSAGEID
 ,   P.CONTENTTYPE
 ,   replace(replace(P.MESSAGETEXT,CHR(13),' '),CHR(10),' ')
FROM
       DSODB.JobRunLog AS P
     , DSODB.JobRun AS R
WHERE  R.RUNID = P.RUNID
  AND  R.RunStartTimeStamp >= '2022-07-12-0.00.00'
  AND  R.RunStartTimeStamp < '2022-07-12-23.59.59'
ORDER BY R.RunStartTimeStamp";
~~~

また、JobExecテーブル定期的にexportしておくと良いでしょう。JobExecテーブルのエントリは、ジョブがコンパイルされる度に追加されます（同じプロジェクトの同じ名前のジョブでも、再コンパイルすると内部的には異なるIDが採番されます）
したがって、以下のようなSQLを日次で実行すると良いでしょう。
~~~
db2 "EXPORT TO DSODB.JobExec_2022-08-16.csv OF DEL MODIFIED BY timestampformat=\"yyyy-mm-dd hh:mm:ss.UUUUUU\"
SELECT *
FROM DSODB.JobExec
WHERE J.CompilationTimestamp < '2022-08-16-23.59.59'";
~~~

![2023-01-16 10_10_07-DataStage_uvlog_DSODB運用.pptx - PowerPoint.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3113783/5e9beca3-eee3-0c2f-600e-651c72296381.png)


# 6.おわりに
DataStageには運用上の考慮点がいろいろあるのですが、解説資料があまり出回っていない気がします。私は実案件でDataStageの構築や運用をしていてハマった経験がいくつもあるので、それらを順次ご紹介していくことができればと考えています。