| Bellacosa Mainframe e o idcams criando gdgs |
☕ Um Café no Bellacosa Mainframe
Jimi Dini Entrou no Catálogo — O Dia em que um GDG Criou uma Geração, Sofreu ABEND e Descobriu que IDCAMS Não É Um Curandeiro de Arquivos
Ou: como deixar de chamar todo arquivo com G0001V00 de “backup”, entender por que (+1) pode virar confusão e descobrir que o verdadeiro rock-and-roll do batch é saber o que ficou no catálogo depois do RC=12
Prólogo — a fita cassete que se chamava ontem
Imagine Jimi Dini, uma criatura de camisa de flanela, café frio e paciência limitada para apresentações com setenta slides, entrando na sala de operações às três da manhã. No monitor, um job de fechamento acabou de cair com ABEND. O operador aponta para a tela e decreta:
— Relaxa. O arquivo está no GDG.
Jimi olha para o spool, toma um gole de café e responde:
— “No GDG” quer dizer o quê? Está criado? Catalogado? É a geração ativa? É a de ontem? Está pendurada em deferred roll-in? Ou alguém só viu um G0042V00 no volume e resolveu chamar isso de plano de recuperação?
É aqui que começa a educação sentimental do programador COBOL. GDG não é uma palavra mágica para “backup”; IDCAMS não é uma ambulância que ressuscita dado errado; e o catálogo não é um detalhe administrativo que alguém do storage resolve quando o seu JCL ficou feio. Os três formam uma parte muito importante da segurança operacional do batch.
Vamos desmontar essa história sem misticismo — mas com respeito pelo momento em que um DELETE ... PURGE é digitado no ambiente errado e a sala inteira fica subitamente muito silenciosa.
1. GDG: uma estante, não uma pasta com nome bonito
GDG significa Generation Data Group. É um grupo de datasets relacionados, mantidos em ordem de geração pelo z/OS. Pense numa coleção de edições de jornal: a base é o título da coleção; cada GDS (Generation Data Set) é uma edição física.
Base lógica:
BELLACOSA.FOLHA.RELATORIOGerações físicas que o sistema administra:
BELLACOSA.FOLHA.RELATORIO.G0001V00
BELLACOSA.FOLHA.RELATORIO.G0002V00
BELLACOSA.FOLHA.RELATORIO.G0003V00O sufixo G0003V00 não é um ornamento que você inventa no teclado. Ele é formado pelo sistema: o número da geração e, quando necessário, o número de versão. A grande vantagem aparece quando o programa não precisa conhecer esse nome físico. Ele só pede a edição que precisa.
| Referência no JCL | Tradução humana |
|---|---|
(+1) | “Vou criar a próxima edição.” |
(0) | “Quero a edição mais recente ativa.” |
(-1) | “Quero a imediatamente anterior.” |
(-2) | “Quero a de duas execuções atrás.” |
G0042V00 | “Quero exatamente esta edição física.” |
Para um lote diário de extratos, isto é ouro. O job de hoje cria (+1). O processo de conferência lê (0). Uma rotina de comparação lê (-1). O JCL expressa intenção, não uma data carimbada à mão numa convenção de nomes que um dia alguém vai esquecer de atualizar.
Mas atenção: GDG administra gerações, não prova que o conteúdo está certo. Se o COBOL calculou juros usando uma taxa incorreta, você não possui um backup apenas porque o arquivo se chama G0088V00. Você possui uma versão perfeitamente organizada de um erro.
2. IDCAMS: o cartório do condomínio de datasets
IDCAMS, Access Method Services, é a ferramenta que conversa com o catálogo e administra vários objetos de dados. Ele é famoso entre programadores por criar VSAM, mas chamar IDCAMS de “o programa que cria KSDS” é como chamar um cartório de “o lugar onde se reconhece firma”. Verdadeiro, mas dramaticamente incompleto.
Com IDCAMS, podemos, entre outras coisas:
definir e alterar bases GDG;
listar entradas do catálogo;
criar, apagar e alterar clusters VSAM;
copiar ou carregar dados com
REPRO;trabalhar com índices alternativos;
investigar atributos que o JCL sozinho não torna tão visíveis.
O esqueleto clássico é:
//IDCAMS EXEC PGM=IDCAMS
//SYSPRINT DD SYSOUT=*
//SYSIN DD *
comandos IDCAMS
/*Guarde uma regra de sobrevivência: se IDCAMS voltar com condição diferente de zero, não pare no RC=8. Abra o SYSPRINT. O retorno é o alarme; as mensagens são o laudo médico. Elas costumam revelar se a base já existe, se uma geração possui retenção, se houve problema de autorização RACF ou se o catálogo localizou algo diferente do que você imaginava.
3. Criando a base: antes de nascer a primeira geração
Definir a base GDG não cria um arquivo de negócio. Cria a regra de vida das futuras gerações no catálogo.
//DEFGDG EXEC PGM=IDCAMS
//SYSPRINT DD SYSOUT=*
//SYSIN DD *
DEFINE GENERATIONDATAGROUP -
(NAME(BELLACOSA.FOLHA.RELATORIO) -
LIMIT(7) -
NOEMPTY -
SCRATCH -
NOPURGE)
/*Também é válido escrever DEFINE GDG. Eu, porém, gosto de começar com GENERATIONDATAGROUP: evita que o jovem padawan imagine que está definindo um dataset sequencial. Está definindo a base, a estante e suas regras.
LIMIT(7): quantas edições cabem na estante?
LIMIT determina o número de gerações ativas. Para um job diário, LIMIT(7) pode representar uma semana. Para fechamento mensal, LIMIT(13) costuma cobrir doze meses e o atual. Para uma interface cuja correção pode levar noventa dias, talvez sete seja uma receita para uma conversa desagradável com auditoria.
O limite não deve nascer do folclore — “sempre fizemos 30” —, mas de perguntas concretas: por quantos dias pode ocorrer reprocessamento? Há retenção legal? Quem recupera um arquivo se o parceiro rejeitar a carga depois de duas semanas? Há espaço para isso? Em GDG clássico, o limite pode chegar a 255; um GDG estendido pode suportar até 999, sujeito à política do ambiente.
NOEMPTY: retire o mais antigo, não a banda inteira
Com NOEMPTY, quando chega uma nova geração acima do limite, apenas a mais velha sofre roll-off — deixa de fazer parte da base. É o comportamento normal em processamento contínuo.
Com LIMIT(3), ao criar a quarta geração:
antes: G0001, G0002, G0003
depois: G0002, G0003, G0004EMPTY é outra conversa: quando o limite estoura, todas as gerações existentes saem da base. Há usos específicos para ciclos fechados, mas para relatório diário isso equivale a contratar Jimi Dini para organizar os arquivos e entregar-lhe um lança-chamas. Use NOEMPTY como padrão mental até que alguém explique, por escrito, por que EMPTY é necessário.
SCRATCH, NOSCRATCH, PURGE e NOPURGE: o que acontece quando a geração cai da estante?
Quando uma geração sofre roll-off, ela pode simplesmente deixar a base ou também ser removida do armazenamento:
SCRATCH: remove o dataset físico conforme o processamento aplicável;NOSCRATCH: não o apaga automaticamente; ele pode continuar existindo e, no cenário SMS, ficar recatalogado fora da base como rolled off;NOPURGE: respeita retenção/data de expiração;PURGE: pode ultrapassar essa barreira de retenção.
Para operação comum, NOEMPTY, SCRATCH e NOPURGE são uma combinação honesta: remove somente a geração mais velha, libera espaço e não atropela proteção de retenção. Mas ela exige que seu LIMIT seja correto. Se a empresa precisa manter sessenta dias, LIMIT(7) com SCRATCH não é automação; é descarte programado.
4. O COBOL encontra o JCL: quem faz o quê?
O COBOL não deveria carregar a preocupação com o nome absoluto da geração. Ele abre um DDNAME. O JCL decide o dataset. O catálogo resolve a geração. Esta separação é uma das pequenas elegâncias do mainframe.
JCL que cria uma geração:
//GERAEXTR EXEC PGM=PGMEXTR
//STEPLIB DD DSN=BELLACOSA.LOADLIB,DISP=SHR
//SYSOUT DD SYSOUT=*
//EXTRATO DD DSN=BELLACOSA.BATCH.EXTRATO(+1),
// DISP=(NEW,CATLG,DELETE),
// SPACE=(CYL,(20,10),RLSE),
// DCB=(RECFM=FB,LRECL=200,BLKSIZE=0)No programa:
SELECT ARQ-EXTRATO ASSIGN TO EXTRATO
ORGANIZATION IS SEQUENTIAL
FILE STATUS IS WS-FS-EXTRATO.O programa escreve em EXTRATO. Não precisa saber se virou G0042V00. E isto dá liberdade para a equipe ajustar as regras de infraestrutura sem reescrever lógica de negócio.
Na execução seguinte, o mais novo pode ser lido assim:
//ENTRADA DD DSN=BELLACOSA.BATCH.EXTRATO(0),DISP=SHRE a comparação com o anterior:
//HOJE DD DSN=BELLACOSA.BATCH.EXTRATO(0),DISP=SHR
//ONTEM DD DSN=BELLACOSA.BATCH.EXTRATO(-1),DISP=SHREsse é um ponto em que a vida do iniciante melhora: (+1) é para criar; (0) é a geração ativa mais recente; (-1) é a anterior. Não tente tratar (+1) como “o arquivo de hoje para leitura em qualquer etapa paralela”. O momento do catalogamento e o fluxo do job importam.
5. A cena do crime: job caiu ao criar (+1)
Agora chegamos à pergunta que separa quem decorou sintaxe de quem começa a entender operação.
O job aloca:
BELLACOSA.BATCH.EXTRATO(+1)O z/OS reserva o nome físico, o programa começa a escrever e então acontece um ABEND: um S0C7, falta de espaço, falha de I/O, queda de subsistema ou aquela rotina antiga que decide que o valor HIGH-VALUES é uma proposta de carreira.
Pode sobrar uma geração física criada, por exemplo G0042V00, sem que ela tenha sido incluída como geração ativa na base. Esse é um estado conhecido como deferred roll-in. Na prática, o arquivo pode estar no DASD, mas (0) ainda aponta para a geração anterior.
O primeiro impulso de alguém é executar de novo. Às vezes funciona. Às vezes transforma um incidente simples numa investigação arqueológica.
Primeiro, investigue:
//LISTGDG EXEC PGM=IDCAMS
//SYSPRINT DD SYSOUT=*
//SYSIN DD *
LISTCAT ENT(BELLACOSA.BATCH.EXTRATO) ALL
LISTCAT LVL(BELLACOSA.BATCH.EXTRATO) ALL
/*Depois, leia o spool: JESMSGLG, JESJCL, SYSPRINT e os SYSOUTs do programa. Você quer saber: a geração existe? O conteúdo foi fechado corretamente? O job morreu antes ou depois de gravar? A geração deveria sobreviver? Há outro job dependente em execução?
Se a GDS estiver íntegra e for realmente a geração que deve entrar na base, IDCAMS oferece a correção de catálogo:
//ROLLIN EXEC PGM=IDCAMS
//SYSPRINT DD SYSOUT=*
//SYSIN DD *
ALTER BELLACOSA.BATCH.EXTRATO.G0042V00 ROLLIN
/*O ROLLIN torna a geração ativa no GDG. É a ferramenta certa para a pergunta certa: “a geração existe e está boa, mas não foi associada à base”. Não a use como ritual automático após todo ABEND. Se o programa morreu depois de gravar metade do arquivo, colocar essa geração no GDG é apenas catalogar oficialmente um problema.
6. Reexecutar, corrigir ou recuperar? Três verbos, três decisões
Jimi Dini escreveria isto na parede da sala de controle: não conserte catálogo antes de decidir se o dado merece ser preservado.
Caso A — o conteúdo está correto, mas a geração não entrou
Valide volume, tamanho, quantidade de registros, totais de controle e sinal de término da aplicação. Se tudo estiver íntegro, ALTER ... ROLLIN pode ser a escolha adequada.
Caso B — o conteúdo está errado
Não “edite” a geração em silêncio para fingir que nada ocorreu. Corrija a causa, gere uma nova (+1) e documente o reprocessamento. A beleza do GDG é justamente preservar a sequência. Uma geração nova, correta e auditável costuma ser muito mais defensável que uma cirurgia clandestina na geração anterior.
Caso C — a geração está incompleta ou descartável
Depois de confirmação operacional, a geração física pode precisar ser excluída e o job reexecutado de maneira controlada. Isto não deve ser decidido pelo programador isolado em produção: há scheduler, dependências, retenção, RACF e possíveis consumidores do arquivo.
O vilão frequente é o segundo job disparado antes que o primeiro tenha sido tratado. Em GDS SMS no DASD, o mecanismo de GDS reclaim pode reutilizar uma geração pendente quando outro job tenta criar o mesmo (+1). Isso pode sobrescrever conteúdo anterior. Portanto, interrompa dependentes, entenda o estado e só então rerode.
7. ALTER, LISTCAT, DELETE: ferramentas, não martelos
LISTCAT é sua lanterna:
LISTCAT ENT(BELLACOSA.BATCH.EXTRATO) ALLEle permite enxergar atributos da base, limite e gerações. Use antes de tomar decisão destrutiva.
ALTER ajusta a política:
ALTER BELLACOSA.BATCH.EXTRATO LIMIT(45)Isso aumenta a capacidade futura de retenção. Não traz de volta dados que já sofreram scratch. Também vale lembrar: reduzir limite pode provocar roll-off das gerações mais antigas. Não trate um ALTER LIMIT como ajuste cosmético.
DELETE faz exatamente o que o nome promete:
DELETE BELLACOSA.BATCH.EXTRATO.G0042V00apaga uma geração específica; enquanto:
DELETE BELLACOSA.BATCH.EXTRATO GDGatinge a base GDG. Isso é reconstrução, não manutenção corriqueira. Antes de qualquer DELETE, confirme ambiente, HLQ, entrada de catálogo, volumes e autorização. O personagem que diz “é só um GDG de teste” merece ao menos uma segunda verificação — porque o ambiente de teste costuma ter um nome suspeitosamente parecido com produção numa sexta-feira.
8. VERIFY não é varinha mágica
Outro equívoco comum: ouvir que IDCAMS possui VERIFY e concluir que ele corrige qualquer GDG. Não. VERIFY está ligado à verificação de consistência de estruturas VSAM e catálogo em cenários próprios. Ele não confere se a regra de cálculo do seu COBOL estava correta; não repõe registros faltantes num arquivo sequencial; não transforma uma GDS truncada em extrato válido.
Para GDG, pense assim:
| Sintoma | Ação inicial correta |
|---|---|
| Arquivo lógico aponta para a geração errada | LISTCAT, avaliar estado e ROLLIN se aplicável |
| Geração não existe | Investigar job, retenção, scratch, backup e catálogo |
| Dados têm erro de negócio | Corrigir programa/parâmetro e reprocessar para nova geração |
| Retenção está pequena | ALTER LIMIT, com avaliação de espaço e auditoria |
| Estrutura VSAM está inconsistente | Acionar procedimento VSAM/storage; pode envolver VERIFY |
| Catálogo parece corrompido | Escalar ao storage/system programmer; não recriar base no improviso |
O IDCAMS é excelente, mas não substitui diagnóstico. Ele administra registros de catálogo; seu processo operacional decide o que é dado confiável.
9. Passo a passo do jovem padawan antes de mexer num GDG
Quando um job com GDG falhar, siga este roteiro:
Pare o reflexo de rerodar. Veja se existem dependentes e evite duas tentativas criando o mesmo
(+1).Leia o ABEND e o spool. Descubra a causa, não só o código final.
Liste a base. Use
LISTCAT ENT(nome-da-base) ALL.Identifique a geração física. Ela existe? Está ativa, rolled off ou pendente?
Valide o conteúdo. Totais, contagem, trailer, retorno da aplicação, volume e integridade esperada.
Escolha conscientemente.
ROLLINse a geração boa não entrou; novo(+1)se deve reprocessar; descarte controlado se está incompleta.Registre a decisão. Ticket, evidência de totals e horário da intervenção valem ouro na auditoria.
Libere a cadeia somente após a consistência. O próximo consumidor não deve descobrir o problema por acidente.
10. Curiosidades para contar no café — sem quebrar produção
Uma GDG pode ser muito mais antiga que boa parte do código Java que hoje a consome. E ainda assim ela resolve um problema moderno: versionamento de dados em lote. A diferença é que, no z/OS, esse versionamento está acoplado a catálogo, retenção, JCL, segurança e operação de grandes volumes — não a uma pasta chamada backup_final_agora_vai_3.
Outra curiosidade: o sufixo absoluto existe para quando uma referência precisa ser imutável. Usar (0) é ótimo para “a mais recente”; usar G0042V00 é apropriado quando uma auditoria, reconciliação ou reexecução exige provar que foi aquela geração, e não a que veio depois.
Por fim, GDG não elimina backup, disaster recovery, retenção corporativa ou cópia para fita/cloud. Ele ajuda a manter versões operacionais de datasets. Backup protege contra outra classe de problemas: perda de volume, desastre, corrupção ampla, retenção longa e erros que só foram percebidos quando todas as gerações úteis já saíram da estante.
Epílogo — o som que fica depois do ABEND
No fim da madrugada, Jimi Dini fecha o SYSPRINT, confere o LISTCAT e deixa uma frase para o programador COBOL iniciante:
— O mainframe não é antigo; ele só não confia em improviso.
GDG oferece uma cronologia clara. IDCAMS administra a cronologia no catálogo. JCL declara como cada etapa usa essa cronologia. COBOL processa os registros. Quando algo falha, a resposta madura não é “reroda e vê”. É descobrir o que foi alocado, o que foi catalogado, o que está íntegro e qual ação preserva tanto o negócio quanto a rastreabilidade.
Quando você entende isso, (+1) deixa de ser uma sequência estranha entre parênteses. Ele se torna uma promessa operacional: “esta é a próxima versão do dado; trate-a com o respeito que ela terá quando alguém precisar explicar seu conteúdo daqui a três meses.