LOGRECデータセットのプリントとイニシャライズ

By kamii - Last updated: 水曜日, 8月 4, 2010

LOGREC(SYS1.LOGREC)はハードウェアおよびソフトウェア(主にOS)のエラーログを記録するデータセットです。EREP(Environmental Record Editing and Printing Program)というユーティリティーを使うことによって記録されているレコードを編集し印刷することができます。


LOGRECデータセットのレコード内容を印刷する。(MVS)


LOGRECデータセットのバックアップ。(MVS)

システム稼働中にLOGRECが一杯になった時などは、取り急ぎ順次データセットへ書き出し、後からヒストリー・データセットによってレポートすることもできます。


LOGRECデータセットのクリアー(再初期化)。(MVS)


EREPの詳細はマニュアル「Environmental Record Editing and Printing Program(EREP) User’s Guide」(http://publibfp.dhe.ibm.com/epubs/pdf/ifc5g102.pdf)や「Environmental Record Editing and Printing Program(EREP) Reference」(http://publibfp.dhe.ibm.com/epubs/pdf/ifc5r105.pdf)を参照して下さい。その他「MVS 診断: ツールと保守援助プログラム」にも少し載ってるはずです。
MSPなら「サービスエイド使用手引書」あたりに載ってるはずです。VOS3では確かLOGRECをRASLOGと呼んでたと記憶してます。マニュアルはちょっと思い出せません。資料も残してませんでした。

Filed in ありがたいサンプルJCL

REXXでポインター??

By kamii - Last updated: 水曜日, 8月 4, 2010

必要があってREXXのプログラムを書くことになったのですが、アセンブラーでは当たり前のように使えるアドレス・ポインターが使えない。同じ構造のデータ・テーブルが複数あって、それを探索するサブルーチンを作りたい。アセンブラーだと探索するテーブルのアドレスをサブルーチンに渡せば事足りるけど、REXXのようにアドレスを扱う言語でないとそれができない。テーブルには名前があるのでそれを引数で渡せば、と思ったがそれはテーブルの場所(先頭アドレス)が渡るのではなく名前そのものが引数になってしまい上手く行かない。同じ処理を行うサブルーチンを、それぞれのテーブル用に名前を変えて何個も作れば簡単なのだが、本当にみんなそんなことをしているのかと疑問に思った。
ネットを探しまくり、value関数の使い方で実現できることがわかった。備忘録代わりに残しておきます。変数エリアの場所を示すアドレスを間接的に使って値を取り出す方法とも言えます。
プログラムは複数のデータ・テーブルを持つ。各テーブルはデータは違うが構造は同じ。入力されたパラメーターが正しいか(テーブルに登録されているか)を調べるサブルーチンを作りたい。チェックしたい値(キー)と、どのテーブルを探すかをサブルーチンに渡し、サブルーチンそのものは1つで各テーブル共用に作りたい。そういう場合にサブルーチンでは渡されたテーブル名を名前の文字列そのものではなく、テーブルの場所を示す引数として処理したい。そういう場合に参考にできます。C言語でいうポインターとは違うけど、引数をポインターっぽく処理する例かな。


/* REXX */
/* Application Data Table-1 */
APT1.0 = 7;    /* Num of Table Entries */
APT1.1 = 2698;
APT1.2 = 3875;
APT1.3 = 4033;
APT1.4 = 5901;
APT1.5 = 7739;
APT1.6 = 8706;
APT1.7 = 9999;
/* Application Data Table-2 */
APT2.0 = 3;    /* Num of Table Entries */
APT2.1 = NYZ;
APT2.2 = XEZ;
APT2.3 = JGZ;

/* Main Procedures */
ARG key;
rc = TableSearch(key, APT1);
if rc = 1 then SAY "Input Key is correct in Table-1:" key
          else SAY "Input Key is invalid in Table-1:" key;

rc = TableSearch(key, APT2);
if rc = 1 then SAY "Input Key is correct in Table-2:" key
          else SAY "Input Key is invalid in Table-2:" key;
exit;

/* Sub Routines */
/* ------------------------------------- */
/* TableSearch(arg1, arg2)               */
/* arg1 --> search value                 */
/* arg2 --> Table Name                   */
/*                                       */
/* rc ----> 0: Table Entry is not found. */
/*          1: Table Entry is found.     */
/* ------------------------------------- */
TableSearch:
  ts_found = 0;
  parse arg ts_value, ts_table;
  do i = 1 to value(value(ts_table).0);
    if (value(value(ts_table).i) = ts_value) then do;
      ts_found = 1;
      leave;
    end;
  end;
return ts_found;

同じ処理だけどCやREXXに慣れてなければこっちの方がわかりやすいかな。
TableSearch:
  ts_found = 0;
  parse arg ts_value, ts_table;
  ts_loopn = value(value(ts_table).0);
  do i = 1 to ts_loopn;
    ts_entry = value(value(ts_table).i);
    if (ts_entry = ts_value) then do;
      ts_found = 1;
      leave;
    end;
  end;
return ts_found;

TableSearchというサブルーチンは2つの引数を持つ。1つは探したいキーの値(例えば入力されたパラメーター値など)、もう1つが探す対象となるテーブル名。value関数を入れ子で使うとテーブル名に添え字を付けて、テーブル内の値を取り出せるようである。REXXは専門ではないので細かいことは追求してないけど、こういう発想って感心します。変数の値を参照するのはいちいちvalue関数使わなくてもできるし、いつ使うんでしょ、とも思うが、それを重ねて使うとこうなるとは。エントリーを探すループの中に「SAY value(ts_table) i value(value(ts_table).i);」を入れてみるとvalue関数の動きがわかりやすい。
これで次のようにテーブル名を直接プログラムの中に書いたサブルーチンをテーブル毎に書くようなことをしなくても済みます。

TableSearch1:
  ts_found = 0;
  parse arg ts_value;
  do i = 1 to APT1.0;
    if (APT1.i = ts_value) then do;
      ts_found = 1;
      leave;
    end;
  end;
return ts_found;
Filed in REXX入門

お手軽バッチ・パフォーマンス改善 – IV

By kamii - Last updated: 月曜日, 7月 26, 2010

データセットのI/O効率を上げる(続き)

いずれにせよブロックサイズやCIサイズを大きくする(適切なサイズにする)だけで効果が上がるのは、順次や区分データセット、VSAMならESDSやKSDSのシーケンシャル・アクセスの場合と考えていいでしょう。

Filed in オペレーション・運用

お手軽バッチ・パフォーマンス改善 – III

By kamii - Last updated: 日曜日, 7月 25, 2010

データセットのI/O効率を上げる(続き)

Filed in オペレーション・運用

お手軽バッチ・パフォーマンス改善 – II

By kamii - Last updated: 日曜日, 7月 25, 2010

データセットのI/O効率を上げる

アプリケーションのバッチ処理では、ファイル(データセット、データベース)に一切アクセスしないものは少ないです。たいていのプログラムはファイルからデータを読み取り、集計や帳票の作成など何らかの業務的な加工処理を行います。またデータを変換して別のファイルに新たなデータとして書き出したり、既存のデータを更新したりします。そのような処理では必ずI/Oを伴いますから、I/O効率を上げることはパフォーマンスの改善に大きく寄与します。ここではI/O効率を見直す中で比較的アプローチしやすいもので考えてみます。

z/OSのDFSMSのマニュアルに、次のような解説があります。
「入出力パフォーマンスは、データを仮想記憶域へと、または仮想記憶域から転送するために必要なプロセッサー時間とチャネル始動/停止時間の両方を削減することによって改善されます。パフォーマンスに影響を及ぼすいくつかの要因を以下に示します。」

最初のアドレス・スペース・タイプについては考える必要はありません。ずいぶんと昔は高いパフォーマンスでジョブを動かすためにJCLのEXEC文にADDRSPC=REALという指定をしたものもあったようですが(V=Rジョブ)、もはや使われてはいないでしょう。V=Rはジョブのメモリーを実記憶に固定します。筆者は自分で使ったことがないので想像ですが、ページング・オーバーヘッドをなくしたり、特別な理由でページングされると困るようなプログラム、I/Oを直接発行するようなプログラムで処理効率を上げるため仮想アドレスと実アドレスが同じであることを前提にしたいプログラムなどのために使われたのだと考えます。
2番目と3番目のブロックサイズとBUFNOは簡単な知識と手間で、意外と効果を得られたりします。4番目のBSAMは今ではアプリケーションプログラムではほとんど使われないため考えなくていいでしょう。COBOLなどのコンパイラーも基本的にはQSAMを使用していると思ってます。
5番目のアクティビティーは、CPUとチャネルが他のジョブで使われていればその間は待たされる、ということです。6番目はデバイスの種類によってI/Oパフォーマンスは変わることを示しています。テープよりはディスク、同じディスクでもモデルによって変わります。またOSからは同じモデルに見えても、ハードウェアとしてのグレードによってもI/Oパフォーマンスは変わります。
残りの2つはz/OSならではのもので、拡張フォーマットやストライピングをサポートした新しいタイプの順次データセットや拡張区分データセットではアクセス効率もよくなっていますが、業務用のデータセットやライブラリーをそれらに移行することになるので、計画的に行う必要があります。規模が大きいと簡単には行かないでしょう。

Filed in オペレーション・運用

お手軽バッチ・パフォーマンス改善 – I

By kamii - Last updated: 日曜日, 7月 25, 2010

パフォーマンス・チューニングというと、とかくRMFレポートと格闘してPARMLIBのIPSやICSのパラメーターをいじる(z/OSではWLMのワークロードやサービスクラスの設定)というイメージがあります。
より細かい現状分析にはRMF(MSPではPDA)レポートなどを見ることは避けられませんが、ここではそんな高度(面倒)なことではなく、もっと身近なもので比較的お手軽にできるパフォーマンス・アップを考えてみます。

いろいろなアプローチがありますが、大きく分けるとCPU使用量を減らすかI/O効率を上げるかになります。
その他にも「待ち」を減らす、というのもあります。ジョブの多重度が上がるほど「待ち」はELAP時間(実行時間)に大きく影響します。CPUを10秒使う、I/Oを100000回行う、といった同じ処理を実行しても、そのジョブしか動かない場合ではELAP時間は30秒なのに、他に別の10ジョブが並行して動いているような場合では2分掛かる、という具合です。このような待ち時間の大小によるパフォーマンスのぶれを調整し、適切なリソース配分やプライオリティ調整をすることもチューニングの大切な作業です。しかしそれはこのトピックの目的とずれてしまうので機会を改めることとし、ここでは採り上げません。このトピックでは個々のジョブ・ステップ単独での効率アップについて見てみます。


アプリケーションプログラム自身が使うCPU使用量を減らす

CPUについてはプログラム論理の見直しで使用量を削減するのは、元がよほどひどいプログラムでない限りあまり大きな期待はできません。そういう箇所を見つける苦労の割りには効果が薄いです。現実的にはコンパイラーのオプション(OPTIMIZE)によって最適化されたコードを生成する、という感じでしょうか。最適化は実行コードとストレージ量の2つの観点によって行われます。
またコンパイラーで注意すべきことの1つとしてデバッグオプションの付けっぱなしがあります。何らかの理由で後から1本だけ直してテストしたものが、誤ってデバッグオプションが付いたまま運用されてしまったようなケースです。本来なら不要な命令を常に実行し続けることになります。何かあったときに調べられないと困るから、デバッグオプションははずせないという考え方もありますが、基本的には本番の運用では不要でしょう。

その他にもタイミングを取るためにループで待ち合わせるプログラムなどがあると極端なCPUを使うことがあります。普段は通らないが何らかのケースの状態が起きるとタイミングを取る必要が生じて、それをループで行っているようなプログラムがあるとそこでCPUが極端に使われます。常に通るところでループしていれば簡単にわかりますが、月に数回とかたまにとかの頻度でしかループによる待ち合わせロジックを通ることがなく、しかもループ時間もそう長くない、という場合はみつけにくいです。
一般的にメインフレームのプログラムではアプリケーション側がループで待ち合わせるような作り方はしないのですが、COBOLなどにはタイマー待ち合わせ(SLEEP)などの機能がないので、ループの中で現時刻を得て一定時間が過ぎたかをチェックしてループから抜けたり、データセットの特定のレコードを何度も読み出してその内容が変わっていたら待ち合わせ終了にするなどのロジックが作られることもあります。このようなケースではプログラムの修正が必要なので、お手軽チューニングの範疇を超えますが、実際にそういうこともあり得るのだと知っておくといいでしょう。


Filed in オペレーション・運用

ENQ/DEQ

By kamii - Last updated: 土曜日, 6月 26, 2010

ENQ/DEQ:プログラムが排他制御に使うAPIサービスのこと

OSの重要な機能のひとつに「資源の逐次化」があります。排他制御とも呼ばれ、メモリーやデータセットなど複数のプログラムで取り合いになるリソースを順番に使わせるものです。複数のプログラムを同時に動かすマルチ・タスキングをサポートするOSには欠かせないものです。

MVSでは一般のアプリケーション・プログラムが排他制御を行うAPIサービスとしてENQ/DEQというアセンブラー言語用マクロ命令を用意しています。ENQが排他制御のために資源を使う権利を得るもので、DEQは逆にその権利を解放します。

次のプログラムは、複数のタスクでメモリー内の共用領域を更新する場合のENQ/DEQを使用した排他制御の例です。

         :
         ENQ   (RESQNAME,RESRNAM1,E,L'RESRNAM1,STEP),RET=USE
         LTR   15,15
         BNZ   SHORT_WAIT   排他制御に失敗したらSHORT_WAITへ飛ぶ
         :
         :
         テーブル内データの更新処理を行う
         :
         :
         DEQ   (RESQNAME,RESRNAM1,L'RESRNAM1,STEP),RET=HAVE
         :


         :
RESQNAME DC    CL8'SHRTABLE'
RESRNAM1 DC    CL32'USER-ACCOUNT-TABLE'
         :

ENQ/DEQでは排他制御の対象になる資源は、あらかじめ決められているわけではなく、サービスの利用者が自由に設定できます。プログラム内のメモリー領域でもいいし、データセット、ファイル内のレコードなど何でもかまいません。ただデータセット全体やデータベース内のレコードなどは、プログラムが自分で直接排他制御するよりは、DD文のDISPパラメーターやデータベースが提供する排他制御の機能を使うことが一般的です。
このサンプルでは、競合してアクセスするテーブル領域に名前を付けて排他制御の資源名にしています。資源名はQ名とR名に分かれ2階層で分類できるようになっています。ENQマクロでは、資源の名前(Q名とR名)、排他の方法(占有/共用)、排他の範囲を指定して排他制御を要求します。
排他の範囲はSCOPEと呼ばれ、ENQマクロではSTEP(同一空間内)、SYSTEM(同一OS内の複数空間)、SYSTEMS(複数OSにまたがる複数空間)が指定できます。

ENQで獲得した排他制御は、資源を使い終わったらすみやかにDEQによって解放しなければなりません。どの資源にどのような名前を付け、どのタイミングで排他制御を行うかはすべてアプリケーション・プログラムのデザインとして決め、決められたとおりにプログラミングしなければなりません。MVSは排他制御のためのメカニズムは提供しますが、アプリケーションが正しい排他制御をしているかまではチェックできません。仮に排他制御が必要なメモリー領域をENQせずにアクセスしてもCPUはそのまま命令を実行してしまいます。あくまでも、決められたルールは決められた通りに守っている、ことが前提のしくみであることを知っておく必要があります。

ENQ/DEQを使うためには最低でもプログラムはアセンブラー言語で作成される必要があります。あるいはアセンブラー言語で排他制御用サブルーチンを作成し、それを呼び出すかです。COBOLなどで作成されたアプリケーションでは、プログラムが資源を直接排他制御することは少なく、アクセスメソッドやデータベース、TPモニターの排他制御機能によって間接的に排他制御を行うのが一般的です。


ENQ/DEQの他、MVSにはOS自身などの制御プログラムが使う「ロック」という排他制御サービスもあります。こちらはENQ/DEQのように任意の資源を指定できず、OSがあらかじめ定めたごく少ない種類の資源のみ排他制御できますが、ENQ/DEQよりはるかに少ないオーバーヘッドで処理できます。また制御プログラムではハードウェアの機能によってメモリー内のフィールドをCPU命令によってロックする方法も使われます。

Filed in キーワードから(何が知りたいですか)

正しい構文?のPARMLIBメンバーなのにIPLエラーになる?

By kamii - Last updated: 水曜日, 6月 23, 2010

MVSの動き方を決める重要なシステム設定パラメーターとして、PARMLIBメンバーがあります。元々はSYS1.PARMLIBという名称の区分データセットが使われていました。現在ではインストール時のカスタマイズによって異なるDSNにしたり、PARMLIBライブラリーを複数のデータセットに分散することもできます。

ずいぶん以前のMVSでは、PARMLIBメンバーにエラーがあるだけでもIPLが止まってしまうため、パラメーター・メンバーの修正にはずいぶんと気を使ったものです。運用で使用しているメンバーを直接直さずに代替のメンバーを作り、そちらを修正する。あるいは現行のメンバー内容をコピーした代替メンバーを作っておき、もしIPLに失敗したら、代替メンバーのパラメーターでIPLし直す、などはよく行われました。これらはIPLができないとOSが起動しないのでエラーを起こしてしまったメンバーを直したり元に戻したりすることができないからでもありました。
しかしOS/390、z/OSとなった現在のMVSでは、PARMLIBメンバーのパラメーター定義や値に誤りなどがあってもよほどのものでない限り、エラーは無視され(警告はされる)IPLが途中で止まるようなことはなくなりました。

そんな中で「これのどこがエラー?」と見えてしまいそうなものをひとつ。

コメントの終わり位置が悪いためエラーとなる

NJEのテストをするためOS内にテスト用の代替JES2を追加した

落ち着いて見ればわかりますが、このような一見すると正しく見え、どこがおかしい?という類のものはなかなか原因を見つけられないというもののひとつでもあります。そうでなくてもIPLでエラーが出たりすると、(自分が直したのが原因であることが明白で)あせりが先に立ってしまったりするものです。

Filed in オペレーション・運用

SYSLOG

By kamii - Last updated: 金曜日, 6月 18, 2010

SYSLOG:System LOG、システム・ログ

システム・ログは、MVS上でのシステムの活動状況や、すべてのジョブからのコンソール・メッセージなどが時系列に記録される、JES2スプール内のSYSOUTデータセットでシスログ(SYSLOG)と呼ばれます。
コンソールに出力される様々なメッセージのうち、センターによって不要と扱われるメッセージなどはコンソールへの出力が抑止されるようなカスタマイズも行われていますが、システム・ログにはすべて記録されます。マスター・スケジューラーは、JES2と連係してシスログを処理します。

システム・ログには、MVS上でのシステムの活動状況が時系列に記録されているため、障害発生時の重要な問題識別の資料となります。特に、他のジョブからの要求を受けてサービスを提供するサーバー・プログラムや、他のジョブやサブシステム等にサービスを要求したり連係して動作したりするようなプログラムでは、障害となったジョブ以外のジョブやOSから関連するメッセージなどが出されている場合もあります。すべてのジョブからのメッセージが記録されているシステム・ログは有効な調査用資料となります。


システム・ログの出力

SYSLOGは、OSコマンドW(WRITELOG)によって出力することができます。

「W L」と入力すれば、IPL以降または前回のWRITELOGコマンド投入からその時点までのSYSLOGを、LクラスのSYSOUTとして印刷またはライター出力することができます。クラスを省略すれば、センターで指定したデフォルト・クラスが使われます。SYSLOGを保管する場合は、XWTRで、DASDあるいはTAPEに順データセットとしてコピーすることができます。


システム・ログの参照

SDSFには、SYSLOGの参照機能(LOG)があります(管理者またはオペレーター権限が必要)。これを利用すれば、WRITELOGコマンドを使わなくても、スプール内のSYSLOGデータセットを直接参照できます。ジョブ出力のSYSOUTと同様に、特定の文字列を検索したり、内容をデータセットにコピーしたりできます。
MSPではECS、VOS3ではSYSLOG2を利用すれば、SYSLOGを参照できます。

MVSではPTコマンドをによってSYSLOGを簡単な操作で任意のデータセットにコピーすることができます。コピーする範囲を「開始時刻 開始日付 終了時刻 終了日付」で指定することもできます。


システム・ログのフォーマット(MVS)


システム・ログのフォーマット(MSP,VOS3)

Filed in キーワードから(何が知りたいですか)

KBKARCS

By kamii - Last updated: 木曜日, 6月 17, 2010

ARCS(ARChives Service program):富士通OSにおけるDASDボリューム・ユーティリティー

ARCSは富士通のメインフレーム用ソフトウェアで、DASDボリューム上のデータの退避、復元、複写、移行を行うユーティリティーです。KBKARCSはそのプログラム名です。マニュアル「ARCS使用手引書」に詳細が記載されています。MSPおよびXSPで利用できます。

Filed in キーワードから(何が知りたいですか)