cheat sheet
IDCAMS
Define, copy, list, alter, and delete VSAM clusters and general datasets — the everyday utility for catalog and dataset lifecycle on z/OS.
IDCAMS — Access Method Services for VSAM
What it is
IDCAMS (the program name; "Access Method Services" or AMS is the language) is IBM's command-driven utility for managing VSAM datasets and the integrated catalog on z/OS — define, alter, list, copy, print, delete, repair, every lifecycle operation lives here. It is one of the few z/OS utilities you run every day across roles: DBAs use it to allocate KSDS clusters under CICS and Db2, batch programmers use REPRO to copy and reshape sequential files, and system programmers use LISTCAT to investigate where a dataset actually lives. Reach for IDCAMS whenever the verb in your head is "define", "list", "copy", or "delete" against a dataset. For pure PDS member manipulation prefer IEBCOPY; for byte-level dataset inspection prefer ISPF Browse or DFSORT.
Invoking IDCAMS
IDCAMS runs as PGM=IDCAMS from JCL, or via TSO IDCAMS interactively. It always reads commands from the SYSIN DD and writes reports to SYSPRINT. The same SYSIN can contain any number of commands; each is independent and its return code rolls up via the LASTCC and MAXCC symbols.
//ALICEJ01 JOB (ACCT),'ALICE',CLASS=A,MSGCLASS=X,NOTIFY=&SYSUID
//IDCAMS EXEC PGM=IDCAMS
//SYSPRINT DD SYSOUT=*
//SYSIN DD *
LISTCAT ENTRIES('ALICE.MASTER.KSDS') ALL
/*
Output:
IDCAMS SYSTEM SERVICES TIME: 10:23:11
LISTCAT ENTRIES('ALICE.MASTER.KSDS') ALL
CLUSTER ------- ALICE.MASTER.KSDS
... attributes ...
IDC0001I FUNCTION COMPLETED, HIGHEST CONDITION CODE WAS 0
Interactive use is identical but with the commands typed directly at the TSO prompt:
TSO IDCAMS
ENTER COMMAND>
LISTCAT ENTRIES('ALICE.MASTER.KSDS') ALL
Output: (same LISTCAT report, displayed on the terminal)
Command structure
Every IDCAMS command is a verb followed by positional and keyword parameters. Continuation is a trailing hyphen (-); comments are /* ... */. Keyword arguments can usually be abbreviated to three or four letters (e.g. RECORDSIZE → RECSZ) but most shops write them out for readability.
VERB POSITIONAL -
(NAME(...) -
<parm1> -
<parm2>) -
<secondary-parm1> -
<secondary-parm2>
The verbs split into four buckets: define (DEFINE CLUSTER, DEFINE AIX, DEFINE PATH, DEFINE GDG, DEFINE ALIAS, DEFINE PAGESPACE), list/inspect (LISTCAT, PRINT, EXAMINE), copy/load (REPRO, EXPORT, IMPORT, BLDINDEX), and modify/destroy (ALTER, DELETE, RENAME, VERIFY).
DEFINE CLUSTER — VSAM allocation
DEFINE CLUSTER allocates a new VSAM dataset of one of four organizations: KSDS (keyed, the default for most CICS files), ESDS (entry-sequenced, append-only), RRDS (relative-record, fixed-length numbered slots), and LDS (linear dataset, used by Db2 tablespaces). The cluster is the logical object; the data component and (for KSDS/AIX) the index component are physical sub-allocations.
//DEFKSDS EXEC PGM=IDCAMS
//SYSPRINT DD SYSOUT=*
//SYSIN DD *
DEFINE CLUSTER -
( NAME(ALICE.MASTER.KSDS) -
INDEXED -
KEYS(10 0) -
RECORDSIZE(80 256) -
RECORDS(5000 500) -
FREESPACE(20 10) -
SHAREOPTIONS(2 3) -
VOLUMES(SHARED) -
SPEED -
) -
DATA ( NAME(ALICE.MASTER.KSDS.DATA) -
CISZ(4096) ) -
INDEX ( NAME(ALICE.MASTER.KSDS.INDEX) -
CISZ(1024) )
/*
Output:
IDC0508I DATA ALLOCATION STATUS FOR VOLUME SMS001 IS 0
IDC0509I INDEX ALLOCATION STATUS FOR VOLUME SMS001 IS 0
IDC0181I STORAGECLASS USED IS SCSTND
IDC0001I FUNCTION COMPLETED, HIGHEST CONDITION CODE WAS 0
The important knobs:
| Parameter | Meaning |
|---|---|
INDEXED / NONINDEXED / NUMBERED / LINEAR | KSDS / ESDS / RRDS / LDS |
KEYS(length offset) | Primary key length and offset (KSDS only) |
RECORDSIZE(avg max) | Average and maximum logical record length |
RECORDS(prim sec) | Primary and secondary allocation in records |
TRACKS(prim sec) | Same in tracks |
CYLINDERS(prim sec) | Same in cylinders |
FREESPACE(ci% ca%) | Percent free per CI and per CA — leaves room for inserts |
SHAREOPTIONS(cross-region cross-system) | Concurrent-access policy (see below) |
VOLUMES(vol1 vol2) / SHARED | Volume placement; under SMS use the SMS class |
STORAGECLASS() / MGMTCLASS() / DATACLASS() | SMS classes (preferred when SMS is active) |
SPEED / RECOVERY | Load mode — SPEED skips preformat, faster initial load |
REUSE / NOREUSE | Allow the cluster to be reopened in load mode |
SPANNED / NOSPANNED | Permit records to span CIs |
IMBED / NOIMBED | (Deprecated) embed sequence set with data |
REPLICATE / NOREPLICATE | (Deprecated) replicate index records |
CONTROLINTERVALSIZE(n) / CISZ(n) | CI size in bytes (512 — 32768) |
BUFFERSPACE(n) | Minimum buffer pool size at open |
ERASE / NOERASE | Overwrite data area on delete |
SHAREOPTIONS quick decoder
The two SHAREOPTIONS numbers define cross-region and cross-system concurrent access. Choosing the right pair is one of the most common DBA discussions for a new file.
| Pair | Meaning |
|---|---|
(1 3) | One updater + many readers, single system |
(2 3) | One updater + many readers, multi-system |
(3 3) | Many updaters, anything goes — applications must serialize themselves |
(4 3) | Many updaters, VSAM enforces serial buffering (slower) |
(3 3) is the common CICS choice when the region itself handles locking; never use it for batch programs that update directly without serialization.
DEFINE ALTERNATEINDEX and DEFINE PATH
An Alternate Index (AIX) is a KSDS that maps non-primary key values back to primary keys of a base cluster — letting an application read records by, say, customer-email when the base is keyed by customer-id. A PATH is the named view that joins the AIX to the base cluster; programs open the path, not the AIX directly.
//DEFAIX EXEC PGM=IDCAMS
//SYSPRINT DD SYSOUT=*
//SYSIN DD *
DEFINE AIX -
( NAME(ALICE.MASTER.AIX.EMAIL) -
RELATE(ALICE.MASTER.KSDS) -
KEYS(40 10) -
RECORDSIZE(50 250) -
RECORDS(5000 500) -
UPGRADE -
NONUNIQUEKEY -
SHAREOPTIONS(2 3) -
) -
DATA ( NAME(ALICE.MASTER.AIX.EMAIL.DATA) ) -
INDEX ( NAME(ALICE.MASTER.AIX.EMAIL.INDEX) )
DEFINE PATH -
( NAME(ALICE.MASTER.PATH.EMAIL) -
PATHENTRY(ALICE.MASTER.AIX.EMAIL) -
UPDATE -
)
BLDINDEX -
INDATASET(ALICE.MASTER.KSDS) -
OUTDATASET(ALICE.MASTER.AIX.EMAIL)
/*
Output:
IDC0181I STORAGECLASS USED IS SCSTND
IDC01551I AIX ALICE.MASTER.AIX.EMAIL HAS BEEN SUCCESSFULLY DEFINED
IDC0001I FUNCTION COMPLETED, HIGHEST CONDITION CODE WAS 0
IDC01558I BLDINDEX COMPLETE, RECORDS PROCESSED = 5000
UPGRADE means VSAM automatically updates the AIX whenever the base cluster changes — almost always what you want. NONUNIQUEKEY allows multiple base records to share an alt-key value (e.g. multiple customers with the same email); UNIQUEKEY rejects duplicates at load and update.
BLDINDEX reads the base cluster end-to-end and populates the AIX. It is the only command that does this — the AIX is empty until you build it. After load, UPGRADE keeps it in sync going forward.
REPRO — copy, load, unload
REPRO is the universal copy verb: it copies any sequential or VSAM dataset to any other (with format conversion handled automatically). It's how you load data into a freshly defined KSDS from a flat file, how you unload a KSDS for backup, and how you copy one PDS member to a sequential dataset for transport.
//LOAD EXEC PGM=IDCAMS
//SYSPRINT DD SYSOUT=*
//FLATIN DD DSN=ALICE.MASTER.FLAT,DISP=SHR
//KSDSOUT DD DSN=ALICE.MASTER.KSDS,DISP=SHR
//SYSIN DD *
REPRO INFILE(FLATIN) OUTFILE(KSDSOUT)
/*
Output:
IDC0005I NUMBER OF RECORDS PROCESSED WAS 5000
IDC0001I FUNCTION COMPLETED, HIGHEST CONDITION CODE WAS 0
The DD-name form is preferable for typed datasets (with DCB on the JCL) but you can also reference datasets directly:
REPRO INDATASET(ALICE.MASTER.KSDS) -
OUTDATASET(ALICE.MASTER.BACKUP.FLAT) -
REPLACE
Output:
IDC0005I NUMBER OF RECORDS PROCESSED WAS 5000
Useful REPRO sub-parameters:
| Parameter | Effect |
|---|---|
FROMKEY(x) TOKEY(y) | Copy only records with primary key in this range |
FROMADDRESS(x) TOADDRESS(y) | Same, by RBA |
SKIP(n) | Skip the first n records |
COUNT(n) | Copy at most n records |
REPLACE | Overwrite duplicates in the output cluster |
NOREPLACE | Skip duplicates (default) |
REUSE | Open the output cluster in load-mode, resetting it |
LISTCAT — what is this thing, really
LISTCAT queries the integrated catalog. You can list a single entry's full attributes, every entry under a high-level qualifier, or just the names matching a pattern. It is the single best command to investigate "why is my job seeing a different copy of this dataset than I expect".
LISTCAT ENTRIES('ALICE.MASTER.KSDS') ALL
LISTCAT LEVEL('ALICE') NAMES
LISTCAT LEVEL('ALICE.MASTER') ALL
LISTCAT ENTRIES('ALICE.MASTER.KSDS') VOLUME
LISTCAT ENTRIES('ALICE.MASTER.KSDS') HISTORY
LISTCAT ENTRIES('ALICE.GDG.BASE') GDG ALL
LISTCAT CLUSTER LEVEL('ALICE')
LISTCAT AIX LEVEL('ALICE')
LISTCAT PATH LEVEL('ALICE')
LISTCAT ALIAS LEVEL('ALICE')
LISTCAT USERCATALOG LEVEL('UCAT.PROD.*')
Output:
LISTING FROM CATALOG -- ICFCAT.MASTER
CLUSTER ------- ALICE.MASTER.KSDS
IN-CAT --- ICFCAT.MASTER
HISTORY
DATASET-OWNER-----ALICE CREATION--------2026.144
RELEASE----------------2 EXPIRATION------0000.000
SMSDATA
STORAGECLASS-----SCSTND MANAGEMENTCLASS--MCSTND
DATACLASS--------DCSTND LBACKUP ---0000.000.0000
RLSDATA
LOG--------------------NULL LOGSTREAMID---------(NULL)
PROTECTION-PSWD-----(NULL) RACF----------------(YES)
ASSOCIATIONS
DATA-----ALICE.MASTER.KSDS.DATA
INDEX----ALICE.MASTER.KSDS.INDEX
DATA --------- ALICE.MASTER.KSDS.DATA
ATTRIBUTES
KEYLEN----------------10 AVGLRECL--------------80
MAXLRECL-------------256 BUFSPACE-----------12288
CISIZE--------------4096 CI/CA-----------------72
SHROPTNS(2,3) SPEED UNORDERED NOREUSE NONSPANNED
STATISTICS
REC-TOTAL------------5000 SPLITS-CI--------------0
REC-DELETED------------0 SPLITS-CA--------------0
REC-INSERTED-----------0 FREESPACE-%CI-------20
REC-UPDATED------------0 FREESPACE-%CA-------10
ALLOCATION
SPACE-TYPE--------RECORD HI-A-RBA---------2949120
SPACE-PRI------------5000 HI-U-RBA---------2949120
SPACE-SEC-------------500
VOLUME
VOLSER------------SMS001 DEVTYPE-------X'3010200F'
| Display option | Shows |
|---|---|
NAMES | Just the entry names — fast |
VOLUME | Adds volume serials |
ALLOCATION | Adds RBA, allocation, splits, free space |
HISTORY | Creation date, expiration, owner |
ALL | Everything — attributes, statistics, allocation, volume |
Filter by type with CLUSTER / DATA / INDEX / AIX / PATH / ALIAS / GDG / NONVSAM / PAGESPACE / USERCATALOG.
PRINT — dump dataset contents
PRINT writes the records of a dataset to SYSPRINT in three optional formats: CHARACTER (EBCDIC text), HEX, or DUMP (side-by-side hex + EBCDIC, the most useful for VSAM debugging). Useful when ISPF Browse won't open the file or when you want a permanent log of "the file looked like this at this moment".
PRINT INDATASET(ALICE.MASTER.KSDS) -
FROMKEY(0000000001) -
TOKEY(0000000010) -
DUMP
PRINT INDATASET(ALICE.MASTER.FLAT) -
CHARACTER -
COUNT(5)
Output:
KEY OF RECORD - F0F0F0F0F0F0F0F0F0F1
0000 E2D4C9E3 C840400 ... CUSTOMER NAME etc. ASCII rendered to side
KEY OF RECORD - F0F0F0F0F0F0F0F0F0F2
...
IDC0005I NUMBER OF RECORDS PROCESSED WAS 10
SKIP(n) and COUNT(n) work the same as in REPRO. OUTFILE(dd) writes to a sequential dataset instead of SYSPRINT.
DELETE — remove with consequences
DELETE removes catalog entries and (optionally) scratches the underlying physical dataset. Without parameters it deletes the catalog entry only; with PURGE it ignores expiration date; with ERASE it overwrites the data area first.
DELETE ALICE.MASTER.OLD.KSDS (* basic *)
DELETE ALICE.MASTER.OLD.KSDS PURGE (* ignore exp date *)
DELETE ALICE.MASTER.OLD.KSDS ERASE (* overwrite first *)
DELETE ALICE.MASTER.OLD.KSDS CLUSTER (* explicit type *)
DELETE 'ALICE.OLD.*' MASK (* pattern match *)
DELETE 'ALICE.NONVSAM' NONVSAM SCRATCH (* uncatalog + scratch *)
DELETE 'ALICE.NOENTRY' NOSCRATCH (* uncatalog only *)
DELETE ALICE.GDG.BASE GDG FORCE (* GDG and all gens *)
DELETE ALICE.MASTER.AIX.EMAIL AIX (* drop the AIX *)
DELETE ALICE.MASTER.PATH.EMAIL PATH (* drop the path *)
Output:
IDC0550I ENTRY (D) ALICE.MASTER.OLD.KSDS.DATA DELETED
IDC0550I ENTRY (I) ALICE.MASTER.OLD.KSDS.INDEX DELETED
IDC0550I ENTRY (C) ALICE.MASTER.OLD.KSDS DELETED
IDC0001I FUNCTION COMPLETED, HIGHEST CONDITION CODE WAS 0
For VSAM clusters the index and data components are deleted automatically when the cluster is. For AIX and PATH, drop them individually before the base cluster (or use CLUSTER FORCE).
| Modifier | Behavior |
|---|---|
PURGE | Override expiration / retention |
ERASE | Overwrite physical area before scratch |
SCRATCH / NOSCRATCH | Scratch DASD (default) vs leave it |
FORCE | For GDGs, delete base and all generations |
RECOVERY / NORECOVERY | DSCB recovery option |
MASK | Treat pattern as wildcard for bulk delete |
ALTER and RENAME
ALTER modifies attributes of an existing cluster without re-defining it; RENAME changes the name only. Most attribute changes do not require unload/reload, but a few (e.g. CISIZE, KEYS, RECORDSIZE) cannot be altered — you must redefine and reload.
ALTER ALICE.MASTER.KSDS SHAREOPTIONS(3 3)
ALTER ALICE.MASTER.KSDS FREESPACE(30 20)
ALTER ALICE.MASTER.KSDS ADDVOLUMES(SMS002)
ALTER ALICE.MASTER.KSDS NULLIFY(OWNER)
ALTER ALICE.MASTER.KSDS BUFFERSPACE(65536)
ALTER ALICE.MASTER.OLD.KSDS NEWNAME(ALICE.MASTER.NEW.KSDS)
ALTER ALICE.MASTER.NEW.KSDS.DATA NEWNAME(ALICE.MASTER.NEW.KSDS.DATA)
ALTER ALICE.MASTER.NEW.KSDS.INDEX NEWNAME(ALICE.MASTER.NEW.KSDS.INDEX)
Output:
IDC0531I ENTRY ALICE.MASTER.KSDS ALTERED
IDC0001I FUNCTION COMPLETED, HIGHEST CONDITION CODE WAS 0
Renaming a VSAM cluster does not rename its DATA and INDEX components — you must alter each one separately. Forgetting this is one of the most common IDCAMS pitfalls.
EXAMINE and VERIFY
EXAMINE runs a structural integrity check on a KSDS — chases pointers through the index, validates control-interval headers, reports broken or out-of-sequence keys. VERIFY is lighter: it compares the catalog's "high used RBA" with the actual end-of-file and fixes the catalog if the dataset was left open across a crash.
EXAMINE NAME(ALICE.MASTER.KSDS) INDEXTEST DATATEST ERRORLIMIT(100)
VERIFY DATASET(ALICE.MASTER.KSDS)
Output:
IDC01700I INDEXTEST BEGINS
IDC01707I INDEXTEST SUCCESSFUL, NO LOGICAL ERRORS DETECTED
IDC01702I DATATEST BEGINS
IDC01708I DATATEST SUCCESSFUL, NO LOGICAL ERRORS DETECTED
IDC0001I FUNCTION COMPLETED, HIGHEST CONDITION CODE WAS 0
IDC01548I VERIFY HIGH USED RBA = 2949120, HIGH ALLOCATED RBA = 2949120
IDC0001I FUNCTION COMPLETED, HIGHEST CONDITION CODE WAS 0
Run VERIFY against any cluster that abended a job mid-update before re-running. Run EXAMINE periodically against critical KSDS files; CI/CA split corruption is rare but real.
DEFINE GENERATIONDATAGROUP
A GDG is a named series of generations of the same dataset. DEFINE GENERATIONDATAGROUP creates the empty base; JCL with (+1) allocates new generations against it.
DEFINE GENERATIONDATAGROUP -
( NAME(ALICE.DAILY.BACKUP) -
LIMIT(14) -
SCRATCH -
NOEMPTY -
)
Output:
IDC0531I ENTRY ALICE.DAILY.BACKUP DEFINED
IDC0001I FUNCTION COMPLETED, HIGHEST CONDITION CODE WAS 0
| Parameter | Meaning |
|---|---|
LIMIT(n) | Maximum generations to retain |
SCRATCH / NOSCRATCH | Physically scratch rolled-off generations vs only uncatalog |
EMPTY / NOEMPTY | At rollover, uncatalog all generations vs only the oldest |
OWNER(id) | Catalog owner ID |
FOR(days) / TO(date) | Default retention for new generations |
EXTENDED | Allow up to 999 generations (otherwise capped at 255) |
See the upcoming gdg article for the JCL-side reference patterns.
ALIAS, USERCATALOG, ALIAS chains
A USERCATALOG is a non-master catalog; an ALIAS routes a high-level qualifier to a specific catalog. Most sites direct each application's HLQ to a dedicated USERCATALOG so backups, recovery, and ownership are scoped.
DEFINE USERCATALOG -
( NAME(UCAT.ALICE) -
VOLUME(SMS001) -
CYLINDERS(50 10) -
ICFCATALOG -
) -
DATA ( CYLINDERS(45 10) ) -
INDEX ( CYLINDERS(5 2) )
DEFINE ALIAS -
( NAME(ALICE) -
RELATE(UCAT.ALICE) -
)
Output:
IDC0531I ENTRY UCAT.ALICE DEFINED
IDC0531I ENTRY ALICE DEFINED
After this, every dataset created under HLQ ALICE.* is catalogued in UCAT.ALICE automatically. Most users will never define a USERCATALOG or ALIAS directly — they are owned by the storage admin — but understanding the chain is essential for diagnosing "why does the catalog not find my dataset".
Return codes — LASTCC and MAXCC
Each command sets LASTCC (this command's RC) and updates MAXCC (the highest RC seen in the step). You can branch on either with IF.
DELETE ALICE.MASTER.OLD.KSDS
IF LASTCC <= 8 THEN -
SET MAXCC = 0 /* swallow the not-found / already-deleted case */
DEFINE CLUSTER ( NAME(ALICE.MASTER.OLD.KSDS) INDEXED KEYS(10 0) -
RECORDSIZE(80 80) RECORDS(100 50) ) -
DATA(NAME(ALICE.MASTER.OLD.KSDS.DATA)) -
INDEX(NAME(ALICE.MASTER.OLD.KSDS.INDEX))
IF LASTCC NE 0 THEN -
SET MAXCC = 16 /* force the step to fail loudly if define failed */
Output:
IDC0550I ENTRY (D) ALICE.MASTER.OLD.KSDS DELETED
IDC0001I FUNCTION COMPLETED, HIGHEST CONDITION CODE WAS 0
IDC0531I ENTRY ALICE.MASTER.OLD.KSDS DEFINED
IDC0001I FUNCTION COMPLETED, HIGHEST CONDITION CODE WAS 0
This "delete-then-define" pattern with SET MAXCC = 0 is the canonical idempotent allocate-or-recreate idiom. Without the SET, a not-found DELETE returns RC=8, which sets MAXCC=8, which propagates to the step return code.
| RC | Meaning |
|---|---|
| 0 | Success |
| 4 | Warning — minor issue, command succeeded |
| 8 | Error — command failed (e.g. duplicate, not found) |
| 12 | Serious — likely a syntax or logic error |
| 16 | Terminal — environment problem (e.g. SYSIN open failure) |
Common pitfalls
- Renaming a cluster without renaming its components —
ALTER cluster NEWNAMEdoesn't touch DATA and INDEX. Always issue three ALTERs together. - Forgetting
BLDINDEXafterDEFINE AIX— the alt-index is empty andUPGRADEonly maintains it from then forward. Applications opening the path before BLDINDEX see no data. SHAREOPTIONS(3 3)everywhere — looks innocent and is the cause of many "the file is corrupt" calls. Batch programs without their own serialization will lose updates.- Quoting matters in
LEVELvsENTRIES—LEVEL('ALICE.MASTER')matches everything under that HLQ;ENTRIES('ALICE.MASTER')looks for an entry literally namedALICE.MASTER. Mixing them returns zero entries. - Deleting a GDG base without
FORCE— fails if any generations exist. UseGDG FORCEor delete generations first. PURGEon an unexpired dataset — there's no undo, no recycle bin. RACF-controlled in production environments for exactly this reason.DEFINE CLUSTERwithRECORDSIZE(80 80)butKEYS(10 5)— key extends past the record. IDCAMS detects this only when you load data; the define succeeds.- Forgetting
REUSEon a temporary cluster — withoutREUSE, the second time you open it for load mode IDCAMS rejects with "already loaded".REUSEre-clears it on open. - No
SYSPRINTin the JCL — IDCAMS opens with RC=16 and a JCL-error message. SYSPRINT is mandatory. - Continuation hyphen in the wrong column — the
-must be the last non-blank character on the line. A trailing space after the hyphen breaks continuation silently. LISTCAT ALLagainst a USERCATALOG with thousands of entries — generates megabytes of SYSOUT. UseNAMESfirst to scope, thenALLagainst specific entries.- EXAMINE without
ERRORLIMIT— defaults to 2,000,000,000 errors before it stops. On a truly broken cluster the SYSPRINT can be enormous. SetERRORLIMIT(100)to be safe.
Sources
References consulted while writing this article. Links open in a new tab.
- IBM Documentation — DFSMS Access Method Services Commands — Authoritative reference for IDCAMS commands (DEFINE, REPRO, LISTCAT, EXAMINE, BLDINDEX) covered in this article.
Real-world recipes
Define and load a KSDS from a flat file end-to-end
The full new-cluster bootstrap: define, load, define and build AIX, define path.
//ALICEJ01 JOB (ACCT),'ALICE',CLASS=A,MSGCLASS=X,NOTIFY=&SYSUID
//*
//* Step 1 — Clean slate (idempotent)
//*
//CLEAN EXEC PGM=IDCAMS
//SYSPRINT DD SYSOUT=*
//SYSIN DD *
DELETE ALICE.MASTER.KSDS CLUSTER
IF LASTCC <= 8 THEN SET MAXCC = 0
/*
//*
//* Step 2 — Define cluster + AIX + path
//*
//DEFINE EXEC PGM=IDCAMS
//SYSPRINT DD SYSOUT=*
//SYSIN DD *
DEFINE CLUSTER -
( NAME(ALICE.MASTER.KSDS) INDEXED KEYS(10 0) -
RECORDSIZE(80 256) RECORDS(5000 500) -
FREESPACE(20 10) SHAREOPTIONS(2 3) ) -
DATA ( NAME(ALICE.MASTER.KSDS.DATA) CISZ(4096) ) -
INDEX ( NAME(ALICE.MASTER.KSDS.INDEX) CISZ(1024) )
DEFINE AIX -
( NAME(ALICE.MASTER.AIX.EMAIL) -
RELATE(ALICE.MASTER.KSDS) -
KEYS(40 10) RECORDSIZE(50 250) -
RECORDS(5000 500) UPGRADE NONUNIQUEKEY ) -
DATA ( NAME(ALICE.MASTER.AIX.EMAIL.DATA) ) -
INDEX ( NAME(ALICE.MASTER.AIX.EMAIL.INDEX) )
DEFINE PATH -
( NAME(ALICE.MASTER.PATH.EMAIL) -
PATHENTRY(ALICE.MASTER.AIX.EMAIL) UPDATE )
/*
//*
//* Step 3 — Load and build
//*
//LOAD EXEC PGM=IDCAMS,COND=(0,NE)
//SYSPRINT DD SYSOUT=*
//SYSIN DD *
REPRO INDATASET(ALICE.MASTER.FLAT) -
OUTDATASET(ALICE.MASTER.KSDS)
BLDINDEX INDATASET(ALICE.MASTER.KSDS) -
OUTDATASET(ALICE.MASTER.AIX.EMAIL)
/*
Output:
IDC0550I ENTRY (C) ALICE.MASTER.KSDS DELETED
IDC0001I FUNCTION COMPLETED, HIGHEST CONDITION CODE WAS 0
IDC0531I ENTRY ALICE.MASTER.KSDS DEFINED
IDC0531I ENTRY ALICE.MASTER.AIX.EMAIL DEFINED
IDC0531I ENTRY ALICE.MASTER.PATH.EMAIL DEFINED
IDC0001I FUNCTION COMPLETED, HIGHEST CONDITION CODE WAS 0
IDC0005I NUMBER OF RECORDS PROCESSED WAS 5000
IDC01558I BLDINDEX COMPLETE, RECORDS PROCESSED = 5000
IDC0001I FUNCTION COMPLETED, HIGHEST CONDITION CODE WAS 0
Daily backup and restore of a KSDS
Two short jobs: one unloads the KSDS to a flat file for archive, the other reloads it after a corruption.
//* BACKUP
//BACKUP EXEC PGM=IDCAMS
//SYSPRINT DD SYSOUT=*
//KSDSIN DD DSN=ALICE.MASTER.KSDS,DISP=SHR
//FLATOUT DD DSN=ALICE.MASTER.BACKUP.FLAT(+1),
// DISP=(NEW,CATLG,DELETE),
// SPACE=(CYL,(10,5),RLSE),
// DCB=(RECFM=VB,LRECL=260,BLKSIZE=27998)
//SYSIN DD *
REPRO INFILE(KSDSIN) OUTFILE(FLATOUT)
/*
//* RESTORE
//RESTORE EXEC PGM=IDCAMS
//SYSPRINT DD SYSOUT=*
//SYSIN DD *
DELETE ALICE.MASTER.KSDS CLUSTER
IF LASTCC <= 8 THEN SET MAXCC = 0
DEFINE CLUSTER -
( NAME(ALICE.MASTER.KSDS) INDEXED KEYS(10 0) -
RECORDSIZE(80 256) RECORDS(5000 500) -
FREESPACE(20 10) SHAREOPTIONS(2 3) ) -
DATA ( NAME(ALICE.MASTER.KSDS.DATA) CISZ(4096) ) -
INDEX ( NAME(ALICE.MASTER.KSDS.INDEX) CISZ(1024) )
REPRO INDATASET(ALICE.MASTER.BACKUP.FLAT(0)) -
OUTDATASET(ALICE.MASTER.KSDS)
/*
Output:
IDC0005I NUMBER OF RECORDS PROCESSED WAS 5000
IDC0001I FUNCTION COMPLETED, HIGHEST CONDITION CODE WAS 0
The (+1) on the backup creates a new GDG generation each run; (0) on restore reads the current generation. Combined with a GDG LIMIT(14), you get free 14-day rolling backups.
Inspect why a job said "dataset not found"
The job referenced ALICE.MASTER.KSDS and got IGZ0035C. Find the actual cluster, its volume, and its catalog.
LISTCAT ENTRIES('ALICE.MASTER.KSDS') ALL
LISTCAT LEVEL('ALICE.MASTER') NAMES
LISTCAT ALIAS LEVEL('ALICE')
Output:
LISTING FROM CATALOG -- ICFCAT.MASTER
NO ENTRY MATCHING ENTRIES NAME 'ALICE.MASTER.KSDS' WAS FOUND
ALIAS ----------- ALICE
IN-CAT --- ICFCAT.MASTER
ASSOCIATIONS
USERCAT--UCAT.ALICE.OLD
The HLQ ALICE is aliased to a stale USERCATALOG — the cluster exists, but in a USERCATALOG that's no longer mounted to this system. Either remount UCAT or redefine the alias to the correct catalog.
Re-organize a fragmenting KSDS
Inserts are causing CI/CA splits and performance is degrading. Unload, redefine with bigger free space, reload.
//REORG EXEC PGM=IDCAMS
//SYSPRINT DD SYSOUT=*
//SYSIN DD *
REPRO INDATASET(ALICE.MASTER.KSDS) -
OUTDATASET(ALICE.MASTER.WORK.FLAT) -
REUSE
DELETE ALICE.MASTER.KSDS CLUSTER
DEFINE CLUSTER -
( NAME(ALICE.MASTER.KSDS) INDEXED KEYS(10 0) -
RECORDSIZE(80 256) RECORDS(10000 1000) -
FREESPACE(30 20) SHAREOPTIONS(2 3) ) -
DATA ( NAME(ALICE.MASTER.KSDS.DATA) CISZ(4096) )-
INDEX ( NAME(ALICE.MASTER.KSDS.INDEX) CISZ(1024) )
REPRO INDATASET(ALICE.MASTER.WORK.FLAT) -
OUTDATASET(ALICE.MASTER.KSDS)
LISTCAT ENTRIES('ALICE.MASTER.KSDS') ALL
/*
Output:
IDC0005I NUMBER OF RECORDS PROCESSED WAS 5000
IDC0531I ENTRY ALICE.MASTER.KSDS DEFINED
IDC0005I NUMBER OF RECORDS PROCESSED WAS 5000
... cluster shows SPLITS-CI = 0, SPLITS-CA = 0
Doubled RECORDS and increased FREESPACE from 20/10 to 30/20 give the inserts room without hitting splits for the next quarter.
Print the first ten records of a binary VSAM file
You don't know if the file even has data. Dump a few records in hex+character form.
PRINT INDATASET(ALICE.MASTER.KSDS) DUMP COUNT(10)
Output:
KEY OF RECORD - F0F0F0F0F0F0F0F0F0F1
000000 F0F0F0F0 F0F0F0F0 F0F1C1D3 C9C3C540 *0000000001ALICE *
000010 C4C5E540 4040C140 40404040 40404040 *DEV A *
...
IDC0005I NUMBER OF RECORDS PROCESSED WAS 10
The hex side reveals byte-by-byte content; the character column on the right renders printable EBCDIC. Use this to confirm encoding, key alignment, and padding before suspecting a program bug.
Bulk-delete every test dataset under a HLQ
You're decommissioning a project. Drop every dataset under ALICE.TEST.* in one job.
DELETE 'ALICE.TEST.*' MASK PURGE
LISTCAT LEVEL('ALICE.TEST') NAMES
Output:
IDC0550I ENTRY (C) ALICE.TEST.KSDS1 DELETED
IDC0550I ENTRY (C) ALICE.TEST.KSDS2 DELETED
IDC0550I ENTRY (A) ALICE.TEST.SEQ1 DELETED
IDC0531I NO ENTRIES MEET SEARCH CRITERIA
IDC0001I FUNCTION COMPLETED, HIGHEST CONDITION CODE WAS 0
MASK enables wildcards; PURGE ignores expiration dates. In production, run with NOSCRATCH first to uncatalog only — verify nothing important got matched — then a second pass to scratch.
Compare cluster statistics before and after a load
A diagnostic for tracking insert behavior over time.
//STATS EXEC PGM=IDCAMS
//SYSPRINT DD SYSOUT=*
//SYSIN DD *
LISTCAT ENTRIES('ALICE.MASTER.KSDS.DATA') ALL
/*
Output:
STATISTICS
REC-TOTAL------------5234 SPLITS-CI--------------12
REC-DELETED------------0 SPLITS-CA-------------- 1
REC-INSERTED---------234 FREESPACE-%CI-------17
REC-UPDATED-----------54 FREESPACE-%CA-------09
12 CI splits and 1 CA split since the last reorg — still well within the budget. When SPLITS-CI climbs into the thousands or FREESPACE-%CI drops near zero, schedule a reorg.
Run IDCAMS interactively from TSO READY
For ad-hoc one-liners you don't need JCL — invoke IDCAMS as a TSO command.
READY
TSO IDCAMS
ENTER COMMAND>
LISTCAT ENTRIES('ALICE.MASTER.KSDS') NAMES
LISTING FROM CATALOG -- ICFCAT.MASTER
CLUSTER ------- ALICE.MASTER.KSDS
DATA --------- ALICE.MASTER.KSDS.DATA
INDEX --------- ALICE.MASTER.KSDS.INDEX
ENTER COMMAND>
END
READY
Output: (LISTCAT result then back to TSO READY)
Two commands per line at most — TSO's input width is 80 columns and IDCAMS truncates silently past that. For anything more than a LISTCAT or a quick DELETE, write JCL.