SPOOL

본 장에서는 SPOOL 데이터셋과 SPOOL 백업 방법에 대해 기술한다.

1. 개요

SPOOL은 JOB 수행에 필요한 입력 및 JOB 수행으로 생성된 결과물인 SPOOL 데이터셋을 담고 있는 볼륨을 지칭하거나 또는 SPOOL 데이터셋을 사용하는 오퍼레이션을 뜻한다.

JCL이 submit되면, TJES에서는 JOB에 유일한 JOBID를 부여하고 JOBQ에 등록한다. 이때 부여된 JOBID 이름으로 SPOOL 볼륨에 SPOOL 공간이 할당된다. 그리고 INPJCL이라는 SPOOL 데이터셋이 생성된 후 JCL을 INPJCL에 복사한다. 그리고 INPJCL과 매크로를 결합하여 EXPJCL을 생성한다. 이후의 JOB 수행에서는 EXPJCL이 입력으로 사용된다.

tjclrun은 JOBID로 생성된 SPOOL 공간에 JESMSG, JESJCL, SYSMSG라는 이름의 SPOOL 데이터셋과 JCL에 기술된 SYSOUT(SOUT) FD에 대한 SPOOL 데이터셋을 생성하고 JOB 수행에 사용한다.

생성된 SPOOL 데이터셋은 tjesmgr나 OpenFrame Manager를 통해서 내용을 확인할 수 있다.

2. SPOOL 데이터셋

SPOOL 데이터셋은 JOB이 수행될 때 기본적으로 생성되는 데이터셋(INPJCL, EXPJCL, JESMSG, JESJCL, SYSMSG)과 JCL에 SOUT으로 기술되어 생성되는 데이터셋이 있다.

다음은 데이터셋 SOUT.DATA.IN의 레코드를 정렬하여 SOUT.DATA.OUT을 생성하는 JCL의 예이다.

<SORT01 JCL>

¥ JOBG USERGRP
¥ JOB SORT01,LIST=(L,JD)
¥ EX SORT
¥ FD LIST=DA,SOUT=L
¥ FD SORTWK01=DA,TRK=21
¥ FD SORTWK02=DA,TRK=21
¥ FD SORTWK03=DA,TRK=21
¥ FD SORTIN=DA,FILE=SORT.DATA.IN
¥ FD SORTOUT=DA,FILE=SORT.DATA.OUT
¥ FD COIN=*
 SORT    FIELDS=(1,6,CH,A)
¥*
¥ JEND
¥ JGEND

JCL SORT01을 submit하여 실행하면 다음과 같은 SPOOL 데이터셋이 생성된다.

SPOOL LIST:
---------------------------------------------------------------------------
NO  STEP              DDNAME       SIZE  DSNAME
---------------------------------------------------------------------------
0   --------          INPJCL         271 INPJCL
1   --------          SYSMSG          4K SYSMSG
2   --------          EXPJCL         271 EXPJCL
3   --------          JESMSG          1K JESMSG
4   --------          JESJCL          9K JESJCL
5                     LIST            1K ROOT.SORT01.JOB00006.D000000

본 절에서는 SPOOL LIST의 SPOOL 데이터셋 내용에 대해서 설명한다.

INPJCL

submit된 JCL이 복사되어 있다.

<INPJCL>

¥ JOBG USERGRP
¥ JOB SORT01,LIST=(L,JD)
¥ EX SORT
¥ FD LIST=DA,SOUT=L
¥ FD SORTWK01=DA,TRK=21
¥ FD SORTWK02=DA,TRK=21
¥ FD SORTWK03=DA,TRK=21
¥ FD SORTIN=DA,FILE=SORT.DATA.IN
¥ FD SORTOUT=DA,FILE=(SORT.DATA.OUT,AD)
¥ FD COIN=*
 SORT    FIELDS=(1,6,CH,A)
¥*
¥ JEND
¥ JGEND
EXPJCL

submit된 JCL에서 Macro 처리를 하고난 JCL이 복사되어 있다. 이후의 JOB 실행에서는 EXPJCL의 내용을 사용한다.

<EXPJCL>

¥ JOBG USERGRP
¥ JOB SORT01,LIST=(L,JD)
¥ EX SORT
¥ FD LIST=DA,SOUT=L
¥ FD SORTWK01=DA,TRK=21
¥ FD SORTWK02=DA,TRK=21
¥ FD SORTWK03=DA,TRK=21
¥ FD SORTIN=DA,FILE=SORT.DATA.IN
¥ FD SORTOUT=DA,FILE=(SORT.DATA.OUT,AD)
¥ FD COIN=*
 SORT    FIELDS=(1,6,CH,A)
¥*
¥ JEND
¥ JGEND
JESMSG

JOB과 관련된 정보와 각각의 STEP에 대한 정보가 저장된다.

---< JOB INFO >------------------------------------------------------------
 JOB  ID    : JOB00032      NODE NAME  : NODE1
 JOBG NAME  : USERGRP       JOB  NAME  : SORT01
 JOB  CLASS : A , JOB STATUS : D(R00010) , JOB PRTY : 0 , RUNNER INDEX : 0
 JOB  USER  : ROOT
 JCL  PATH  : /home/obmxsp/oframe_new/volume_default/SYS1.JCLLIB/TEST
 TIME STAMP : SUBM 20120723110515, EXEC 20140723110516, TERM 20140723110518
 RES  USAGE : CPU - 0s (p:2s) , 0%
---<STEP INFO>-------------------------------------------------------------
 STEP : []
  CPU      0s(p: 5s).
  LIST     JOB00006(ROOT.SORT01.JOB00006.D000000)            R:0       W:38
  SORTWK01 SYS08175.T234027.RA000.SORT01.R010001             R:0       W:0
  SORTWK02 SYS08175.T234027.RA000.SORT01.R010002             R:0       W:0
  SORTWK03 SYS08175.T234027.RA000.SORT01.R010003             R:0       W:0
  SORTIN   SORT.DATA.IN                                      R:10      W:0
  SORTOUT  SORT.DATA.OUT                                     R:0       W:10
  COIN     JOB00006(ROOT.SORT01.JOB00006.D000006)            R:1       W:0
  • JOB 정보

    다음은 JESMSG에 저장되는 JOB 정보에 대한 설명이다.

    필드 설명

    JOB ID

    할당된 JOB의 고유번호이다.

    JOBG NAME

    JOB 그룹 이름이다.

    JOB NAME

    JOB 이름이다.

    NODENAME

    JOB이 실행된 TJES 노드 이름이다.

    JOB CLASS

    JOB 클래스이다.

    JOB STATUS

    JOB의 현재 상태(반환값)이다.

    JOB PRTY

    실행한 JOB의 JOB 스케줄링 우선순위이다.

    RUNNER INDEX

    JOB을 실행한 Runner Slot 번호이다.

    JOB USER

    JOB을 실행한 USER이다.

    JCL PATH

    USER가 submit한 JCL 파일의 위치 및 파일이름이다.

    TIME STAMP

    JOB이 submit된 시각, JOB 실행의 시작 및 종료 시각이다.

    RES USAGE

    JOB 실행에 사용된 CPU 시간을 나타낸다.

    • CPU

    • 0s : tjclrun 및 fork된 자식 프로세스의 CPU 사용량의 합 (현재는 프로세스가 종료되었으므로 0)

    • (p:2s) : tjclrun이 fork된 시점부터 종료될 때까지의 시간 (JOB 수행시간)

    • 0% : JOB 수행시간 대비 CPU 사용량.

  • STEP 정보

    다음은 JESMSG에 저장되는 STEP 정보에 대한 설명이다.

    필드 설명

    STEP

    해당 JOBSTEP의 이름이다.

    CPU

    해당 JOBSTEP 처리에 사용된 CPU 시간이다. (CPU 시간: 실제 처리 시간)

    LIST

    해당 JOBSTEP에서 발생한 LIST에 대한 I/O 카운트이다.

    SORTWK01

    해당 JOBSTEP에서 발생한 SORTWK01에 대한 I/O 카운트이다.

    SORTWK02

    해당 JOBSTEP에서 발생한 SORTWK02에 대한 I/O 카운트이다.

    SORTWK03

    해당 JOBSTEP에서 발생한 SORTWK03에 대한 I/O 카운트이다.

    SORTIN

    해당 JOBSTEP에서 발생한 SORTIN에 대한 I/O 카운트이다.

    SORTOUT

    해당 JOBSTEP에서 발생한 SORTOUT에 대한 I/O 카운트이다.

    COIN

    해당 JOBSTEP에서 발생한 COIN에 대한 I/O 카운트이다.

JESJCL

INPJCL에 대하여 JCL 문장의 parse tree가 저장된다.

<JESJCL>

 ========================================================================
 ¥ JOBG[name=]={
    |lineno=1
    |param[position=1]={
    |   |type=VAL_STR
    |   |value=[USERGRP]
    |}
    |---------- child statements ----------
    |¥ JOB[name=]={
    |   |lineno=2
    |   |param[position=1]={
    |   |   |type=VAL_STR
    |   |   |value=[SORT01]
    |   |}
    |   |param[keyword=LIST]={
    |   |   |type=VAL_SUBPARAMS
    |   |   |value={
    |   |   |   |param[position=1]={
    |   |   |   |   |type=VAL_STR
    |   |   |   |   |value=[L]
    |   |   |   |}
    |   |   |   |param[position=2]={
    |   |   |   |   |type=VAL_STR
    |   |   |   |   |value=[JD]
    |   |   |   |}
    |   |   |}
    |   |}
    |   |---------- child statements ----------
    |   |¥ EX[name=]={
    |   |   |lineno=3
    |   |   |param[position=1]={
    |   |   |   |type=VAL_STR
    |   |   |   |value=[SORT]
    |   |   |}
    |   |}
    |   |¥ FD[name=]={
    |   |   |lineno=4
    |   |   |param[keyword=LIST]={
    |   |   |   |type=VAL_STR
    |   |   |   |value=[DA]
    |   |   |}
    |   |   |param[keyword=SOUT]={
    |   |   |   |type=VAL_STR
    |   |   |   |value=[L]
    |   |   |}
..
SYSMSG

JOB이 실행되는 동안 tjclrun이 생성한 메시지를 저장한다.

<SYSMSG>

 JOBID=JOB00032   JOBPOS=0   RUNPID=30176
 SORT01 JOB
 ----------------------------------  EX step ----------------------------------
 (JRN2258I) COIN     FD SHUNT - FILENAME=JOB00032(ROOT.SORT01.JOB00032.D000006)
 (JRN2905I) Now allocate(JOB00032) step: fd:SYSPRINT
 (JRN2910I) LIST FD ALLOCATED - FILENAME=JOB00032(ROOT.SORT01.JOB00032.D000000)
 (JRN2905I) Now allocate(SYS12205.T110516.RA000.SORT01.R010001) step: fd:SORTWK01
 (JRN2909I) SORTWK01 FD ALLOCATED - FILENAME=SYS12205.T110516.RA000.SORT01.R010001
 (JRN2905I) Now allocate(SYS12205.T110516.RA000.SORT01.R010002) step: fd:SORTWK02
 (JRN2909I) SORTWK02 FD ALLOCATED - FILENAME=SYS12205.T110516.RA000.SORT01.R010002
 (JRN2905I) Now allocate(SYS12205.T110516.RA000.SORT01.R010003) step: fd:SORTWK03
 (JRN2909I) SORTWK03 FD ALLOCATED - FILENAME=SYS12205.T110516.RA000.SORT01.R010003
 (JRN2905I) Now allocate(SORT.DATA.IN) step: fd:SORTIN
 (JRN2909I) SORTIN   FD ALLOCATED - FILENAME=SORT.DATA.IN
 (JRN2905I) Now allocate(SORT.DATA.OUT) step: fd:SORTOUT
 (JRN2909I) SORTOUT  FD ALLOCATED - FILENAME=SORT.DATA.OUT
 (JRN2905I) Now allocate(JOB00032) step: fd:COIN
 (JRN2910I) COIN     FD ALLOCATED - FILENAME=JOB00032(ROOT.SORT01.JOB00032.D000006)
 (JRN2012I) SYSOUT open LIST  ok
 (JRN2011I) SYSIN open COIN ok
 (JRN2335I) SORTOUT FD in  exported
 (JRN2335I) SORTIN FD in  exported
 (JRN2335I) SORTWK03 FD in  exported
 (JRN2335I) SORTWK02 FD in  exported
 (JRN2335I) SORTWK01 FD in  exported
 (JRN0056I) coprocess child: argv[0]=SORT
 (JRN0058I) pgm pid=30184
 (JRN0060I) Entering exec_pipe_loop() ...
 (JRN2010I) SYSIN write ok
 (JRN2011I) child program is SORT ok
 (JRN0245I) PGM closed stdout pipe
 (JRN0061I) Leaving exec_pipe_loop() ...
 (JRN0063I) pipe work done with coprocess child (PGM)
 (JRN0080I) PGM pid[30184] EXITED
 (JRN0065I)  EXEC PGM step done with RC=10
 (JRN2012I) LIST FD disposed - NORMAL ok
 (JRN2012I) SORTWK01 FD disposed - NORMAL ok
 (JRN2012I) SORTWK02 FD disposed - NORMAL ok
 (JRN2012I) SORTWK03 FD disposed - NORMAL ok
 (JRN2012I) SORTIN FD disposed - NORMAL ok
 (JRN2012I) SORTOUT FD disposed - NORMAL ok
 (JRN2012I) COIN FD disposed - NORMAL ok
 ------------------------------ DATA SET DISPOSE ------------------------------
 --------------------------- DATA SET UNALLOCATION ----------------------------
 (JRN2012I) COIN FD unallocated - NORMAL ok
 (JRN2012I) SORTOUT FD unallocated - NORMAL ok
 (JRN2012I) SORTIN FD unallocated - NORMAL ok
 (JRN2012I) SORTWK03 FD unallocated - NORMAL ok
 (JRN2012I) SORTWK02 FD unallocated - NORMAL ok
 (JRN2012I) SORTWK01 FD unallocated - NORMAL ok
 (JRN2012I) LIST FD unallocated - NORMAL ok
 (JRN0333I) JOB is enqueued for output processing - JOBID=JOB00032, ABEND=0
JCL에서 SYSOUT으로 정의된 SPOOL 데이터셋

이들은 주로 JCL에 기술된 유틸리티나 애플리케이션에서 OUTPUT으로 사용된다. 현재 이 예제에서는 SORT 유틸리티가 수행 중에 발생된 메시지를 저장하는 LIST문에 대하여 SPOOL 데이터셋이 생성되었다.

< SYSPRINT ROOT.SORT01.JOB00032.D000000>

 dfsort version 7.3.0(0) tmaxsoft@openframe:ofsrc73/batch(#1) 2012-04-17 09:57:32
 110517 M SRT0001M parsing starts.
 110517 M SRT0002M parsing finishes.

 <<PROSORT SCRIPT>>

 DEFREC FIXED,SIZE=80
 DATASIZE 1M
 MEMORY 512M
 WORKSPACE = (
              /home/tmaxsoft/openframe/temp)
 SORT FIELDS=(1,6,CH,A)


 110517 U MSGXXXXU 0 records are released
 110517 U MSGXXXXU 0 records are returned
 110517 M SRT3002M sorting  finishes.
 110517 M SRT9002M 0 records are written.

3. SPOOL BACKUP

JOBQ에서 필요없게 된 JOB을 삭제하게 되면, 해당 SPOOL도 삭제하게 된다. 만약 SPOOL을 보존해야 할 필요가 있으면 SPOOL BACKUP 기능을 사용하여 SPOOL을 백업할 수 있다.

SPOOL BACKUP 명령이 내려지면 OpenFrame 환경설정에 tjes 서브젝트, SPOOL 섹션의 SPOOL_BACKUP_DIR 키의 VALUE 항목에 설정된 백업 디렉터리에 현재 날짜로 디렉터리가 생성된다.

그리고 이 디렉터리에 백업된 JOB에 대해서 해당 SPOOL을 압축하여 JOBID_JOBNAME_submitDATE_submitTIME.tar.gz 형식의 파일을 생성한 후 백업된 JOB을 JOBQ와 SPOOL에서 삭제한다. 백업된 SPOOL에 대해서 조회하게 되면, OpenFrame 환경설정에 tjes 서브젝트, SPOOL 섹션의 SPOOL_UNPACK_DIR 키의 VALUE 항목에 설정된 디렉터리에 압축된 JOBID_JOBNAME_submitDATE_submitTIME.tar.gz 형식의 파일을 풀어 놓고, 이후 해당 JOB에 대한 SPOOL을 조회할 수 있다.

SPOOL BACKUP이 가능한 JOB 상태는 DONE, ERROR, STOP, FLUSH이다.

  1. SPOOL BACKUP된 내용은 추후에 항상 tjesmgr 명령어나 OpenFrame Manager[Batch] 메뉴에서 조회가 가능하다.

  2. SPOOL BACKUP 관련 명령은 TJESMGR 명령어를 참조한다.

  3. OpenFrame 환경설정에 tjes 서브젝트, SPOOL 섹션의 설정방법에 대한 자세한 내용은 OpenFrame Batch "환경설정 안내서"를 참고한다.