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

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

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


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

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

By kamii - Last updated: 火曜日, 8月 17, 2010

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


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

DFSMSの保証スペース

By kamii - Last updated: 火曜日, 8月 17, 2010

数千シリンダーを超えるような大きなデータセットを作成する場合、複数のボリュームに分散して割り当てることができます。マルチボリューム・データセットなどと呼ばれ、古くから利用されてきました。

データセットを最大3つのボリュームに分散して作成します。最初に割り振られるスペースはボリュームDATA01に3000シリンダーです。DATA01に3000シリンダーを満たす空きスペースがなければ、最初の割り振りに失敗します。最初の割り振りに成功した後、3000シリンダーを使い切ると、OSは同じボリュームに1000シリンダー分の2次量で追加の割り振りを試みます。ボリュームに空きがなければDATA02、そこも空きがなければDATA03と順に最大3ボリュームにまたがってスペースが割り振られていきます。

これが基本的なデータセット・スペースの拡張メカニズムですが、使う側から見ると問題がないわけではありません。確実にスペースが割り振られるのは最初の3000シリンダーだけです。たとえ2次量を指定して、複数のボリュームにまたがってもかまわないことを指定していても、2次スペース量の拡張時に指定されたボリュームに空きがなければ追加の割り振りはできません。その結果スペース不足でジョブはABENDしてしまいます。

このような問題を回避するためDFSMSには保証スペース(Guaranteed Space)という機能があります。SMSのストレージクラスにGuaranteed Space=Yesの属性を与えれば、指定されたすべてのボリュームに1次量を割り振ります。

データセットは指定されたすべてのボリューム(DATA01,DATA02,DATA03)に1次量である3000シリンダーが割り振られ、最初に作成した時点で3000シリンダー×3ボリュームで9000シリンダーのスペース量が確保されます。2次量が指定されていれば最初のボリュームの1次スペースが一杯になると同じボリューム内で可能なだけの2次スペース量拡張が行われ、それをすべて使い切ってから、2番目のボリュームのすでに割り振り済みの1次スペースが使われます。絶対に必要としたいスペース量を事前に割り振ることができるため、運用中にスペース不足でジョブがABENDすることを防げます。保証スペースは、指定した1次量を複数のボリュームに分散するのではありません(例えば1000cylを250cylずつ4ボリュームに割り振る)、また指定した1次量が最初のボリュームでまかないきれず不足分を次のボリュームに割り当てるものでもありません(例えば1000cylのうち、最初のボリュームに800cyl、2番目のボリュームに200cylを割り振る)。VOLパラメーターで指定されたすべてのボリュームにSPACEパラメーターで指定された1次量を割り振ります。したがってその仕組みを考慮して1次量を指定します。例えば全部で5000シリンダーが必要で、5つのボリュームが使えるなら1次量は1000cylとします。指定されたボリュームのうち、1つでも1次量を満たす空きスペースがなければデータセットは作成されません。



なおラージ・データセットを作成し、かつそのスペース割り振りを保証するには、保証スペース機能の他にも3390-9型以上の大容量ボリュームに単一エクステントのデータセットとして作成する方法もあります。一般のデータセットでは1つのボリュームに割り当てることができるエクステント(ボリューム内でデータセットに割り当てられる連続した領域)は最大65535トラックに制限されますが、拡張形式の順次データセットやVSAMデータセットはこれを超える容量のデータセット・エクステントを割り当てることができます。拡張形式のPSデータセットなら、30000シリンダーという巨大なデータセットでも単一エクステントで割り振ることができます。


保証スペースやラージ・エクステントに関する詳細はマニュアル「z/OS DFSMS データ・セットの使用法」に解説されています。

Filed in アドミニストレーター編

FTP

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

FTP:ファイル転送プログラム(File Transfer Program)


FTPそのものが何であるかを解説する必要はないでしょう。メインフレームでもTCP/IPがサポートされてから、FTPもTCPアプリケーション(ユーティリティー)として利用できるようになっています。以前はFTPの利用を嫌うユーザーも多く「TCPは使えますがFTPは禁止です」というところもありました。最近ではどうなのでしょうか?以前ほどFTPは使わせない、というところは少ないように思います。


FTPにはクライアントとサーバーの2種類がありますが、いずれも利用できます。ただしMSPではFTPサーバーの利用にはDTSというPPが別に導入されている必要がありました(もしかしたら今ではTISP単独で利用可能になっているかも知れません)。
メインフレームと言えばサーバー・コンピューターでもありますから、FTPもサーバーで使うもの、と思われがちですが決してそんなことはありません。むしろFTPはクライアントで使う方がバッチジョブのステップに組み込めますから、自動的なデータ転送処理を行いたいときなどに便利です。


FTPサーバーは、PC上のファイル(例えばJCLやソースプログラム、業務処理用のデータ制御ファイルなど)を区分データセットのメンバーや順次データセットとして送りたい場合によく使われます。基本的には利用者が使いたいときに起動するものではなく、システムのIPL後に常駐タスク(アドレス空間)として起動されます。z/OSではTCPIPサービスの起動時に、FTPデーモンプロセスがUSS(Unix System Service)を使ってアクティブになります。いずれにせよFTPサーバーに関しては利用者の好みに合わせて機能を選択したり設定を変えたりはできません。システム管理者がセンター環境に合わせて設定した範囲での利用になります。
メインフレームのFTPサーバーを利用するクライアントは同じメインフレームに限らず、Unix、WindowsなどTCPをサポートしたプラットフォームであればかまいません。


データセットとファイルパス

z/OSのHFSでなければ、MVSではUnixやWindowsのような階層ファイルシステムではありません。しかしFTPにおけるファイル名は階層を意識したファイルパスでの指定になっています。例えばMVS(z/OS)のTCPIPのFTPでは、D:/folder1/subfolder2/JCLCOPY.txt のようなファイルパスとファイル名は、UAP1/JCLLIB/JCLCOPY のようにデータセットの修飾子で区切られたファイルパスとして表現されます。データセット名は修飾子で区切られた階層によって構成されているので、それを階層ファイルシステムのパス名のように割り当てます。データセット名の各修飾子をフォルダー名のように扱うわけです。そのためデータセットはカタログされていることが前提です。ディレクトリパスUAP1/JCLLIB、ファイル名JCLCOPY は UAP1.JCLLIB.JCLCOPY という順次データセットか、UAP1.JCLLIB という区分データセットのメンバーJCLCOPY を示します。
このようにDSNの修飾子をディレクトリに置き換えて対応させるマッピング方法を知ることは、LSコマンドなどディレクトリ内のファイル一覧を表示させたい場合に役立ちます。初期ディレクトリはFTPサーバーにログインした際のアカウント名(TSOユーザーID)です。USERID=RTJ6638でログインした場合、ログイン後に LS コマンドを入れると修飾子 RTJ6638 で始まるDSNがリストされます。その状態で CD TEST と入力すればカレントディレクトリは RTJ6638.TEST に変わり、LSコマンドを入れると修飾子 RTJ6638.TEST で始まるDSNがリストされます。先頭修飾子を UAP1 に変えたければ CD ‘UAP1′ と入力します。
しかしGETやPUTで転送の対象となるデータセットが予めわかっているなら、最終修飾子やメンバー名がファイル名になるよう階層を掘り下げなくても、’RTJ6638.TEST.DATA1′ や ‘RTJ6638.JCL(IEBCOPY)’ のようにDSNをアポストロフィで囲めば、メインフレームのデータセット名の形式で指定することもできます。各メーカーが提供するFTPソフトウェアの仕様によって細かな点は異なるので必要に応じてマニュアルなどを参照して下さい。


FTPによっては、DD名をサポートしている場合もあります。例えばz/OSでは、メインフレーム側のファイル名として、//DD:ddname が指定できます。これはJCLにDD名ddnameで定義されているDDステートメントに定義されたデータセットを示します。この場合、ターゲットのデータセットはカタログされていなくてもかまいません。UNITとVOL=SERパラメーターでデータセットの場所を特定することができます。VOS3のXTCPでは、DD(ddname) と指定します。また INTRDR はJESのリーダーを示し、転送したファイルをJCLとしてサブミットする場合に使われます(z/OSでは事前にSITEコマンドが必要)。なおDD名指定のファイル転送はFTPクライアントで使用されます。


文字コードの変換

異なる文字コードを持つプラットフォーム間の転送では、文字コードの変換が必要です。送り手、受けてどちらが変換するかは考え方がいろいろあります。「受け手が自分と違うコードなら変換する」という仕様なら同じ文字コードであれば変換が不要なのですっきりするとか、サーバーとクライアントならサーバー側でやるべき、とかです。しかし現実メインフレームの場合は、送り手だろうが受け手だろうが、メインフレームが他と異なる特有の世界のコードを使っているのが実情なので、クライアントであってもメインフレーム側のFTPで文字コードを変換するのが一般的です。メインフレームのFTPでは単にECBDICとASCIIの変換だけでなく、日本語コードをShiftJISやEUCなど相手側ホストの文字コードに合わせて変換できます。z/OSのFTPであれば、シフトコードの位置に擬似コード(文字→や←)を入れてそこにシフトコードがあることを示したり、バイナリー転送時に可変長レコードのデータセットのRDWを付加して元のレコードが何バイトなのかを識別できるようにしたり、などきめ細かなコード変換機能を持っています。


FTPの使用サンプルはこちらのページに記載しています。


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

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

By kamii - Last updated: 木曜日, 8月 12, 2010

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

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

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

By kamii - Last updated: 木曜日, 8月 5, 2010

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

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

米国IBMの公式入門書?

By kamii - Last updated: 木曜日, 8月 5, 2010

USのIBM WebサイトからはRedbookという解説書を得ることができます。その中からメジャーな製品の入門書的なものを以下に紹介します。このサイト(IBM Redbooks)には数千冊ものredbookが登録されています。タイトルの一部をキーワードで検索することもできますから必要とするものが見つかるかも知れません。すべて英文になりますが、どれも有益な資料です。






Introduction to the New Mainframe:
z/OS Basics
z/OSおよびOSと共に利用されている代表的なミドルウェアについての概説書。
Introduction to the New Mainframe:
z/VM Basics
z/VMについての概説書。
IMS PrimerIMS入門書。
MQSeries PrimerMQ入門書。
DFSMShsm PrimerDFSMShsm入門書(DFSMSの階層ストレージ管理:データセットのマイグレート/リコール)。
DFSMSrmm PrimerDFSMSrmm入門書(DFSMSのリムーバブルメディア管理:テープや仮想テープボリュームの管理)。
VSAM DemystifiedVSAMの内部構造や仕組みを解説したもの。入門書の域を超えているがアプリケーションプログラマーにとってもVSAMのファイル設計などにも役立つ内容が載っている。

 




Filed in メインフレーム情報

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 オペレーション・運用