Case Study 1: Setting Up a VSAM Environment for a New Banking Application
Background
Continental Federal Bank (CFB) is launching a new core banking module called "Integrated Account Platform" (IAP) to replace a 35-year-old flat-file-based account management system. The legacy system stores all data in sequential files -- customer master records, transaction history, and branch reference data -- processed exclusively through nightly batch runs. As transaction volumes have grown from 200,000 per day to over 3 million, the sequential file approach has become a severe bottleneck. Batch windows that once completed in two hours now consume nearly seven, threatening to overlap with the start of the next business day.
The architecture team has selected VSAM (Virtual Storage Access Method) as the data storage layer for IAP. VSAM offers indexed access for rapid record retrieval, sequential access for batch processing, and the reliability characteristics required for a mission-critical banking system. Three VSAM cluster types will be deployed:
- KSDS (Key-Sequenced Data Set) for the Account Master file, providing keyed access by account number for online inquiries and batch updates.
- ESDS (Entry-Sequenced Data Set) for the Transaction Audit Log, preserving the exact chronological order in which transactions are recorded.
- RRDS (Relative Record Data Set) for the Branch Lookup table, enabling direct access by branch number as a relative record number.
This case study walks through the complete IDCAMS setup process, from cluster definition through initial data load and verification. Every JCL job and IDCAMS control statement shown here represents a production-ready implementation.
The Infrastructure Requirements
Before writing a single line of JCL, the database administration team documented the following requirements based on projected data volumes and access patterns:
Account Master (KSDS)
- Record count: 4.2 million active accounts at launch, growing 8% annually
- Key: 10-digit account number (positions 1-10)
- Record size: Fixed at 500 bytes (customer demographics, balances, status flags, rate information)
- Access pattern: 70% random reads (online inquiries), 20% sequential (batch reports), 10% random updates (postings)
- CI size: 4096 bytes selected to balance random access performance against space utilization
- CA size: Calculated for optimal CI/CA split ratio
Transaction Audit Log (ESDS)
- Record count: 3 million new records per day, retained for 90 days (approximately 270 million active records)
- Record size: Variable, minimum 120 bytes (simple balance inquiry), maximum 800 bytes (complex wire transfer with memo fields)
- Access pattern: Write-once (append), sequential read for end-of-day reconciliation and audit queries
- CI size: 8192 bytes to optimize sequential throughput
Branch Lookup (RRDS)
- Record count: 850 branches, maximum 9999 (reserved for future expansion)
- Record size: Fixed at 200 bytes (branch name, address, manager, routing number, status)
- Access pattern: 95% random reads by branch number, 5% sequential scans for reports
- CI size: 4096 bytes
Step 1: Defining the VSAM Clusters
The first JCL job defines all three VSAM clusters using IDCAMS DEFINE CLUSTER. Each definition specifies the cluster, data, and index components with carefully calculated space allocations.
//IAPDEFCL JOB (ACCT),'IAP VSAM DEFINE',
// CLASS=A,MSGCLASS=X,MSGLEVEL=(1,1),
// NOTIFY=&SYSUID
//*
//*================================================================*
//* JOB: IAPDEFCL - DEFINE VSAM CLUSTERS FOR IAP APPLICATION
//* DATE: 2024-01-15
//* PURPOSE: CREATE KSDS, ESDS, AND RRDS CLUSTERS
//*================================================================*
//*
//*------------------------------------------------------------*
//* STEP 1: DELETE EXISTING CLUSTERS (IF RERUN)
//*------------------------------------------------------------*
//DELCLUST EXEC PGM=IDCAMS
//SYSPRINT DD SYSOUT=*
//SYSIN DD *
DELETE CFB.IAP.ACCTMAST.CLUSTER -
CLUSTER -
PURGE
IF LASTCC <= 8 THEN -
SET MAXCC = 0
DELETE CFB.IAP.TRANLOG.CLUSTER -
CLUSTER -
PURGE
IF LASTCC <= 8 THEN -
SET MAXCC = 0
DELETE CFB.IAP.BRANCHLK.CLUSTER -
CLUSTER -
PURGE
IF LASTCC <= 8 THEN -
SET MAXCC = 0
/*
//*
//*------------------------------------------------------------*
//* STEP 2: DEFINE KSDS FOR ACCOUNT MASTER
//*------------------------------------------------------------*
//DEFKSDS EXEC PGM=IDCAMS
//SYSPRINT DD SYSOUT=*
//SYSIN DD *
DEFINE CLUSTER ( -
NAME(CFB.IAP.ACCTMAST.CLUSTER) -
INDEXED -
RECORDS(4200000 500000) -
RECORDSIZE(500 500) -
KEYS(10 0) -
FREESPACE(20 10) -
SHAREOPTIONS(2 3) -
SPEED -
ERASE -
SPANNED ) -
DATA ( -
NAME(CFB.IAP.ACCTMAST.DATA) -
CONTROLINTERVALSIZE(4096) -
VOLUMES(VSAM01 VSAM02) ) -
INDEX ( -
NAME(CFB.IAP.ACCTMAST.INDEX) -
CONTROLINTERVALSIZE(2048) -
VOLUMES(VSAM01) )
IF LASTCC > 0 THEN -
SET MAXCC = 16
/*
//*
//*------------------------------------------------------------*
//* STEP 3: DEFINE ESDS FOR TRANSACTION AUDIT LOG
//*------------------------------------------------------------*
//DEFESDS EXEC PGM=IDCAMS
//SYSPRINT DD SYSOUT=*
//SYSIN DD *
DEFINE CLUSTER ( -
NAME(CFB.IAP.TRANLOG.CLUSTER) -
NONINDEXED -
RECORDS(270000000 30000000) -
RECORDSIZE(120 800) -
SHAREOPTIONS(2 3) -
SPEED -
ERASE ) -
DATA ( -
NAME(CFB.IAP.TRANLOG.DATA) -
CONTROLINTERVALSIZE(8192) -
VOLUMES(VSAM03 VSAM04 VSAM05) )
IF LASTCC > 0 THEN -
SET MAXCC = 16
/*
//*
//*------------------------------------------------------------*
//* STEP 4: DEFINE RRDS FOR BRANCH LOOKUP
//*------------------------------------------------------------*
//DEFRRDS EXEC PGM=IDCAMS
//SYSPRINT DD SYSOUT=*
//SYSIN DD *
DEFINE CLUSTER ( -
NAME(CFB.IAP.BRANCHLK.CLUSTER) -
NUMBERED -
RECORDS(9999 1000) -
RECORDSIZE(200 200) -
SHAREOPTIONS(2 3) -
SPEED ) -
DATA ( -
NAME(CFB.IAP.BRANCHLK.DATA) -
CONTROLINTERVALSIZE(4096) -
VOLUMES(VSAM01) )
IF LASTCC > 0 THEN -
SET MAXCC = 16
/*
Design Decisions Explained
FREESPACE(20 10) on the KSDS allocates 20% free space within each control interval and 10% free control intervals within each control area. This accommodates new account insertions without immediate CI and CA splits. Since account numbers are assigned sequentially by branch region, inserts tend to cluster geographically. The 20/10 split provides breathing room for these clustered inserts.
SHAREOPTIONS(2 3) permits multiple readers with one writer at the cross-region level and cross-system level. This supports the planned architecture where CICS regions handle online reads while a single batch region performs nightly updates.
SPEED vs RECOVERY: The SPEED option bypasses preformatting of the data component during initial load, significantly reducing cluster definition time. Since the initial load will write every record sequentially, preformatting is unnecessary. For subsequent operations, VSAM will format CIs as needed.
ERASE on the account master and transaction log ensures that deleted records are physically overwritten with binary zeros, meeting the bank's data security standards for sensitive financial information.
Step 2: Loading Initial Data from Flat Files
The legacy system exports its data as fixed-length sequential flat files. The REPRO command loads this data into the newly defined VSAM clusters.
//IAPLOAD JOB (ACCT),'IAP VSAM LOAD',
// CLASS=A,MSGCLASS=X,MSGLEVEL=(1,1),
// NOTIFY=&SYSUID
//*
//*================================================================*
//* JOB: IAPLOAD - LOAD INITIAL DATA INTO VSAM CLUSTERS
//* SOURCE: LEGACY FLAT FILE EXTRACTS
//*================================================================*
//*
//*------------------------------------------------------------*
//* STEP 1: LOAD ACCOUNT MASTER (KSDS)
//* INPUT FILE MUST BE SORTED BY ACCOUNT NUMBER
//*------------------------------------------------------------*
//LOADACCT EXEC PGM=IDCAMS
//SYSPRINT DD SYSOUT=*
//INFILE DD DSN=CFB.LEGACY.ACCTMAST.EXTRACT,
// DISP=SHR
//OUTFILE DD DSN=CFB.IAP.ACCTMAST.CLUSTER,
// DISP=SHR
//SYSIN DD *
REPRO INFILE(INFILE) -
OUTFILE(OUTFILE) -
REPLACE
IF LASTCC > 0 THEN DO
SET MAXCC = 16
PRINT INFILE(INFILE) -
COUNT(5) -
CHARACTER
END
/*
//*
//*------------------------------------------------------------*
//* STEP 2: LOAD TRANSACTION LOG (ESDS)
//* RECORDS LOADED IN CHRONOLOGICAL ORDER AS-IS
//*------------------------------------------------------------*
//LOADTRAN EXEC PGM=IDCAMS
//SYSPRINT DD SYSOUT=*
//INFILE DD DSN=CFB.LEGACY.TRANLOG.EXTRACT,
// DISP=SHR
//OUTFILE DD DSN=CFB.IAP.TRANLOG.CLUSTER,
// DISP=SHR
//SYSIN DD *
REPRO INFILE(INFILE) -
OUTFILE(OUTFILE)
IF LASTCC > 0 THEN -
SET MAXCC = 16
/*
//*
//*------------------------------------------------------------*
//* STEP 3: LOAD BRANCH LOOKUP (RRDS)
//* INPUT RECORDS CONTAIN BRANCH NUMBER IN POSITIONS 1-4
//* BRANCH NUMBER BECOMES THE RELATIVE RECORD NUMBER
//*------------------------------------------------------------*
//LOADBRCH EXEC PGM=IDCAMS
//SYSPRINT DD SYSOUT=*
//INFILE DD DSN=CFB.LEGACY.BRANCH.EXTRACT,
// DISP=SHR
//OUTFILE DD DSN=CFB.IAP.BRANCHLK.CLUSTER,
// DISP=SHR
//SYSIN DD *
REPRO INFILE(INFILE) -
OUTFILE(OUTFILE)
IF LASTCC > 0 THEN -
SET MAXCC = 16
/*
Critical Consideration: Input File Sort Order
The KSDS load requires the input flat file to be sorted in ascending account number order. If the file is not sorted, REPRO will fail with a sequence error. The legacy extract program produces records in account-number order, but the team added a verification step to their runbook: a pre-load SORT job confirms the input file is in the correct sequence before REPRO executes.
For the ESDS, sort order is irrelevant because records are simply appended in the order they arrive. The chronological ordering of the legacy extract is preserved naturally.
For the RRDS, the REPRO operation assigns each record to consecutive slots. The COBOL load program (described below) handles the mapping of branch numbers to relative record numbers when direct control over slot assignment is required.
Step 3: Verifying the Cluster Definitions
After loading, the team runs LISTCAT to confirm that all clusters were defined and loaded correctly.
//IAPVFYCL JOB (ACCT),'IAP VSAM VERIFY',
// CLASS=A,MSGCLASS=X,MSGLEVEL=(1,1),
// NOTIFY=&SYSUID
//*
//*================================================================*
//* JOB: IAPVFYCL - VERIFY VSAM CLUSTER DEFINITIONS AND STATS
//*================================================================*
//*
//LISTALL EXEC PGM=IDCAMS
//SYSPRINT DD SYSOUT=*
//SYSIN DD *
LISTCAT ENTRIES( -
CFB.IAP.ACCTMAST.CLUSTER -
CFB.IAP.TRANLOG.CLUSTER -
CFB.IAP.BRANCHLK.CLUSTER ) -
ALL
/*
//*
//*------------------------------------------------------------*
//* VERIFY RECORD COUNTS MATCH EXPECTED VALUES
//*------------------------------------------------------------*
//VERCOUNT EXEC PGM=IDCAMS
//SYSPRINT DD SYSOUT=*
//ACCTFILE DD DSN=CFB.IAP.ACCTMAST.CLUSTER,
// DISP=SHR
//TRANFILE DD DSN=CFB.IAP.TRANLOG.CLUSTER,
// DISP=SHR
//BRCHFILE DD DSN=CFB.IAP.BRANCHLK.CLUSTER,
// DISP=SHR
//SYSIN DD *
PRINT INFILE(ACCTFILE) -
COUNT(3) -
CHARACTER
PRINT INFILE(TRANFILE) -
COUNT(3) -
CHARACTER
PRINT INFILE(BRCHFILE) -
COUNT(3) -
CHARACTER
VERIFY FILE(ACCTFILE)
VERIFY FILE(TRANFILE)
VERIFY FILE(BRCHFILE)
/*
Understanding LISTCAT Output
The LISTCAT ALL command produces detailed statistics for each cluster. The team reviews several critical fields:
- REC-TOTAL: Total number of records loaded. Must match the expected count from the legacy extract.
- SPLITS-CI: Number of control interval splits that occurred during load. For the initial sequential load with SPEED, this should be zero.
- SPLITS-CA: Number of control area splits. Also zero for initial load.
- FREESPACE-%CI and %CA: Confirms the free space allocations match the DEFINE specification.
- HURBA (High Used RBA): The relative byte address of the highest record written, used to calculate actual space consumption.
- HARBA (High Allocated RBA): The total allocated space, which should exceed HURBA by the free space margin.
The VERIFY command ensures the catalog information is synchronized with the actual VSAM data. If a job abends while a VSAM file is open, the catalog may contain stale end-of-file information. VERIFY corrects this by reading the actual data component and updating the catalog.
Step 4: COBOL Program for RRDS Branch Load
The RRDS requires special handling because branch numbers are not consecutive. Branch 0001 exists, but branch 0002 may not. To load records into specific relative record slots corresponding to branch numbers, a COBOL program is used instead of REPRO.
IDENTIFICATION DIVISION.
PROGRAM-ID. IAPBRLD.
*================================================================*
* PROGRAM: IAPBRLD - LOAD BRANCH LOOKUP RRDS
* PURPOSE: READS FLAT FILE OF BRANCH RECORDS AND WRITES EACH
* TO THE RRDS SLOT MATCHING ITS BRANCH NUMBER.
* DATE: 2024-01-15
*================================================================*
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT BRANCH-INPUT
ASSIGN TO BRANCHIN
ORGANIZATION IS SEQUENTIAL
FILE STATUS IS WS-INPUT-STATUS.
SELECT BRANCH-RRDS
ASSIGN TO BRANCHVS
ORGANIZATION IS RELATIVE
ACCESS MODE IS RANDOM
RELATIVE KEY IS WS-BRANCH-SLOT
FILE STATUS IS WS-RRDS-STATUS.
DATA DIVISION.
FILE SECTION.
FD BRANCH-INPUT
RECORDING MODE IS F
RECORD CONTAINS 200 CHARACTERS.
01 BRANCH-INPUT-REC.
05 BI-BRANCH-NUMBER PIC 9(4).
05 BI-BRANCH-NAME PIC X(40).
05 BI-BRANCH-ADDRESS PIC X(60).
05 BI-BRANCH-CITY PIC X(25).
05 BI-BRANCH-STATE PIC X(2).
05 BI-BRANCH-ZIP PIC X(10).
05 BI-ROUTING-NUMBER PIC 9(9).
05 BI-MANAGER-ID PIC X(8).
05 BI-STATUS PIC X(1).
05 BI-OPEN-DATE PIC 9(8).
05 FILLER PIC X(33).
FD BRANCH-RRDS
RECORD CONTAINS 200 CHARACTERS.
01 BRANCH-RRDS-REC PIC X(200).
WORKING-STORAGE SECTION.
01 WS-INPUT-STATUS PIC X(2).
01 WS-RRDS-STATUS PIC X(2).
01 WS-BRANCH-SLOT PIC 9(4).
01 WS-COUNTERS.
05 WS-READ-COUNT PIC 9(7) VALUE ZERO.
05 WS-WRITE-COUNT PIC 9(7) VALUE ZERO.
05 WS-ERROR-COUNT PIC 9(7) VALUE ZERO.
05 WS-DUPLICATE-COUNT PIC 9(7) VALUE ZERO.
01 WS-EOF-FLAG PIC X(1) VALUE 'N'.
88 END-OF-FILE VALUE 'Y'.
88 NOT-END-OF-FILE VALUE 'N'.
PROCEDURE DIVISION.
0000-MAIN.
PERFORM 1000-INITIALIZE
PERFORM 2000-PROCESS-BRANCHES
UNTIL END-OF-FILE
PERFORM 3000-TERMINATE
STOP RUN.
1000-INITIALIZE.
OPEN INPUT BRANCH-INPUT
IF WS-INPUT-STATUS NOT = '00'
DISPLAY 'ERROR OPENING INPUT FILE: '
WS-INPUT-STATUS
MOVE 16 TO RETURN-CODE
STOP RUN
END-IF
OPEN OUTPUT BRANCH-RRDS
IF WS-RRDS-STATUS NOT = '00'
DISPLAY 'ERROR OPENING RRDS FILE: '
WS-RRDS-STATUS
MOVE 16 TO RETURN-CODE
STOP RUN
END-IF
PERFORM 8000-READ-INPUT.
2000-PROCESS-BRANCHES.
MOVE BI-BRANCH-NUMBER TO WS-BRANCH-SLOT
IF WS-BRANCH-SLOT = ZERO
DISPLAY 'SKIPPING RECORD WITH ZERO BRANCH: '
BRANCH-INPUT-REC
ADD 1 TO WS-ERROR-COUNT
ELSE
MOVE BRANCH-INPUT-REC TO BRANCH-RRDS-REC
WRITE BRANCH-RRDS-REC
EVALUATE WS-RRDS-STATUS
WHEN '00'
ADD 1 TO WS-WRITE-COUNT
WHEN '22'
DISPLAY 'DUPLICATE BRANCH NUMBER: '
WS-BRANCH-SLOT
ADD 1 TO WS-DUPLICATE-COUNT
WHEN OTHER
DISPLAY 'WRITE ERROR ON BRANCH '
WS-BRANCH-SLOT
' STATUS: ' WS-RRDS-STATUS
ADD 1 TO WS-ERROR-COUNT
END-EVALUATE
END-IF
PERFORM 8000-READ-INPUT.
3000-TERMINATE.
CLOSE BRANCH-INPUT
CLOSE BRANCH-RRDS
DISPLAY '========================================='
DISPLAY 'BRANCH RRDS LOAD COMPLETE'
DISPLAY 'RECORDS READ: ' WS-READ-COUNT
DISPLAY 'RECORDS WRITTEN: ' WS-WRITE-COUNT
DISPLAY 'DUPLICATES SKIPPED: ' WS-DUPLICATE-COUNT
DISPLAY 'ERRORS: ' WS-ERROR-COUNT
DISPLAY '========================================='
IF WS-ERROR-COUNT > ZERO
MOVE 8 TO RETURN-CODE
ELSE
MOVE 0 TO RETURN-CODE
END-IF.
8000-READ-INPUT.
READ BRANCH-INPUT
AT END
SET END-OF-FILE TO TRUE
NOT AT END
ADD 1 TO WS-READ-COUNT
END-READ.
The JCL to compile and execute this program:
//IAPBRLD JOB (ACCT),'IAP BRANCH LOAD',
// CLASS=A,MSGCLASS=X,MSGLEVEL=(1,1),
// NOTIFY=&SYSUID
//*
//*================================================================*
//* COMPILE AND EXECUTE BRANCH RRDS LOAD PROGRAM
//*================================================================*
//*
//COMPILE EXEC PGM=IGYCRCTL,
// PARM='RENT,APOST,DATA(31)'
//STEPLIB DD DSN=IGY.V6R4M0.SIGYCOMP,DISP=SHR
//SYSLIB DD DSN=CFB.IAP.COPYLIB,DISP=SHR
//SYSPRINT DD SYSOUT=*
//SYSLIN DD DSN=&&OBJMOD,DISP=(MOD,PASS),
// UNIT=SYSDA,SPACE=(TRK,(5,5))
//SYSUT1 DD UNIT=SYSDA,SPACE=(CYL,(1,1))
//SYSUT2 DD UNIT=SYSDA,SPACE=(CYL,(1,1))
//SYSUT3 DD UNIT=SYSDA,SPACE=(CYL,(1,1))
//SYSUT4 DD UNIT=SYSDA,SPACE=(CYL,(1,1))
//SYSUT5 DD UNIT=SYSDA,SPACE=(CYL,(1,1))
//SYSUT6 DD UNIT=SYSDA,SPACE=(CYL,(1,1))
//SYSUT7 DD UNIT=SYSDA,SPACE=(CYL,(1,1))
//SYSIN DD DSN=CFB.IAP.SRCLIB(IAPBRLD),DISP=SHR
//*
//LKED EXEC PGM=IEWL,PARM='LIST,MAP,RENT',
// COND=(4,LT,COMPILE)
//SYSLIB DD DSN=CEE.SCEELKED,DISP=SHR
//SYSPRINT DD SYSOUT=*
//SYSLMOD DD DSN=CFB.IAP.LOADLIB(IAPBRLD),DISP=SHR
//SYSLIN DD DSN=&&OBJMOD,DISP=(OLD,DELETE)
//*
//RUN EXEC PGM=IAPBRLD,
// COND=(4,LT)
//STEPLIB DD DSN=CFB.IAP.LOADLIB,DISP=SHR
//BRANCHIN DD DSN=CFB.LEGACY.BRANCH.EXTRACT,DISP=SHR
//BRANCHVS DD DSN=CFB.IAP.BRANCHLK.CLUSTER,DISP=SHR
//SYSOUT DD SYSOUT=*
Step 5: Building an Alternate Index for the Account Master
Online inquiries frequently need to look up accounts by customer Social Security Number rather than by account number. An alternate index (AIX) provides this capability without duplicating the data.
//IAPAIX JOB (ACCT),'IAP AIX DEFINE',
// CLASS=A,MSGCLASS=X,MSGLEVEL=(1,1),
// NOTIFY=&SYSUID
//*
//*================================================================*
//* DEFINE ALTERNATE INDEX ON SSN FOR ACCOUNT MASTER
//*================================================================*
//*
//DEFAIX EXEC PGM=IDCAMS
//SYSPRINT DD SYSOUT=*
//SYSIN DD *
DEFINE ALTERNATEINDEX ( -
NAME(CFB.IAP.ACCTMAST.AIX.SSN) -
RELATE(CFB.IAP.ACCTMAST.CLUSTER) -
KEYS(9 50) -
RECORDSIZE(64 1024) -
UNIQUEKEY -
SHAREOPTIONS(2 3) -
UPGRADE ) -
DATA ( -
NAME(CFB.IAP.ACCTMAST.AIX.SSN.DATA) -
VOLUMES(VSAM01) ) -
INDEX ( -
NAME(CFB.IAP.ACCTMAST.AIX.SSN.INDEX) -
VOLUMES(VSAM01) )
DEFINE PATH ( -
NAME(CFB.IAP.ACCTMAST.PATH.SSN) -
PATHENTRY(CFB.IAP.ACCTMAST.AIX.SSN) -
UPDATE )
BLDINDEX INDATASET(CFB.IAP.ACCTMAST.CLUSTER) -
OUTDATASET(CFB.IAP.ACCTMAST.AIX.SSN) -
EXTERNALSORT
/*
The UPGRADE parameter ensures the alternate index is automatically updated whenever the base cluster is modified. The PATH definition creates a logical entry point that COBOL programs can reference to access the base cluster through the alternate key.
Lessons Learned
1. VSAM Cluster Type Selection Is a Data Architecture Decision
Choosing between KSDS, ESDS, and RRDS is not merely a technical preference -- it reflects the fundamental nature of the data and its access patterns. The account master requires keyed access because inquiries arrive with an account number. The transaction log must preserve insertion order because audit regulations require chronological integrity. The branch lookup uses numeric identifiers that map naturally to relative record positions. Selecting the wrong cluster type leads to inefficient access patterns, unnecessary complexity in application code, or both.
2. Free Space Planning Prevents Performance Degradation
The FREESPACE(20 10) specification on the KSDS directly affects long-term performance. Too little free space causes frequent CI and CA splits, degrading both random and sequential access performance. Too much free space wastes DASD and increases sequential processing time because VSAM must read through empty CIs. The team arrived at 20/10 through analysis of the legacy system's insert patterns: approximately 15% of CIs would receive new records between monthly reorganizations.
3. IDCAMS Conditional Logic Is Essential for Restartability
Every DELETE command in the cluster definition job includes IF LASTCC <= 8 THEN SET MAXCC = 0. Without this, a first-time run (where no clusters exist to delete) would set a non-zero condition code and prevent subsequent steps from executing. This pattern makes the job idempotent -- it can be run repeatedly without manual intervention.
4. VERIFY After Abnormal Termination Is Not Optional
If a batch job abends while a VSAM file is open, the high-used RBA in the catalog may not reflect the actual data written. Running VERIFY corrects this discrepancy. The team added VERIFY to the beginning of every batch job that opens VSAM files, not just to the verification job shown here.
5. Alternate Indexes Must Be Planned from the Start
Adding an alternate index to an existing cluster requires rebuilding the index from the base data. For a 4.2-million-record file, BLDINDEX can take 30-45 minutes. The team identified all alternate key requirements during design rather than discovering them after deployment, avoiding unplanned outages.
Discussion Questions
-
The team selected SHAREOPTIONS(2 3) for all clusters. What would happen if they had chosen SHAREOPTIONS(1 3) instead? How would this affect the planned architecture of concurrent CICS online reads and batch updates?
-
The ESDS for the transaction audit log does not support record deletion. After 90 days, how would you implement a retention policy to remove expired records? What IDCAMS operations would be involved?
-
The RRDS branch lookup assumes branch numbers are numeric and fit within a 9999-slot range. What would happen if the bank introduced alphanumeric branch identifiers (e.g., "NY01", "LA03")? What alternative VSAM organization would you recommend?
-
The FREESPACE(20 10) allocation trades storage space for insert performance. If the bank's growth rate doubled from 8% to 16% annually, how would you adjust the free space parameters, and what monitoring metrics would guide your decision?
-
The alternate index on SSN uses UNIQUEKEY, which means each SSN maps to exactly one account. In practice, a customer might hold multiple accounts (checking, savings, CD). How would you modify the AIX definition to support this, and what changes would the COBOL application require?
-
Why does the team use SPEED rather than RECOVERY when defining the clusters? Under what circumstances would RECOVERY be the better choice, and what is the performance cost?
Connection to Chapter Concepts
This case study directly applies several key concepts from Chapter 29:
-
IDCAMS utility (Section: IDCAMS -- The Access Method Services Utility): The DEFINE CLUSTER, REPRO, LISTCAT, VERIFY, and BLDINDEX commands demonstrate the core IDCAMS functions used in VSAM administration.
-
VSAM cluster types (Section: VSAM Data Set Types): The three cluster types -- KSDS, ESDS, and RRDS -- are each used for the data organization they are best suited to, illustrating the selection criteria covered in the chapter.
-
JCL for utility programs (Section: Coding JCL for Mainframe Utilities): Every job shown follows the standard JCL structure for IDCAMS invocation: PGM=IDCAMS, SYSPRINT for output, and SYSIN for control statements.
-
VSAM performance parameters (Section: VSAM Tuning with IDCAMS): Control interval size, free space percentages, and share options demonstrate the performance tuning capabilities available through IDCAMS cluster definition.