A COBOL program successfully executes all its WRITE
statements and reaches the CLOSE statement. Then, unexpectedly, the program
issues an SB37 space abend.
Why would an out-of-space condition become visible during
CLOSE rather than during WRITE?
Let's investigate.
The Test Program
Consider this simple COBOL program:
IDENTIFICATION DIVISION.
PROGRAM-ID. TESTPGM.
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
SPECIAL-NAMES.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT OUTPUT-FILE ASSIGN TO OUTFILE.
DATA DIVISION.
FILE SECTION.
FD OUTPUT-FILE.
01 OUTPUT-REC PIC X(30).
WORKING-STORAGE SECTION.
01 WS-GRP.
05 FILLER PIC X(05) VALUE 'WS-I:'.
05 WS-I PIC S9(8) COMP.
01 WS-VAR PIC 9(8).
PROCEDURE DIVISION.
ACCEPT WS-VAR
DISPLAY WS-VAR
OPEN OUTPUT OUTPUT-FILE
PERFORM VARYING WS-I FROM 1 BY 1 UNTIL WS-I > WS-VAR
WRITE OUTPUT-REC
END-PERFORM
DISPLAY 'WS-I ' WS-I
CLOSE OUTPUT-FILE
GOBACK.
The program simply accepts a record count and writes that
many 30-byte records.
The corresponding JCL is:
//GO1 EXEC
PGM=TESTPGM
//SYSOUT DD SYSOUT=*
//OUTFILE DD DSN=USERID.TESTFIL,
// LRECL=30,RECFM=FB,VOL=(,,,1),
// DISP=(,CATLG,CATLG),
// SPACE=(TRK,(1,1),RLSE),BUFNO=5
//*
//SYSIN DD *
00034520
//*
So the program attempts to write: 34,520 records
The important file allocation characteristics are:
LRECL
= 30
BLKSIZE = 27,990
SPACE = TRK,(1,1) = 1 Primary + 15 secondary tracks = total 16 tracks
BUFNO = 5
First, Let's Look at the Blocks
With fixed-block records:
Records
per block = BLKSIZE / LRECL = 27,990 / 30 = 933 records
Therefore, one physical block can contain 933 logical
COBOL records.
For 34,520 records: 34,520
/ 933 = 36 remainder 932
So the output consists of:
Therefore the output dataset needs space for 37 blocks.
A track can accommodate two blocks, and each block
holds 933 records.
With 16 tracks available(based on SPACE parameter), the
total number of records that can be successfully written to output file is:
16 tracks × 2 blocks per track × 933 records per block =
29,856 records
So, the output data set can accommodate exactly 29,856
records before the space-related failure occurs.
If we translate 29,856 records to number of blocks,
29856/933 = 32 blocks.
But program is trying to write 37 blocks of records.
Now Look at What the
Program Reports
The SYSOUT contains:
00034520
PROGRAM-ID. TESTPGM.
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
SPECIAL-NAMES.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT OUTPUT-FILE ASSIGN TO OUTFILE.
DATA DIVISION.
FILE SECTION.
FD OUTPUT-FILE.
01 OUTPUT-REC PIC X(30).
WORKING-STORAGE SECTION.
01 WS-GRP.
05 FILLER PIC X(05) VALUE 'WS-I:'.
05 WS-I PIC S9(8) COMP.
01 WS-VAR PIC 9(8).
PROCEDURE DIVISION.
ACCEPT WS-VAR
DISPLAY WS-VAR
OPEN OUTPUT OUTPUT-FILE
PERFORM VARYING WS-I FROM 1 BY 1 UNTIL WS-I > WS-VAR
WRITE OUTPUT-REC
END-PERFORM
DISPLAY 'WS-I ' WS-I
CLOSE OUTPUT-FILE
GOBACK.
//SYSOUT DD SYSOUT=*
//OUTFILE DD DSN=USERID.TESTFIL,
// LRECL=30,RECFM=FB,VOL=(,,,1),
// DISP=(,CATLG,CATLG),
// SPACE=(TRK,(1,1),RLSE),BUFNO=5
//*
//SYSIN DD *
00034520
//*
BLKSIZE = 27,990
SPACE = TRK,(1,1) = 1 Primary + 15 secondary tracks = total 16 tracks
BUFNO = 5
- 36 complete blocks
- 1 partial block containing 932 records
WS-I 00034521
IGZ0034W The file with system-name OUTFILE could not be extended. Secondary extents were not specified or were not available. The last WRITE was at offset X'E23156CC' in program TESTPGM.
The interesting part is:
“WS-I 00034521”
This tells us that the PERFORM loop finished. In other words, COBOL executed all 34,520
WRITE statements.
Yet, after the job abended, the output data set contained
only 29,856 records.
This means that the remaining records were in BUFFER.
CLOSE Is More Than "Close the File"
Although all the WRITE statements have completed, some
records are still held in the output buffers.
During CLOSE, these buffered records are written to disk.
Since the data set cannot be extended to accommodate them,
the program encounters an SB37 abend while closing the file.
IGZ0034W The file with system-name OUTFILE could not be extended. Secondary extents were not specified or were not available. The last WRITE was at offset X'E23156CC' in program TESTPGM.
No comments:
Post a Comment
Note: Only a member of this blog may post a comment.