以前投稿した「消してしまったデータセットを復活させる」の記事は、z/OS V1R11に合わせて内容を修正していますが、区分データセットの復活については単一エクステントでも複数エクステントでも同じ方法で、また、PDSEであっても復活できる方法がわかったので備忘録代わりに新記事として掲載します。
(※この記事にはz/OS DFSMSdfpのDASDボリューム管理の知識を必要とする内容を含みます)
消してしまった区分データセット(PDSE含む)の復活を試みる
①消してしまったデータセットのエクステント位置にABSTRアロケーションで仮データセット枠を再割り振りする
1 2 3 4 5 6 7 8 9 10 11 12 13 |
//ALLOC EXEC PGM=IEFBR14 //ORGXT1 DD DISP=(,KEEP),DSN=DELETED.PDS.XT01,DCB=DSORG=DA, // UNIT=SYSDA,VOL=SER=volume,SPACE=(ABSTR,(100,02325)) // //ALLOC EXEC PGM=IEFBR14 //ORGXT1 DD DISP=(,KEEP),DSN=DELETED.PDS.XT01,DCB=DSORG=DA, // UNIT=SYSDA,VOL=SER=volume,SPACE=(ABSTR,(100,02325)) //ORGXT2 DD DISP=(,KEEP),DSN=DELETED.PDS.XT02,DCB=DSORG=DA, // UNIT=SYSDA,VOL=SER=volume,SPACE=(ABSTR,(050,01758)) //ORGXT3 DD DISP=(,KEEP),DSN=DELETED.PDS.XT03,DCB=DSORG=DA, // UNIT=SYSDA,VOL=SER=volume,SPACE=(ABSTR,(050,14562)) // |
ABSTR指定のSPACEパラメーターで、元のトラック位置に仮のデータセットを割り振ります。DCBパラメーターにはDSORG=DAだけを指定します。決してDSORG=POやPSにしてはなりません。PDSEの場合であってもDSNTYPE=LIBRARYは指定しません。複数エクステントで構成されていた場合は、エクステント毎に仮データセットを割り振ります。
この仮のデータセット自体は後続の作業では直接使用しません。消してしまったデータセットのトラック内容が、他のデータセットによって上書きされてしまうことを防ぐために行います。
②作業用のデータセットを作成する
1 2 3 4 5 6 7 8 9 10 |
//ALLOC EXEC PGM=IEFBR14 //WRKXTNT DD DISP=(,KEEP),DSN=SALVAGE.PDS.WORK,VOL=SER=VPWRKA, // UNIT=SYSDA,SPACE=(CYL,(20,0,50),,CONTIG), // DCB=(DSORG=PO,RECFM=FB,LRECL=80,BLKSIZE=3120) //ALLOC EXEC PGM=IEFBR14 //WRKXTNT DD DISP=(,KEEP),DSN=SALVAGE.PDSE.WORK,VOL=SER=VPWRKA, // UNIT=SYSDA,SPACE=(CYL,(20,0,0),,CONTIG), // DCB=(DSORG=PO,RECFM=FB,LRECL=80,BLKSIZE=32720),DSNTYPE=LIBRARY // |
元の区分データセットと同じ属性(DSORG、RECFM、LRECLおよびBLKSIZE)で作業用のデータセットを作成します。同じ装置タイプ(3390)であれば、別のボリュームに作ってもかまいません。スペース量は、ディレクトリー・ブロック数も含めて同じか大きめにします。なお、作業用データセットは単一エクステントが割り当てられるよう、CONTIGオプションを指定して必ず連続した領域を確保します。
③元のデータセットのトラック内容をコピーする
1 2 3 4 5 6 7 8 9 10 11 12 13 |
//DFDSS EXEC PGM=ADRDSSU,REGION=0M //SYSPRINT DD SYSOUT=* //SYSIN DD * COPY IDY(VPWRKA) ODY(VPWRKA) TRKS(82,0,88,9) OUTTRKS(547,0) // //DFDSS EXEC PGM=ADRDSSU,REGION=0M //SYSPRINT DD SYSOUT=* //SYSIN DD * COPY IDY(VPWRKA) ODY(VPWRKA) TRKS(82,0,83,14) OUTTRKS(547,0) COPY IDY(VPWRKA) ODY(VPWRKA) TRKS(53,5,56,12) OUTTRKS(549,0) COPY IDY(VPWRKA) ODY(VPWRKA) TRKS(154,10,155,11) OUTTRKS(552,8) // |
DFSMSdssのCOPY TRKSで、元の区分データセットのトラック内容を、②で作成した作業用データセットのエクステントにコピーします。トラック上の物理レコード(ブロック)がそのままの形でコピーされる必要がありますので、TRKSとOUTTRKSパラメーターを使い、読み出し元と書き出し先はデータセット名ではなく、トラック・アドレスで指定します。
読み出し元と書き出し先のエクステント位置は、IEHLISTのLISTVTOC FORMATを使えばわかります(JCLは「DASDボリューム内にあるデータセットの一覧(VTOCリスト)を出力する」にサンプルがあります)。元のデータセットがマルチ・エクステントの場合は、各エクステントのトラック数に応じて、OUTTRKSパラメーターに指定する書き出し先の開始トラック・アドレスをずらします。
④IEBCOPYで元の区分データセットの全メンバーを読み出す
1 2 3 4 5 6 7 8 9 |
//IEBCOPY EXEC PGM=IEBCOPY //SYSPRINT DD SYSOUT=* //SYSUT1 DD DISP=SHR,DSN=SALVAGE.PDS.WORK, // UNIT=SYSDA,VOL=SER=VPWRKA //SYSUT2 DD DISP=(,KEEP),DSN=SALVAGE.PDS.RESTORED, // UNIT=SYSDA,VOL=SER=VPWRKA,SPACE=(CYL,(10,5,30)), // DCB=(DSORG=PO,RECFM=FB,LRECL=80,BLKSIZE=0) //SYSIN DD DUMMY // |
IEBCOPYで新しい別の区分データセットにコピーすることで、③でコピーした作業用データセットのトラック・データから元の区分データセットのメンバー内容を読み取ります。SYSUT2側の新しい区分データセットは、スペース量(1次量、2次量、DIR数)やブロック長を変更できます。成功すれば、ABSTRアロケーションした仮のデータセット枠と作業用データセットは不要です。新しい区分データセットのメンバー・リストやメンバー内容を確認して、大丈夫なようなら削除してかまいません。
なお、トラック・データをコピーし終えた段階では、作業用データセットの内容を見るだけであればいいですが決してメンバーの更新や追加をしてはなりません。VTOC内のDSCB1レコードのDS1LSTARは正しく更新されていませんから、別のメンバー領域を上書きしてしまうことになります。PDSEでも内部ディレクトリーの情報は元のデータセットのままです。作業用データセットは読み込みの処理だけにしておきます。
上記の方法は、元のデータセットがあったトラック位置を上書きされないようにしておき(DSORG=DAでABSTRアロケーション)、同じ属性のデータセットを別の場所に割り当て、元のデータセットのエクステント位置のトラック内容をそのまま新しいデータセットのエクステント位置にコピーすれば、元のデータセットの内容は読み出せるはず、という仮定の下で試したものです。PSDEもここで解説した方法で復活できました。
元のデータセットのトラック内容がコピーできれば、順次や区分以外のVSAMやSMS管理データセットも復元できそうなものですが、実際には難しいでしょう。VSAMは、VTOCだけなくVVDSにも制御と管理の情報を持っているため、単にトラック上のデータをコピーするだけでは不十分です。
拡張形式の順次データセットや基本形式であってもSMS管理されるデータセットが格納されるSMS管理ボリュームは、スペースを割り振るボリュームを指定したりABSTRアロケーションすることができないので、元のデータセットのエクステント位置を仮のデータセットで保護することができません。特定のSMS管理ボリュームに対して新規データセットの割り振りを禁止するようにはできますが、VSAM同様にSMS管理データセットもVVDSに制御と管理の情報を持っているため、単にトラック上のデータをコピーするだけではVVDSとの不整合が起こり得ます。