Managing multiple versions of datasets efficiently
Generation Data Groups (GDGs) are a powerful z/OS feature that allows you to manage multiple versions (generations) of related datasets. Each time a new generation is created, it becomes part of the group, and the system maintains the relationship between all versions.
GDGs are especially useful for:
A catalog entry that defines properties for the group and associates all generations
An individual dataset that belongs to a GDG
The actual identifier (G0001V00) assigned by the system
Reference to generations relative to current (0, -1, +1)
Maximum number of generations maintained in the catalog
Process where oldest generations are removed when limit is reached
When you define a GDG, you create a GDG base entry in the catalog. The base doesn't contain any data itself; it's a control structure that groups the individual generations. Each physical dataset (generation) has a name consisting of the GDG base name followed by a suffix like G0001V00, G0002V00, etc.
Before you can create generation datasets, you must first define a GDG base using the IDCAMS utility. The base entry establishes the properties for the entire group.
123456789//DEFGDG EXEC PGM=IDCAMS //SYSPRINT DD SYSOUT=* //SYSIN DD * DEFINE GENERATIONDATAGROUP - (NAME(MY.EXAMPLE.GDG) - LIMIT(5) - NOEMPTY - SCRATCH) /*
To create a new generation, you reference the GDG base name with a relative generation number of +1:
12345678//STEP1 EXEC PGM=MYPROG //SYSPRINT DD SYSOUT=* //OUTPUT DD DSN=MY.EXAMPLE.GDG(+1), // DISP=(NEW,CATLG,DELETE), // SPACE=(CYL,(1,1)),DCB=(RECFM=FB,LRECL=80,BLKSIZE=27920) //SYSIN DD * Data records... /*
When creating a new generation, always specify DISP=(NEW,CATLG,DELETE). The CATLG disposition is essential for properly adding the dataset to the GDG.
You can reference generations using relative numbers:
1234//STEP1 EXEC PGM=MYPROG //SYSPRINT DD SYSOUT=* //INPUT DD DSN=MY.EXAMPLE.GDG(0),DISP=SHR //OUTPUT DD SYSOUT=*
12345678//STEP1 EXEC PGM=MYPROG //SYSPRINT DD SYSOUT=* //INPUT DD DSN=MY.EXAMPLE.GDG(-1),DISP=SHR // DD DSN=MY.EXAMPLE.GDG(-2),DISP=SHR // DD DSN=MY.EXAMPLE.GDG(-3),DISP=SHR // DD DSN=MY.EXAMPLE.GDG(-4),DISP=SHR // DD DSN=MY.EXAMPLE.GDG(0),DISP=SHR //OUTPUT DD SYSOUT=*
To list information about a GDG base and its generations, use the LISTCAT command:
12345//LISTGDG EXEC PGM=IDCAMS //SYSPRINT DD SYSOUT=* //SYSIN DD * LISTCAT ENTRIES(MY.EXAMPLE.GDG) ALL /*
To delete a GDG base and potentially all its generations, use the DELETE command:
12345//DELGDG EXEC PGM=IDCAMS //SYSPRINT DD SYSOUT=* //SYSIN DD * DELETE MY.EXAMPLE.GDG GDG FORCE /*
Warning: Deleting a GDG base will affect all associated generations based on the EMPTY/NOEMPTY option specified when the GDG was created.
You can modify certain GDG attributes using the ALTER command:
12345//ALTGDG EXEC PGM=IDCAMS //SYSPRINT DD SYSOUT=* //SYSIN DD * ALTER MY.EXAMPLE.GDG LIMIT(10) /*
Choose a LIMIT value based on your retention needs and storage capacity. Too low might cause needed data to be lost; too high consumes unnecessary space.
NOSCRATCH preserves datasets that roll off but keeps them uncataloged. This provides safety but requires manual cleanup eventually.
Avoid referencing generations by their absolute names (with G0001V00) in JCL; use relative numbers to ensure your JCL works consistently.
Keep clear documentation about your GDGs, including their purpose, retention requirements, and jobs that use them.
Specify complete DCB parameters when creating the first generation to establish consistent dataset attributes for all generations.
Ensure your catalog backup procedures include GDG bases to facilitate disaster recovery without manual GDG reconstruction.
Create JCL to implement a daily reporting system using GDGs. The system should:
Consider how you would handle:
Try writing the JCL yourself, then compare with a sample solution in a future lesson.
1. What is the primary purpose of Generation Data Groups?
2. Which command is used to define a GDG base?
3. What does a relative generation number of -1 refer to?
4. What happens when a GDG reaches its LIMIT value?
5. How would you reference the current (latest) generation in a JCL statement?