COBOL/エンタープライズ製品 技術情報(FAQ)


MFSORT 多重実行時の考慮事項

MFSORT は、データファイルのソートやマージを行う際に用いるコマンドラインユーティリティです。
MFSORT 自体は 1 プロセスのみの排他実行が強制されるようなものではなく、複数のジョブ (プロセス) から同時に実行することが可能です。但しこの時の注意事項として、以下のような点が挙げられます。


出力ファイルの競合

同一の出力ファイルが指定された MFSORT を複数同時に実行すると、最初に出力ファイルの作成に成功したジョブのみがソート処理に成功し、他のジョブでは出力ファイルの作成に失敗してソート処理が異常終了します。
ジョブごとに一意の出力ファイルが指定されていれば、複数同時に実行されても問題ありません。


一時ファイルの競合

MFSORT はそのソート処理中に、一時ディレクトリに一時ファイルを作成して読み書きを行い、ソート処理完了後にこれを削除します。

使用される一時ディレクトリ:
Windows 環境の場合 ... TMP 環境変数に設定されたディレクトリ
Linux / UNIX 環境の場合 ... TMPDIR 環境変数に設定されたディレクトリ
上記環境変数が設定されていない場合 ... MFSORT 実行時のカレントディレクトリ

作成される一時ファイル:
("nnn" の箇所は連番です。)
M$FSTnnn.001
M$FSTnnn.002
M$FSTnnn.TMP

一時ファイル作成時には上記のように一意の連番を伴う名前付けが為されますが、タイミング要素によって稀に複数ジョブ間で競合が発生する場合があります。

この場合、一時ディレクトリとして一意の作業ディレクトリを各ジョブごとに個別に使用することにより、一時ファイルの競合が発生しないようにします。
以下は RANDOM 変数で取得した乱数を使って一意の作業ディレクトリを TMP / TMPDIR 環境変数に指定し、同ディレクトリを作成した上でソート処理を行なっているコマンド例です。
(作成した作業ディレクトリは MFSORT 実行後に削除しています。)

Windows 環境の場合:

SET TMP=C:\Temp\MFSORT\%RANDOM%
MKDIR %TMP%
MFSORT ....
RMDIR /S /Q %TMP%

Linux/UNIX 環境の場合:

TMPDIR=/var/mfsort/$RANDOM; export TMPDIR
mkdir $TMPDIR
mfsort ....
rm -Rf $TMPDIR

これによって一時ファイルが一意の作業ディレクトリに生成されるようになるため、問題に遭遇する可能性を排除することができます。


SYSOUT の競合

MFSORT を実行すると、実行結果レポートとして SYSOUT ファイルがカレントディレクトリに出力されます。このため、同じカレントディレクトリ上で MFSORT を複数同時に実行すると、最初に SYSOUT ファイルの作成に成功したジョブが SYSOUT を占有ロックし、これによって他のジョブでは SYSOUT への書き込みが行なえない旨の
「SORT004I: SYSOUT に書き込めません。コンソール出力に切り替えます。」
というメッセージとソート処理の結果レポートが標準出力に書き出されます。
これはあくまで結果レポートの出力先に関する影響であり、ソート処理そのものには影響しませんが、この事象が発生した場合の MFSORT 自体の戻り値としては正常終了時の 0 とは異なり 8 が返されます。戻り値によってソート処理の成否を判定されている場合、この点にもご注意ください。

この SYSOUT 競合事象に対し、結果レポートの保全要否によって以下の回避策が考えられます。

(1) 結果レポートの保全が不要な場合
SYSOUT 環境変数にファイルを指定すると、カレントディレクトリの SYSOUT ファイルの代わりにその指定ファイルが結果レポートとして生成されます。
これを応用し、SYSOUT に null デバイスを指定することにより、結果レポートはファイルにも標準出力にも書き出されずに破棄され、また MFSORT 自体もソート処理に問題が生じていない限りは戻り値 0 で終了します。

Windows 環境で SYSOUT に null デバイスを指定する場合:

SET SYSOUT=nul

Linux / UNIX 環境で SYSOUT に null デバイスを指定する場合:

SYSOUT=/dev/null; export SYSOUT


(2) 結果レポートの保全が必要な場合
各ジョブごとに一意の作業ディレクトリを作成し、これをカレントディレクトリとした上で MFSORT を実行します。これにより同一のカレントディレクトリ上で多重実行されることがなくなり、SYSOUT の競合を回避できます。
前述の一時ファイルの競合で例示したコマンドにこの回避策を組み合わせると、以下のような例が考えられます。

Windows 環境の場合:

SET PREVDIR=%CD%                  ← 開始時点のカレントディレクトリを記憶
SET TMP=C:\Temp\MFSORT\%RANDOM%
MKDIR %TMP%
CD /D %TMP%                       ← 作業ディレクトリに移動
MFSORT ....
COPY SYSOUT ...                   ← 必要に応じて SYSOUT を別ディレクトリへコピー
CD /D %PREVDIR%                   ← 元のディレクトリに戻ってから・・・
RMDIR /S /Q %TMP%                 ← 作業ディレクトリを削除

Linux / UNIX 環境の場合:

PREVDIR=$pwd; export PREVDIR      ← 開始時点のカレントディレクトリを記憶
TMPDIR=/var/mfsort/$RANDOM; export TMPDIR
mkdir $TMPDIR
cd $TMPDIR                        ← 作業ディレクトリに移動
mfsort ....
cp SYSOUT ...                     ← 必要に応じて SYSOUT を別ディレクトリへコピー
cd $PREVDIR                       ← 元のディレクトリに戻ってから・・・
rm -Rf $TMPDIR                    ← 作業ディレクトリを削除