1. ICF Catalog — o que é e por que existe

ICF (Integrated Catalog Facility) é o sistema de catálogo do z/OS. Cada dataset que existe no sistema — VSAM ou não-VSAM — tem uma entrada no catálogo que descreve onde ele está (volume, dispositivo), quais são seus atributos (tamanho, tipo, datas) e quem pode acessá-lo.

🦕 Analogia
O catálogo ICF é como o índice de uma biblioteca enorme. Os livros (datasets) estão nas prateleiras (volumes DASD), mas sem o índice você não sabe em qual prateleira está "PROD.CLIENTES.KSDS". O catálogo guarda: nome do dataset → volume → tipo → atributos → data de criação. O z/OS consulta o catálogo toda vez que um job faz OPEN em um dataset.

O catálogo ICF em si é um conjunto de datasets VSAM especiais — um KSDS para os registros de nomes e um ESDS de dados de volume (o VVDS). Isso significa que o catálogo usa VSAM para armazenar informações sobre VSAM.

O que o catálogo armazena por dataset

InformaçãoExemplo
Nome do datasetPROD.CLIENTES.KSDS
TipoCLUSTER / DATA / INDEX / NONVSAM
Volume(s)VOL001, VOL002
Dispositivo3390
Data de criação2026/120
Data de expiração0000.000 (sem expiração)
Atributos VSAMRECORDSIZE, KEYS, CISZ, FREESPACE, SHAREOPTIONS
EstatísticasREC-TOTAL, SPLITS-CI, EXTENTS
OwnerUSERID ou NULL

2. Master catalog e user catalogs

O z/OS usa uma hierarquia de dois níveis de catálogos:

Hierarquia de catálogos ICF
┌─────────────────────────────────────────────────────────┐
│              MASTER CATALOG (SYS1.MASTER.ICFCAT)        │
│  Contém: datasets do sistema, aliases de user catalogs  │
│  Fica em: volume de IPL (SYSRES)                        │
└─────────────────┬───────────────────┬───────────────────┘
                  │                   │
        ┌─────────▼──────┐  ┌─────────▼──────┐
        │ UCAT.PROD       │  │ UCAT.DESEN      │
        │ (user catalog)  │  │ (user catalog)  │
        │ Contém: PROD.*  │  │ Contém: DESEN.* │
        └─────────────────┘  └─────────────────┘

Master catalog

Existe exatamente um master catalog por sistema z/OS. Ele é inicializado na instalação do sistema e fica em disco de boot. Contém:

  • Datasets do sistema (SYS1.*, MVS1.*, etc.)
  • Entradas de alias que apontam prefixos de nome para user catalogs
  • O próprio catálogo master como entrada
⚠️ Master catalog é crítico
Corrupção do master catalog pode tornar o sistema inacessível. Por isso, ele é protegido por RACF, tem backup automático e não deve ser manipulado diretamente. Programadores não definem datasets no master catalog — isso é feito exclusivamente em user catalogs.

User catalogs

User catalogs são criados pelo DBA para organizar datasets por ambiente, projeto ou sistema. Cada user catalog cobre um ou mais prefixos de nome definidos por ALIAS no master catalog.

IDCAMS — criando um user catalog
  DEFINE USERCATALOG                          -
         (NAME(UCAT.PROD)                     -
          CYLINDERS(5 2)                      -
          VOLUMES(CATVOL)                     -
          ICFCATALOG)

3. VVDS — VSAM Volume Data Set

Além do catálogo ICF (que fica num único volume), cada volume DASD que contém datasets VSAM possui um VVDS (VSAM Volume Data Set). O VVDS armazena as informações de localização física dos datasets VSAM naquele volume específico.

Relação catálogo ICF ↔ VVDS
Catálogo ICF (UCAT.PROD, num único volume):
  └── "PROD.CLIENTES.KSDS está no volume VOL001"

VVDS no volume VOL001 (SYS1.VVDS.VVOL001):
  └── "PROD.CLIENTES.KSDS ocupa as trilhas X a Y, CISZ=4096..."

Quando o z/OS abre PROD.CLIENTES.KSDS:
  1. Consulta catálogo ICF → sabe que está em VOL001
  2. Consulta VVDS de VOL001 → sabe a localização exata no disco

O VVDS é um ESDS criado automaticamente pelo z/OS na primeira vez que um dataset VSAM é definido num volume. Seu nome sempre segue o padrão SYS1.VVDS.V<volser>.

💗 Por que o programador precisa saber isso?
Quando um LISTCAT diz "catálogo inconsistente com VVDS" ou quando um VERIFY falha com "VVDS inacessível", você entende que o problema está no dataset de controle do volume, não nos seus dados de aplicação. Isso direciona a chamada para o time correto (sistemas) e evita ações erradas como reorganizar um KSDS que não tem problema.

4. ALIAS — conectando prefixos ao user catalog

Um ALIAS é uma entrada no master catalog que diz: "qualquer dataset cujo nome começa com <prefixo> pertence ao user catalog <nome>". Sem o ALIAS, o z/OS não sabe em qual catálogo procurar o dataset.

IDCAMS — definindo ALIAS
  /* Todos os datasets PROD.* vão para UCAT.PROD */
  DEFINE ALIAS                                -
         (NAME(PROD)                          -
          RELATE(UCAT.PROD))

  /* Todos os datasets DESEN.* vão para UCAT.DESEN */
  DEFINE ALIAS                                -
         (NAME(DESEN)                         -
          RELATE(UCAT.DESEN))

Após esses aliases, quando um job faz DEFINE CLUSTER com NAME(PROD.CLIENTES.KSDS), o IDCAMS automaticamente cataloga a entrada em UCAT.PROD sem precisar especificar CATALOG(UCAT.PROD) explicitamente.

IDCAMS — listando aliases do master catalog
  LISTCAT CATALOG(SYS1.MASTER.ICFCAT) ALIAS
✅ ALIAS de múltiplos níveis
O alias cobre apenas o primeiro qualificador do nome. DEFINE ALIAS NAME(PROD) cobre PROD.QUALQUER.COISA mas não cobre PRODUCAO.ARQUIVO. Para cobertura de dois níveis como PROD.CONTAS.*, é necessário um alias de dois qualificadores: NAME(PROD.CONTAS). Na prática, alias de um qualificador por ambiente (PROD, DESEN, HOMOL) é o padrão mais comum.

5. VSAM no JCL — DD statements

Ao contrário de datasets sequenciais, datasets VSAM existem antes do job ser executado — eles são criados pelo IDCAMS, não pelo JCL. O DD statement para VSAM é mais simples:

JCL — DD para dataset VSAM existente
//ARQUIVO  DD DSN=PROD.CLIENTES.KSDS,
//            DISP=SHR

Comparando com dataset sequencial:

JCL — sequencial vs VSAM
/* Dataset sequencial — JCL controla criação */
//SEQFILE  DD DSN=PROD.RELAT.SEQ,
//            DISP=(NEW,CATLG,DELETE),
//            SPACE=(CYL,(5,2),RLSE),
//            DCB=(RECFM=FB,LRECL=133,BLKSIZE=13300)

/* Dataset VSAM — já existe, JCL só referencia */
//VSAMFILE DD DSN=PROD.CLIENTES.KSDS,
//            DISP=SHR

Parâmetros que não se aplicam a datasets VSAM no DD:

  • SPACE — alocação foi feita no DEFINE CLUSTER
  • DCB — atributos vêm do catálogo (exceto alguns casos com AMP)
  • RECFM / LRECL / BLKSIZE — definidos no DEFINE CLUSTER

6. DISP com datasets VSAM

O parâmetro DISP para VSAM tem comportamento diferente do sequencial. O z/OS ignora a ação de disposição final (segunda e terceira subparâmetros) para datasets VSAM catalogados:

DISPEfeito em VSAMObservação
DISP=SHR Abre para leitura/escrita compartilhada Mais comum; SHAREOPTIONS do cluster controla concorrência
DISP=OLD Abre com enqueue exclusivo no dataset inteiro Bloqueia outros jobs; use para carga ou reorganização
DISP=(NEW,CATLG) Não funciona para VSAM VSAM não é criado pelo JCL; use IDCAMS DEFINE CLUSTER
DISP=(OLD,DELETE) Delete ignorado para VSAM catalogado Para deletar VSAM, use IDCAMS DELETE explicitamente
DISP=(NEW,DELETE) Cria dataset temporário não-VSAM Não se aplica a VSAM
⚠️ DISP=OLD vs DISP=SHR em batch
Usar DISP=OLD em um KSDS que o CICS também tem aberto causa um enqueue conflict — o job vai esperar indefinidamente que o CICS feche o arquivo, o que normalmente não acontece em produção. Em ambientes onde o CICS acessa o mesmo VSAM, use sempre DISP=SHR e deixe o SHAREOPTIONS controlar a concorrência.

7. Parâmetro AMP — controle avançado

AMP (Access Method Parameters) é um subparâmetro do DD statement que permite passar parâmetros adicionais ao VSAM durante a abertura do dataset. É o único mecanismo para controlar comportamento VSAM via JCL sem alterar o catálogo.

JCL — AMP básico
//ARQUIVO  DD DSN=PROD.CLIENTES.KSDS,
//            DISP=SHR,
//            AMP=('BUFND=8,BUFNI=3')

Parâmetros AMP mais usados

Parâmetro AMPDescriçãoQuando usar
BUFND=n Número de buffers para o componente DATA Aumentar para acesso sequencial intenso (leitura de todo o arquivo)
BUFNI=n Número de buffers para o componente INDEX Aumentar para muitos READs aleatórios (mantém mais do índice em memória)
BUFSP=n Espaço total de buffer em bytes Alternativa ao BUFND/BUFNI quando o total importa mais que a divisão
STRNO=n Número de string concorrentes (posições de leitura) Aumentar quando múltiplas tasks do CICS acessam o mesmo ACB
RMODE31=ALL Aloca buffers acima da linha dos 16MB Datasets grandes em ambiente de 31 bits
ACCBIAS=USER Controle de bias de acesso (sequencial vs aleatório) Ajuste fino de performance em acesso misto
JCL — AMP para alta performance em acesso sequencial
/* Leitura sequencial de KSDS grande: mais buffers DATA */
//ARQUIVO  DD DSN=PROD.CLIENTES.KSDS,
//            DISP=SHR,
//            AMP=('BUFND=20,BUFNI=3,RMODE31=ALL')

/* Acesso aleatório intenso: mais buffers INDEX */
//ARQUIVO  DD DSN=PROD.CLIENTES.KSDS,
//            DISP=SHR,
//            AMP=('BUFND=4,BUFNI=10')
🟣 BUFND mínimo para KSDS
O VSAM exige no mínimo BUFND=2 para KSDS (um buffer para leitura lookahead, um para o CI sendo processado). Para acesso sequencial, o VSAM usa leitura antecipatória (prefetch): com BUFND=8, ele pode ler até 7 CIs à frente enquanto o programa processa o atual, reduzindo tempo de espera de I/O drasticamente. O custo é memória — cada buffer ocupa CISZ bytes (4096 bytes por default).

AMP para identificar um dataset não catalogado

Em situações de recuperação, pode ser necessário abrir um dataset VSAM que não está no catálogo — por exemplo, um volume de backup restaurado. O AMP com AMORG permite isso:

JCL — acessar VSAM não catalogado
//ARQUIVO  DD DSN=PROD.CLIENTES.KSDS,
//            DISP=SHR,
//            VOL=SER=VOLBKP,
//            UNIT=3390,
//            AMP=('AMORG')

8. Definir via JCL vs via IDCAMS

Datasets sequenciais e PDS podem ser criados diretamente pelo JCL com DISP=(NEW,CATLG). Datasets VSAM não podem — eles sempre precisam do IDCAMS DEFINE CLUSTER. Mas existe uma exceção histórica: o parâmetro AMP com AMORG em conjunto com alguns utilitários legados.

TipoCriação via JCLCriação via IDCAMS
Dataset sequencial (QSAM) Sim — DISP=(NEW,CATLG) Possível com DEFINE NONVSAM
PDS / PDSE Sim — DISP=(NEW,CATLG) + DCB=DSORG=PO Possível com DEFINE NONVSAM
VSAM KSDS/ESDS/RRDS Não Obrigatório — DEFINE CLUSTER
VSAM LDS Não DEFINE CLUSTER LINEAR (ou pelo subsistema)

JCL pattern completo: criar e carregar um KSDS

O fluxo típico de um job que cria e popula um KSDS do zero:

JCL — criar KSDS e carregar dados
//CRIAVSAM JOB (ACCT),'CRIA KSDS',CLASS=A,MSGCLASS=X
//*
//* STEP 1 — Apaga o KSDS se existir (ignora erro se não existir)
//*
//STEP1    EXEC PGM=IDCAMS
//SYSPRINT DD SYSOUT=*
//SYSIN    DD *
  DELETE PROD.CLIENTES.KSDS CLUSTER PURGE
  IF LASTCC LE 8 THEN SET MAXCC = 0
/*
//*
//* STEP 2 — Cria o KSDS vazio
//*
//STEP2    EXEC PGM=IDCAMS,COND=(8,LT,STEP1)
//SYSPRINT DD SYSOUT=*
//SYSIN    DD *
  DEFINE CLUSTER                              -
         (NAME(PROD.CLIENTES.KSDS)            -
          CYLINDERS(20 5)                     -
          RECORDSIZE(200 200)                 -
          INDEXED                             -
          KEYS(8 0)                           -
          FREESPACE(20 10)                    -
          SHAREOPTIONS(2 3))                 -
         DATA                               -
         (NAME(PROD.CLIENTES.KSDS.DATA)      -
          CISZ(4096))                        -
         INDEX                              -
         (NAME(PROD.CLIENTES.KSDS.INDEX)     -
          CISZ(512))
/*
//*
//* STEP 3 — Carrega dados do arquivo sequencial de extração
//*
//STEP3    EXEC PGM=IDCAMS,COND=(8,LT,STEP2)
//SYSPRINT DD SYSOUT=*
//SEQIN    DD DSN=EXTRACAO.CLIENTES.SEQ,DISP=SHR
//VSAMOUT  DD DSN=PROD.CLIENTES.KSDS,DISP=SHR
//SYSIN    DD *
  REPRO INFILE(SEQIN) OUTFILE(VSAMOUT)
/*
//*
//* STEP 4 — Confirma a carga com LISTCAT
//*
//STEP4    EXEC PGM=IDCAMS,COND=(8,LT,STEP3)
//SYSPRINT DD SYSOUT=*
//SYSIN    DD *
  LISTCAT ENTRY(PROD.CLIENTES.KSDS) ALL
/*

9. Recuperação de catálogo corrompido

Embora recuperação de catálogo seja tarefa de sistemas, o programador precisa reconhecer os sintomas e saber quais passos básicos aplicar quando o dataset fica inacessível por problema de catálogo.

Sintomas de problema de catálogo

Mensagem / SituaçãoCausa provável
IEC161I 168-072 — OPEN failed Dataset marcado como aberto no catálogo (crash anterior)
IDC3009I — catalog check error Inconsistência entre catálogo ICF e VVDS
VSAM OPEN RC=160 — catalog not found Alias ausente ou user catalog offline
IDC0551I — entry not found Dataset não catalogado (deletado do catálogo sem deletar dados)

Sequência de diagnóstico

Passo 1 — verificar se o dataset está catalogado
//DIAG1    EXEC PGM=IDCAMS
//SYSPRINT DD SYSOUT=*
//SYSIN    DD *
  LISTCAT ENTRY(PROD.CLIENTES.KSDS) ALL
/*
Passo 2 — se open falhou por dataset "ainda aberto"
//DIAG2    EXEC PGM=IDCAMS
//SYSPRINT DD SYSOUT=*
//SYSIN    DD *
  VERIFY DATASET(PROD.CLIENTES.KSDS)
/*
Passo 3 — recatalogar dataset que saiu do catálogo
/* O dataset existe no disco mas não no catálogo */
//DIAG3    EXEC PGM=IDCAMS
//SYSPRINT DD SYSOUT=*
//SYSIN    DD *
  DEFINE CLUSTER                              -
         (NAME(PROD.CLIENTES.KSDS)            -
          RECATALOG                           -
          VOLUMES(VOL001))
/*
✅ RECATALOG
O parâmetro RECATALOG no DEFINE CLUSTER não cria um novo dataset — ele recria apenas a entrada no catálogo para um dataset que já existe no disco. O VSAM lê o VVDS do volume para recuperar os atributos originais. Use quando o catálogo foi corrompido ou quando um dataset precisa ser registrado num novo catálogo após migração de volume.

10. LISTCAT no catálogo

Além de listar datasets individuais, LISTCAT é a ferramenta principal para navegar na estrutura do catálogo.

LISTCAT — consultas de catálogo
  /* Ver todos os clusters do user catalog UCAT.PROD */
  LISTCAT CATALOG(UCAT.PROD) CLUSTER ALL

  /* Ver todos os aliases no master catalog */
  LISTCAT CATALOG(SYS1.MASTER.ICFCAT) ALIAS

  /* Ver todos os user catalogs */
  LISTCAT CATALOG(SYS1.MASTER.ICFCAT) USERCATALOG

  /* Listar tudo que começa com PROD.CONTAS */
  LISTCAT LEVEL(PROD.CONTAS) ALL

  /* Ver apenas nomes, sem estatísticas */
  LISTCAT LEVEL(PROD) NAME

  /* Ver datasets em um volume específico */
  LISTCAT VOLUME(VOL001) ALL

Saída LISTCAT para USER CATALOG

Saída — LISTCAT USERCATALOG
LISTING OF USERCATALOG --- UCAT.PROD
     IN-CAT --- SYS1.MASTER.ICFCAT
     HISTORY
       DATASET-OWNER--------(NULL)        CREATION--------2025.001
     ALLOCATION
       SPACE-TYPE----------CYLINDER        SPACE-PRI-----------    5
       SPACE-SEC-----------     2
     VOLUME
       VOLSER------------CATVOL            DEVTYPE---------3390
       HI-ALLOC-RBA----  20971520          HI-USED-RBA-----  8388608
🟣 LISTCAT LEVEL vs LISTCAT CATALOG
LISTCAT LEVEL(PROD) lista todos os datasets cujo primeiro qualificador é PROD, consultando o catálogo que cobre esse prefixo (determinado pelo alias). LISTCAT CATALOG(UCAT.PROD) lista tudo que está fisicamente dentro do user catalog, independente do prefixo. Se houver datasets com nomes inesperados catalogados em UCAT.PROD (por erro de configuração de alias), só o segundo comando os revela.

Verificação de integridade do catálogo

IDCAMS — EXAMINE para verificar integridade
  /* Verifica consistência interna do catálogo */
  EXAMINE NAME(UCAT.PROD)                    -
          INDEXTEST                          -
          DATATEST

  /* Verifica um cluster específico */
  EXAMINE NAME(PROD.CLIENTES.KSDS)           -
          INDEXTEST

EXAMINE verifica a integridade estrutural do componente INDEX de um KSDS (árvore B+ corrompida) e a consistência dos registros no DATA. Deve ser executado periodicamente em KSDS críticos de produção — e sempre antes de uma reorganização quando há suspeita de corrupção.

Comando IDCAMSFinalidadeQuando usar
LISTCAT ALLVer atributos e estatísticasDiagnóstico de performance e espaço
VERIFYSincronizar catálogo com discoApós crash de job que escrevia no VSAM
EXAMINEVerificar integridade estruturalSuspeita de corrupção, antes de reorganizar
DEFINE CLUSTER RECATALOGRecriar entrada no catálogoDataset existe no disco mas saiu do catálogo
ALTER NEWNAMERenomear dataset no catálogoMigração, versionamento de datasets