☕ Um Café no Bellacosa Mainframe
Gostou do conteúdo? Ajude a manter o café quente, o COBOL compilando e o mainframe acordado. 😄
☕ Pague um café ao Bellacosa

Translate

terça-feira, 13 de agosto de 2019

SORT — O Pelotão que Colocava o Caos em Ordem

Bellacosa Mainframe e a classificacao de datasets via sort

☕ Um Café no Bellacosa Mainframe

SORT — O Pelotão que Colocava o Caos em Ordem

Como DFSORT, ICETOOL, arquivos temporários e algumas linhas de JCL reorganizam milhões de registros enquanto o recruta tenta sobreviver à sua primeira madrugada no CPD

“No batch, ninguém abandona um registro para trás.”

A sala de operações estava quase vazia.

Eram duas e quarenta e sete da manhã quando o recruta recebeu sua primeira missão de verdade. Não era um programa COBOL elegante, não havia tela CICS piscando nem banco de dados esperando um COMMIT.

Havia apenas um arquivo.

Um arquivo enorme.

Milhões de registros de transações, clientes, datas, agências e valores haviam chegado completamente fora de ordem. Alguns registros estavam duplicados. Outros deveriam ser eliminados. Certas colunas precisavam mudar de posição. O departamento financeiro queria um relatório por agência, em ordem de data e valor.

E queria antes das seis da manhã.

O veterano olhou para o recruta como o sargento Elias observando um soldado recém-chegado à selva de Platoon.

— Você sabe usar o SORT?

O jovem respirou fundo.

— Sei colocar em ordem crescente.

O veterano apagou o cigarro imaginário no cinzeiro do CPD.

— Então você ainda não sabe usar o SORT.


1. O que é o SORT no mainframe?

No universo IBM z/OS, quando alguém diz simplesmente SORT, normalmente está falando de uma família de operações capazes de:

  • classificar registros;

  • copiar arquivos;

  • mesclar arquivos previamente ordenados;

  • selecionar ou eliminar registros;

  • remover duplicidades;

  • somar campos numéricos;

  • reformatar registros;

  • criar vários arquivos de saída;

  • gerar relatórios;

  • contar registros;

  • comparar arquivos;

  • cruzar dois datasets por meio de chaves;

  • inserir cabeçalhos e rodapés;

  • converter formatos;

  • criar sequências;

  • procurar e substituir conteúdo.

Na plataforma IBM, a implementação mais conhecida é o DFSORT, produto de alto desempenho destinado a classificação, cópia, mesclagem, análise e geração de relatórios em z/OS. Apesar de seu nome histórico, ele está muito longe de ser apenas um classificador. (IBM)

Dependendo da instalação, também pode existir outro produto compatível, como o Syncsort/MFX. A sintaxe básica costuma ser semelhante, mas opções avançadas, mensagens e comportamentos podem variar.

Por isso, uma das primeiras regras do recruta é:

Antes de copiar um SORT encontrado na internet, descubra qual produto está instalado em seu ambiente.


2. A origem: antes do silício, já existia o problema da ordem

A necessidade de ordenar informações é muito anterior ao computador.

Bibliotecas classificavam livros. Bancos organizavam fichas de clientes. Governos agrupavam registros populacionais. Empresas separavam cartões perfurados por código, região, conta ou data.

Nas antigas instalações de processamento de dados, máquinas classificadoras eletromecânicas liam cartões perfurados e os distribuíam fisicamente em compartimentos. Para ordenar por vários campos, os cartões podiam passar diversas vezes pela máquina.

Primeiro uma coluna.

Depois outra.

Depois outra.

Era uma coreografia mecânica de papel, engrenagens e eletricidade.

Quando os computadores eletrônicos assumiram o processamento comercial, aquela necessidade permaneceu. O suporte mudou — cartões, fitas magnéticas, discos, datasets —, mas a missão continuou a mesma:

Receber dados desordenados e entregá-los na sequência necessária ao processamento seguinte.

Em ambientes batch, a ordenação tornou-se fundamental porque muitos programas foram projetados para trabalhar com arquivos em sequência de chave.

Um programa COBOL poderia, por exemplo:

  1. ler um arquivo de clientes em ordem de número de conta;

  2. ler um arquivo de movimentos na mesma ordem;

  3. comparar as chaves;

  4. aplicar os movimentos ao cliente correspondente;

  5. produzir um novo arquivo mestre.

Sem a classificação prévia, esse casamento sequencial seria caótico.

O SORT tornou-se, portanto, uma espécie de pelotão de logística do mainframe. Ele não aparece na linha de frente das aplicações, mas prepara o terreno para que todo o restante funcione.


3. Anatomia de uma missão SORT

Um passo básico de DFSORT em JCL costuma ter quatro elementos:

//ORDENA   EXEC PGM=SORT
//SYSOUT   DD SYSOUT=*
//SORTIN   DD DSN=VAGNER.ARQUIVO.ENTRADA,DISP=SHR
//SORTOUT  DD DSN=VAGNER.ARQUIVO.SAIDA,
//            DISP=(NEW,CATLG,DELETE),
//            UNIT=SYSDA,
//            SPACE=(CYL,(10,5),RLSE),
//            DCB=(RECFM=FB,LRECL=100,BLKSIZE=0)
//SYSIN    DD *
  SORT FIELDS=(1,10,CH,A)
/*

O papel de cada DD

EXEC PGM=SORT

Executa o utilitário de classificação definido pela instalação.

Em muitos ambientes também aparece:

//ORDENA EXEC PGM=ICEMAN

ICEMAN é um nome tradicionalmente associado ao programa do DFSORT, mas PGM=SORT é mais legível e costuma ser preferido em JCL de aplicação.

SYSOUT

Recebe mensagens produzidas pelo utilitário:

//SYSOUT DD SYSOUT=*

É aqui que o recruta descobrirá:

  • quantos registros foram lidos;

  • quantos foram gravados;

  • quais opções foram utilizadas;

  • se houve alocação dinâmica;

  • qual foi o return code;

  • qual mensagem explica o desastre.

Nunca despreze o SYSOUT.

No campo de batalha do batch, ele é o relatório da patrulha.

SORTIN

É o dataset de entrada:

//SORTIN DD DSN=VAGNER.ARQUIVO.ENTRADA,DISP=SHR

SORTOUT

É o arquivo principal de saída:

//SORTOUT DD DSN=VAGNER.ARQUIVO.SAIDA,...

SYSIN

Contém as instruções de controle:

//SYSIN DD *
  SORT FIELDS=(1,10,CH,A)
/*

É no SYSIN que a missão é descrita.


4. Decifrando SORT FIELDS

Observe:

SORT FIELDS=(1,10,CH,A)

A estrutura é:

posição, tamanho, formato, ordem

Portanto:

1,10,CH,A

significa:

  • começar na posição 1;

  • usar 10 bytes;

  • interpretar como caracteres;

  • ordenar de forma ascendente.

Ordem ascendente e descendente

A = Ascending
D = Descending

Exemplo:

  SORT FIELDS=(1,10,CH,A)

Ordena nomes da posição 1 à 10 em ordem crescente.

  SORT FIELDS=(1,10,CH,D)

Ordena em ordem decrescente.


5. Ordenação com várias chaves

Imagine este layout:

PosiçãoTamanhoCampo
14Agência
58Data AAAAMMDD
1310Número da conta
239Valor
321Tipo

Queremos ordenar:

  1. por agência crescente;

  2. dentro da agência, por data crescente;

  3. dentro da data, por valor decrescente.

//SYSIN DD *
  SORT FIELDS=(1,4,CH,A,
               5,8,CH,A,
               23,9,ZD,D)
/*

O DFSORT aplica as chaves da esquerda para a direita.

É como organizar um pelotão:

  1. primeiro por companhia;

  2. depois por esquadrão;

  3. finalmente por graduação.


6. Os principais formatos de dados

O SORT precisa saber como interpretar os bytes.

A sequência hexadecimal que representa o número 123 em display não é a mesma representação de um campo binário ou packed decimal.

Entre os formatos suportados estão diversos tipos de caracteres, binários e decimais. O formato CH, por exemplo, trata cada caractere segundo seu código EBCDIC. (IBM)

Formatos comuns

CH — Character

1,20,CH,A

Usado para campos alfanuméricos em EBCDIC.

ZD — Zoned Decimal

Muito comum em arquivos originados por COBOL:

05 WS-VALOR PIC 9(9).

No SORT:

23,9,ZD,D

PD — Packed Decimal

Corresponde normalmente a campos COBOL COMP-3.

05 WS-VALOR PIC S9(9)V99 COMP-3.

O tamanho físico não é 11 bytes. Para 11 dígitos, o campo packed ocupa:

(11 + 1) / 2 = 6 bytes

Exemplo:

23,6,PD,D

BI — Binary

Trata o campo como binário sem sinal.

FI — Fixed-point signed

Usado em certos campos binários com sinal.

UFF e SFF

Úteis para números em formato livre, com espaços ou sinais em diferentes posições.


7. A armadilha do recruta: ordenar números como caracteres

Considere:

1
2
10
20
100

Se os valores ocuparem campos de tamanho variável ou não estiverem preenchidos corretamente, uma classificação alfanumérica pode produzir algo semelhante a:

1
10
100
2
20

Isso ocorre porque a comparação está sendo feita byte a byte, como texto.

Para números, use o formato correspondente à representação física real:

  SORT FIELDS=(1,5,ZD,A)

Mas atenção:

Não escolha ZD, PD ou BI pelo significado lógico do campo. Escolha pela forma como ele está fisicamente gravado.

Um valor pode ser conceitualmente numérico e, ainda assim, estar armazenado como caracteres.


8. Como descobrir as posições dos campos

Suponha o copybook:

01 REGISTRO-CLIENTE.
   05 CLI-AGENCIA      PIC X(04).
   05 CLI-CONTA        PIC X(10).
   05 CLI-NOME         PIC X(30).
   05 CLI-SALDO        PIC S9(09)V99 COMP-3.
   05 CLI-STATUS       PIC X(01).

Calculando as posições:

CampoPosiçãoTamanho físico
CLI-AGENCIA14
CLI-CONTA510
CLI-NOME1530
CLI-SALDO456
CLI-STATUS511

Para ordenar por agência, saldo decrescente e conta:

  SORT FIELDS=(1,4,CH,A,
               45,6,PD,D,
               5,10,CH,A)

Regra de ouro

Antes de escrever o SORT:

  1. obtenha o copybook;

  2. confirme o RECFM;

  3. confirme o LRECL;

  4. calcule a posição física;

  5. verifique campos COMP, COMP-3 e redefinições;

  6. confirme se existe RDW em registros variáveis;

  7. examine uma amostra em hexadecimal.

O programador que não olha os dados em hexadecimal está entrando na selva sem mapa.


9. Arquivos FB e VB: a história dos quatro bytes invisíveis

Arquivo FB

Em um dataset RECFM=FB, todos os registros têm tamanho fixo.

Se o LRECL é 100, o primeiro campo começa normalmente na posição 1 do registro lógico.

  SORT FIELDS=(1,10,CH,A)

Arquivo VB

Em um dataset RECFM=VB, cada registro físico começa com um Record Descriptor Word, o famoso RDW.

O RDW ocupa quatro bytes.

Por isso, em muitas instruções DFSORT para arquivos variáveis, os dados começam na posição 5.

Se o campo lógico está no início do registro de aplicação, a chave poderá ser:

  SORT FIELDS=(5,10,CH,A)

Este é um dos erros clássicos de iniciantes.

O recruta vê o copybook dizendo que o campo começa na posição 1 e escreve:

1,10,CH,A

Mas, no contexto do SORT para VB, acaba incluindo os bytes do RDW.

O resultado pode ser:

  • classificação absurda;

  • erro de campo além do registro;

  • comportamento variável;

  • longas horas procurando um problema que estava quatro bytes antes.


10. SORT FIELDS=COPY: quando não queremos classificar

DFSORT também pode apenas copiar registros:

//COPIA    EXEC PGM=SORT
//SYSOUT   DD SYSOUT=*
//SORTIN   DD DSN=VAGNER.CLIENTES,DISP=SHR
//SORTOUT  DD DSN=VAGNER.CLIENTES.COPIA,
//            DISP=(NEW,CATLG,DELETE),
//            SPACE=(CYL,(5,2),RLSE),
//            UNIT=SYSDA,
//            DCB=*.SORTIN
//SYSIN    DD *
  SORT FIELDS=COPY
/*

Também pode ser usado:

OPTION COPY

A cópia parece banal, mas é extremamente poderosa quando combinada com:

  • INCLUDE;

  • OMIT;

  • INREC;

  • OUTREC;

  • OUTFIL;

  • FINDREP;

  • IFTHEN.

É comum usar DFSORT apenas como um transformador de arquivos, sem alterar a ordem.


11. Selecionando registros com INCLUDE

Imagine que o status esteja na posição 51.

Queremos somente clientes ativos:

  INCLUDE COND=(51,1,CH,EQ,C'A')
  SORT FIELDS=COPY

Operadores de comparação

EQ = Equal
NE = Not equal
GT = Greater than
GE = Greater than or equal
LT = Less than
LE = Less than or equal

Exemplo com mais de uma condição

Selecionar:

  • status ativo;

  • saldo maior que zero.

  INCLUDE COND=(51,1,CH,EQ,C'A',AND,
                45,6,PD,GT,+0)
  SORT FIELDS=(1,4,CH,A)

Uso de OR

  INCLUDE COND=(51,1,CH,EQ,C'A',OR,
                51,1,CH,EQ,C'P')
  SORT FIELDS=COPY

Aceita status A ou P.


12. Eliminando registros com OMIT

Se a missão for remover cancelados:

  OMIT COND=(51,1,CH,EQ,C'C')
  SORT FIELDS=COPY

Nunca use INCLUDE e OMIT simultaneamente no mesmo nível de controle. Escolha a lógica mais clara.

Como regra de manutenção:

  • use INCLUDE quando poucos registros devem passar;

  • use OMIT quando poucos registros devem ser descartados.


13. Constantes no SORT

Caracteres

C'ATIVO'

Hexadecimal

X'F1F2F3'

Decimal positivo

+100

Decimal negativo

-50

Exemplo:

  INCLUDE COND=(1,3,CH,EQ,C'BRA')

14. Removendo registros duplicados

Considere um arquivo ordenado por conta.

Queremos manter apenas um registro para cada conta:

  SORT FIELDS=(5,10,CH,A)
  SUM FIELDS=NONE

SUM FIELDS=NONE elimina registros cujas chaves de classificação sejam duplicadas.

Mas há uma pergunta perigosa:

Qual registro duplicado será mantido?

Isso depende das opções de estabilidade e da estratégia utilizada.

Para preservar a ordem relativa original de registros com a mesma chave, pode-se usar:

  OPTION EQUALS
  SORT FIELDS=(5,10,CH,A)
  SUM FIELDS=NONE

EQUALS ajuda a preservar a ordem de entrada entre registros com chaves iguais.

Mesmo assim, não trate a seleção de “primeiro” ou “último” duplicado como acidente. Quando a regra de negócio depende disso, torne-a explícita adicionando uma chave complementar, como data ou timestamp.

Exemplo: manter o movimento mais recente.

  SORT FIELDS=(5,10,CH,A,
               60,14,CH,D)
  SUM FIELDS=NONE

Aqui:

  • conta crescente;

  • timestamp decrescente;

  • o registro mais recente aparece primeiro dentro da conta;

  • os demais duplicados são eliminados.


15. Somando valores com SUM

Suponha:

  • agência: posição 1, tamanho 4;

  • valor packed: posição 45, tamanho 6.

Queremos consolidar o valor total por agência:

  SORT FIELDS=(1,4,CH,A)
  SUM FIELDS=(45,6,PD)

Todos os registros com a mesma chave serão consolidados, e o valor será somado.

É essencial verificar:

  • capacidade do campo de saída;

  • sinal;

  • casas decimais implícitas;

  • possível overflow;

  • existência de outros campos não pertencentes à chave.

Campos não somados poderão vir de um dos registros do grupo. Portanto, não presuma que todo o conteúdo do registro consolidado terá significado lógico.


16. INREC: preparando o soldado antes da batalha

INREC reformata cada registro antes da classificação principal.

O fluxo conceitual é:

Entrada
  ↓
INCLUDE/OMIT
  ↓
INREC
  ↓
SORT ou MERGE
  ↓
SUM
  ↓
OUTREC
  ↓
OUTFIL
  ↓
Saída

A documentação IBM explica que INREC é processado antes de SORT, SUM e OUTREC, mas depois das condições INCLUDE ou OMIT. (IBM)

Exemplo

Arquivo original:

CampoPosiçãoTamanho
Conta110
Nome1130
Agência414
Saldo456

Queremos criar internamente:

Agência + Conta + Saldo
  INREC BUILD=(41,4,
               1,10,
               45,6)
  SORT FIELDS=(1,4,CH,A,
               5,10,CH,A)

Depois do INREC, as posições mudaram.

Agora:

  • agência está em 1;

  • conta está em 5;

  • saldo está em 15.

Uma das maiores fontes de erro é continuar usando no SORT FIELDS as posições do registro original após um INREC.


17. OUTREC: reorganizando depois da classificação

OUTREC reformata os registros depois da operação de ordenação, cópia ou mesclagem. (IBM)

Exemplo:

  SORT FIELDS=(1,4,CH,A)
  OUTREC BUILD=(1,4,
                C'|',
                5,10,
                C'|',
                15,30)

Saída:

0001|1234567890|JOSE DA SILVA
0001|2234567890|MARIA DE SOUZA

Inserindo espaços

  OUTREC BUILD=(10X,1,20,5X,21,10)

A documentação IBM permite inserir áreas em branco com notações como 20X ou 10X. (IBM)

Inserindo texto literal

  OUTREC BUILD=(C'AGENCIA=',1,4,
                C' CONTA=',5,10)

18. OVERLAY: cirurgia em posições específicas

BUILD constrói um novo registro.

OVERLAY altera partes específicas do registro, preservando o restante.

Exemplo: colocar PROCESSADO na posição 80:

  SORT FIELDS=COPY
  OUTREC OVERLAY=(80:C'PROCESSADO')

Exemplo: substituir um status:

  OUTREC IFTHEN=(WHEN=(51,1,CH,EQ,C'A'),
                 OVERLAY=(51:C'X'))

19. IFTHEN: regras condicionais

É possível aplicar transformações diferentes dependendo do conteúdo.

  SORT FIELDS=COPY
  OUTREC IFTHEN=(WHEN=(51,1,CH,EQ,C'A'),
                 OVERLAY=(60:C'CLIENTE ATIVO')),
         IFTHEN=(WHEN=(51,1,CH,EQ,C'I'),
                 OVERLAY=(60:C'CLIENTE INATIVO'))

Cláusulas IFTHEN podem selecionar grupos de registros e aplicar operações como BUILD, OVERLAY ou FINDREP. (IBM)

Outras formas úteis incluem:

WHEN=INIT
WHEN=GROUP
WHEN=ANY
WHEN=NONE

Exemplo com inicialização

  OUTREC IFTHEN=(WHEN=INIT,
                 OVERLAY=(80:C'NAO CLASSIFICADO')),
         IFTHEN=(WHEN=(51,1,CH,EQ,C'A'),
                 OVERLAY=(80:C'ATIVO'))

Primeiro todos recebem NAO CLASSIFICADO. Depois os ativos recebem ATIVO.


20. FINDREP: localizar e substituir

Imagine registros contendo:

SAO PAULO

Queremos trocar por:

SP
  SORT FIELDS=COPY
  OUTREC FINDREP=(IN=C'SAO PAULO',
                  OUT=C'SP')

Também pode substituir várias expressões:

  OUTREC FINDREP=(INOUT=(C'SAO PAULO',C'SP',
                         C'RIO DE JANEIRO',C'RJ',
                         C'MINAS GERAIS',C'MG'))

Use com cuidado em arquivos de layout fixo. Uma substituição que muda o tamanho do conteúdo pode deslocar campos ou alterar o LRECL.


21. OUTFIL: vários destinos em uma única passagem

OUTFIL permite produzir um ou vários arquivos a partir de uma única leitura e de uma única operação principal. A IBM documenta que múltiplas instruções OUTFIL podem gerar diferentes saídas com filtros e reformatações próprias. (IBM)

Imagine um arquivo com status na posição 51.

Queremos:

  • ativos em ATIVOS;

  • inativos em INATIVOS;

  • cancelados em CANCELA.

//ATIVOS   DD DSN=VAGNER.CLIENTES.ATIVOS,
//            DISP=(NEW,CATLG,DELETE),
//            SPACE=(CYL,(5,2),RLSE),
//            UNIT=SYSDA
//INATIVOS DD DSN=VAGNER.CLIENTES.INATIVOS,
//            DISP=(NEW,CATLG,DELETE),
//            SPACE=(CYL,(5,2),RLSE),
//            UNIT=SYSDA
//CANCELA  DD DSN=VAGNER.CLIENTES.CANCELADOS,
//            DISP=(NEW,CATLG,DELETE),
//            SPACE=(CYL,(5,2),RLSE),
//            UNIT=SYSDA
//SYSIN    DD *
  SORT FIELDS=(1,4,CH,A)

  OUTFIL FNAMES=ATIVOS,
         INCLUDE=(51,1,CH,EQ,C'A')

  OUTFIL FNAMES=INATIVOS,
         INCLUDE=(51,1,CH,EQ,C'I')

  OUTFIL FNAMES=CANCELA,
         INCLUDE=(51,1,CH,EQ,C'C')
/*

Isso evita:

  • três leituras do arquivo;

  • três passos distintos;

  • três classificações;

  • consumo desnecessário de CPU e I/O.


22. SAVE: recolhendo quem ficou para trás

Depois de criar saídas específicas, podemos usar SAVE para capturar tudo que não entrou nas anteriores:

  OUTFIL FNAMES=ATIVOS,
         INCLUDE=(51,1,CH,EQ,C'A')

  OUTFIL FNAMES=INATIVOS,
         INCLUDE=(51,1,CH,EQ,C'I')

  OUTFIL FNAMES=OUTROS,
         SAVE

A saída OUTROS funciona como uma rede de segurança.

Em produção, ela é excelente para detectar códigos inesperados.


23. Cabeçalhos, rodapés e relatórios

O DFSORT também pode produzir relatórios.

  SORT FIELDS=(1,4,CH,A)

  OUTFIL FNAMES=RELATOR,
         HEADER1=(C'RELATORIO DE CLIENTES'),
         HEADER2=(C'AGENCIA   CONTA       NOME'),
         TRAILER1=(C'FIM DO RELATORIO')

É possível usar recursos como:

DATE
TIME
PAGE
COUNT
TOT
MIN
MAX
AVG

Exemplo conceitual:

  OUTFIL FNAMES=RELATOR,
         HEADER1=(C'RELATORIO DIARIO - ',DATE),
         TRAILER1=(C'TOTAL DE REGISTROS: ',COUNT)

A sintaxe exata pode variar conforme o tipo de relatório e a edição desejada.


24. MERGE: unindo pelotões já organizados

Se dois ou mais arquivos já estiverem classificados pela mesma chave, podemos mesclá-los sem realizar uma nova classificação completa.

//JUNTA    EXEC PGM=SORT
//SYSOUT   DD SYSOUT=*
//SORTIN01 DD DSN=VAGNER.MOVIMENTO.DIA1,DISP=SHR
//SORTIN02 DD DSN=VAGNER.MOVIMENTO.DIA2,DISP=SHR
//SORTOUT  DD DSN=VAGNER.MOVIMENTO.CONSOLIDADO,
//            DISP=(NEW,CATLG,DELETE),
//            SPACE=(CYL,(20,10),RLSE),
//            UNIT=SYSDA
//SYSIN    DD *
  MERGE FIELDS=(1,10,CH,A)
/*

Os arquivos de entrada precisam estar previamente ordenados pela chave especificada.

Não use MERGE esperando que ele conserte arquivos desordenados.


25. JOINKEYS: quando dois arquivos precisam se encontrar

JOINKEYS permite combinar registros de dois datasets por uma ou mais chaves.

É semelhante ao conceito de JOIN em SQL.

A IBM documenta suporte a combinações equivalentes a:

  • inner join;

  • left outer join;

  • right outer join;

  • full outer join;

  • registros pareados;

  • registros não pareados.

Os arquivos podem ter formatos e comprimentos diferentes. (IBM)

Exemplo: clientes e movimentos

Arquivo F1 — clientes

PosiçãoCampo
1–10Conta
11–40Nome

Arquivo F2 — movimentos

PosiçãoCampo
1–10Conta
11–18Data
19–27Valor
//CRUZA    EXEC PGM=SORT
//SYSOUT   DD SYSOUT=*
//SORTJNF1 DD DSN=VAGNER.CLIENTES,DISP=SHR
//SORTJNF2 DD DSN=VAGNER.MOVIMENTOS,DISP=SHR
//SORTOUT  DD DSN=VAGNER.CLIENTE.MOVIMENTO,
//            DISP=(NEW,CATLG,DELETE),
//            SPACE=(CYL,(10,5),RLSE),
//            UNIT=SYSDA
//SYSIN    DD *
  JOINKEYS FILE=F1,FIELDS=(1,10,A)
  JOINKEYS FILE=F2,FIELDS=(1,10,A)

  REFORMAT FIELDS=(F1:1,40,
                   F2:11,17)

  SORT FIELDS=COPY
/*

O resultado contém:

  • dados do cliente;

  • data e valor do movimento correspondente.

Apenas registros correspondentes

Esse é o comportamento básico de um inner join.

Registros sem correspondência

Para incluir não pareados:

  JOIN UNPAIRED,F1,F2

Para identificar a origem, pode-se usar um indicador na reformatação:

  REFORMAT FIELDS=(F1:1,40,
                   F2:11,17,
                   ?)

O caractere indicador ajuda a distinguir:

  • registros encontrados nos dois lados;

  • apenas no F1;

  • apenas no F2.


26. Arquivos temporários no JCL

Um dataset temporário existe somente durante a execução do job.

Seu nome começa com &&.

Exemplo:

//TEMP1 DD DSN=&&CLIENTES,
//         DISP=(NEW,PASS),
//         UNIT=SYSDA,
//         SPACE=(CYL,(10,5)),
//         DCB=(RECFM=FB,LRECL=80,BLKSIZE=0)

&&CLIENTES

É um nome temporário.

O sistema cria um nome interno para o dataset, que será removido ao final do job.

DISP=(NEW,PASS)

  • NEW: o dataset será criado;

  • PASS: se o passo terminar adequadamente, o dataset será passado para um passo seguinte.

Exemplo completo com dois passos

No primeiro passo, selecionamos clientes ativos.

No segundo, classificamos por agência.

//FILTRA   EXEC PGM=SORT
//SYSOUT   DD SYSOUT=*
//SORTIN   DD DSN=VAGNER.CLIENTES.MESTRE,DISP=SHR
//SORTOUT  DD DSN=&&ATIVOS,
//            DISP=(NEW,PASS),
//            UNIT=SYSDA,
//            SPACE=(CYL,(10,5)),
//            DCB=(RECFM=FB,LRECL=100,BLKSIZE=0)
//SYSIN    DD *
  INCLUDE COND=(51,1,CH,EQ,C'A')
  SORT FIELDS=COPY
/*
//ORDENA   EXEC PGM=SORT
//SYSOUT   DD SYSOUT=*
//SORTIN   DD DSN=&&ATIVOS,DISP=(OLD,DELETE)
//SORTOUT  DD DSN=VAGNER.CLIENTES.ATIVOS.ORD,
//            DISP=(NEW,CATLG,DELETE),
//            UNIT=SYSDA,
//            SPACE=(CYL,(10,5),RLSE),
//            DCB=(RECFM=FB,LRECL=100,BLKSIZE=0)
//SYSIN    DD *
  SORT FIELDS=(1,4,CH,A,
               15,30,CH,A)
/*

No segundo passo:

DISP=(OLD,DELETE)

indica que o arquivo será utilizado e removido depois.

Mas o veterano perguntaria:

— Por que dois passos?

A mesma operação poderia ser feita em um:

  INCLUDE COND=(51,1,CH,EQ,C'A')
  SORT FIELDS=(1,4,CH,A,
               15,30,CH,A)

Arquivos temporários são úteis, mas não devem substituir uma boa análise.

Use-os quando:

  • o resultado intermediário será utilizado por vários passos;

  • a separação facilita recuperação e restart;

  • existe necessidade operacional de inspeção;

  • diferentes utilitários precisam consumir o resultado;

  • o processo requer checkpoints;

  • a transformação não pode ser feita em uma única operação.


27. SORTWKnn: a trilha de suprimentos

Durante uma classificação, o DFSORT pode precisar de espaço de trabalho.

Quando os dados não cabem integralmente nas estruturas internas disponíveis, partes intermediárias são gravadas em work datasets.

Esses arquivos costumam ter DD names como:

SORTWK01
SORTWK02
SORTWK03
...

Exemplo de alocação manual:

//SORTWK01 DD UNIT=SYSDA,SPACE=(CYL,(500,100))
//SORTWK02 DD UNIT=SYSDA,SPACE=(CYL,(500,100))
//SORTWK03 DD UNIT=SYSDA,SPACE=(CYL,(500,100))
//SORTWK04 DD UNIT=SYSDA,SPACE=(CYL,(500,100))

Alocação manual ou dinâmica?

Em instalações modernas, frequentemente é melhor permitir que o DFSORT faça a alocação dinâmica.

A IBM afirma que a alocação dinâmica pode ajustar automaticamente o espaço de trabalho às características reais da aplicação, enquanto uma alocação fixa em JCL não pode ser ajustada pelo DFSORT e pode desperdiçar espaço. (IBM)

Portanto, evite copiar cegamente dezenas de SORTWKnn de um JCL antigo.

Talvez aquelas linhas tenham sido necessárias vinte anos atrás.

Talvez hoje estejam apenas ocupando espaço, limitando a otimização ou confundindo o diagnóstico.

Quando especificar manualmente?

Pode fazer sentido quando:

  • a instalação exige volumes específicos;

  • existe política local de storage;

  • o SORT não consegue estimar corretamente a entrada;

  • a alocação dinâmica está desabilitada;

  • há necessidade de isolar workloads;

  • o job apresenta falhas recorrentes de espaço;

  • a equipe de storage ou performance recomendou explicitamente.

Não direcione automaticamente SORTWKnn para VIO. A IBM recomenda evitar VIO para datasets temporários de trabalho do DFSORT e considerar os mecanismos próprios de memória e Hipersorting. (IBM)


28. Como o SORT trabalha com grandes datasets

Imagine um arquivo de 500 milhões de registros.

O DFSORT não precisa necessariamente carregar tudo em uma única área convencional e então “apertar um botão”.

Conceitualmente, uma classificação externa pode envolver:

  1. leitura de blocos da entrada;

  2. criação de sequências ordenadas intermediárias;

  3. uso de memória e áreas de trabalho;

  4. gravação de runs intermediários;

  5. intercalação dessas sequências;

  6. produção da saída final.

As implementações modernas usam diversas otimizações internas. O DFSORT pode explorar recursos como:

  • armazenamento virtual;

  • objetos de memória de 64 bits;

  • data spaces;

  • Hiperspace;

  • buffers;

  • leitura e escrita em blocos;

  • alocação dinâmica de work files;

  • estimativa do tamanho da entrada.

A IBM documenta que o DFSORT pode selecionar modos que usam objetos de memória em armazenamento virtual de 64 bits, além de outras estratégias para otimizar a classificação. (IBM)

O programador de aplicação não deve tentar adivinhar todo o algoritmo interno.

Mas precisa fornecer informações corretas.


29. Como ajudar o SORT em arquivos gigantes

29.1 Informe corretamente os atributos

Confirme:

  • RECFM;

  • LRECL;

  • tamanho estimado;

  • quantidade de registros;

  • tipo de dispositivo;

  • compressão;

  • organização;

  • concatenações;

  • entrada em fita ou disco.

29.2 Filtre o mais cedo possível

Se apenas 5% dos registros interessam, use INCLUDE antes da classificação:

  INCLUDE COND=(51,1,CH,EQ,C'A')
  SORT FIELDS=(1,10,CH,A)

Não classifique 500 milhões de registros para depois descartar 475 milhões.

29.3 Reduza o tamanho do registro antes de ordenar

Se a entrada possui 2.000 bytes, mas a classificação precisa de apenas 40, use INREC para reduzir o registro temporário:

  INREC BUILD=(1,10,
               500,8,
               1500,22)
  SORT FIELDS=(1,10,CH,A)

Menos bytes significam potencialmente:

  • menos memória;

  • menos I/O;

  • menos espaço de trabalho;

  • menos tempo de transferência;

  • menos espaço de saída intermediária.

Mas lembre-se de reconstruir o formato necessário, caso a saída precise do registro original.

29.4 Evite passos desnecessários

Ruim:

Passo 1: copiar
Passo 2: filtrar
Passo 3: ordenar
Passo 4: separar saídas
Passo 5: gerar relatório

Talvez tudo possa ser feito em um passo com:

INCLUDE
SORT
OUTREC
OUTFIL

29.5 Use MERGE quando as entradas já estiverem ordenadas

Não reordene dois arquivos gigantes se ambos já estiverem na sequência correta.

29.6 Use OUTFIL para múltiplas saídas

Evite reler o mesmo arquivo várias vezes.

29.7 Verifique a chave

Ordenar por 200 bytes quando a chave real ocupa 10 bytes aumenta o trabalho sem necessidade.

29.8 Não use parâmetros misteriosos sem medir

Parâmetros de memória, alocação e performance dependem:

  • da versão;

  • do volume;

  • da instalação;

  • do WLM;

  • do storage;

  • das opções padronizadas;

  • da concorrência;

  • do horário.

O parâmetro que salvou um job em 2009 pode degradar outro em 2026.


30. Tipos de classificação

30.1 Ascendente

  SORT FIELDS=(1,10,CH,A)

30.2 Descendente

  SORT FIELDS=(1,10,CH,D)

30.3 Alfanumérica

  SORT FIELDS=(1,20,CH,A)

A ordem segue a representação e as regras de comparação aplicáveis, normalmente baseadas em EBCDIC para CH.

Não espere automaticamente a mesma ordem de um PC em ASCII.

30.4 Numérica display

  SORT FIELDS=(1,9,ZD,A)

30.5 Packed decimal

  SORT FIELDS=(1,6,PD,D)

30.6 Binária

  SORT FIELDS=(1,4,BI,A)

30.7 Múltiplas chaves

  SORT FIELDS=(1,4,CH,A,
               5,8,CH,D,
               13,6,PD,D)

30.8 Estável

  OPTION EQUALS

Mantém a ordem relativa dos registros com chaves iguais, dentro das regras da operação.

30.9 Não estável

  OPTION NOEQUALS

Pode permitir estratégias diferentes para registros com chaves iguais. Não dependa da ordem relativa nesse caso.

30.10 Com sequência alternativa

O SORT pode trabalhar com tabelas de tradução ou sequências de comparação específicas, conforme recursos e opções do ambiente.


31. Criando um número sequencial

É possível adicionar uma sequência aos registros:

  SORT FIELDS=(1,10,CH,A)
  OUTREC BUILD=(SEQNUM,8,ZD,
                1,100)

Saída:

00000001...
00000002...
00000003...

Também podemos usar reinicialização por grupo em construções mais avançadas com WHEN=GROUP.


32. Agrupando registros

Considere:

HCLIENTE001
DTRANSACAO1
DTRANSACAO2
T00000002
HCLIENTE002
DTRANSACAO1
T00000001

Temos:

  • H: header;

  • D: detail;

  • T: trailer.

Com recursos de agrupamento, é possível propagar dados do header para os detalhes, numerar grupos e tratar conjuntos relacionados.

Exemplo conceitual:

  INREC IFTHEN=(WHEN=GROUP,
                BEGIN=(1,1,CH,EQ,C'H'),
                PUSH=(81:ID=4))

Cada grupo recebe uma identificação.

Recursos de WHEN=GROUP são extremamente poderosos para arquivos hierárquicos, mas precisam ser testados com:

  • grupo sem trailer;

  • detalhe sem header;

  • dois headers consecutivos;

  • grupo vazio;

  • último grupo incompleto.


33. Preservando header e trailer com ICETOOL DATASORT

Às vezes o arquivo possui:

HEADER
DADOS
DADOS
DADOS
TRAILER

Queremos ordenar apenas os dados, mantendo o header no início e o trailer no final.

O operador DATASORT do ICETOOL foi criado justamente para classificar os registros de dados preservando registros de cabeçalho e rodapé. A IBM informa que esse operador usa EQUALS para manter a ordem relativa dos duplicados. (IBM)

Exemplo:

//TOOL     EXEC PGM=ICETOOL
//TOOLMSG  DD SYSOUT=*
//DFSMSG   DD SYSOUT=*
//IN       DD DSN=VAGNER.ARQUIVO.COMPLETO,DISP=SHR
//OUT      DD DSN=VAGNER.ARQUIVO.ORDENADO,
//            DISP=(NEW,CATLG,DELETE),
//            UNIT=SYSDA,
//            SPACE=(CYL,(10,5),RLSE)
//TOOLIN   DD *
  DATASORT FROM(IN) TO(OUT) HEADER TRAILER USING(CTL1)
/*
//CTL1CNTL DD *
  SORT FIELDS=(1,10,CH,A)
/*

34. ICETOOL: o canivete de campanha

ICETOOL é um utilitário multifuncional baseado nas capacidades do DFSORT e capaz de executar múltiplas operações em um único passo. (IBM)

O JCL básico:

//TOOL     EXEC PGM=ICETOOL
//TOOLMSG  DD SYSOUT=*
//DFSMSG   DD SYSOUT=*
//ENTRADA  DD DSN=VAGNER.ARQUIVO,DISP=SHR
//TOOLIN   DD *
  ...
/*

Operadores comuns

COPY

Copia dados.

SORT

Classifica dados.

COUNT

Conta registros.

SELECT

Seleciona registros por ocorrência de chave.

UNIQUE

Mostra chaves únicas ou conta ocorrências, conforme construção utilizada.

OCCUR

Produz estatísticas de ocorrência.

DISPLAY

Gera relatórios formatados.

VERIFY

Verifica campos numéricos.

STATS

Produz estatísticas de campos numéricos.

RANGE

Seleciona valores dentro ou fora de intervalos.

SUBSET

Seleciona partes do arquivo.

DATASORT

Ordena dados preservando headers e trailers.


35. Contando registros com ICETOOL

//TOOL     EXEC PGM=ICETOOL
//TOOLMSG  DD SYSOUT=*
//DFSMSG   DD SYSOUT=*
//ENTRADA  DD DSN=VAGNER.CLIENTES,DISP=SHR
//TOOLIN   DD *
  COUNT FROM(ENTRADA)
/*

Também podemos testar condições.

Exemplo conceitual:

  COUNT FROM(ENTRADA) EMPTY RC8

Se o arquivo estiver vazio, retorna RC 8.

Isso permite controlar passos posteriores com JCL:

//PROXIMO IF (TOOL.RC = 0) THEN
...
//        ENDIF

Os return codes do ICETOOL podem representar tanto erros quanto condições programadas por operadores como COUNT. (IBM)


36. Selecionando duplicados com ICETOOL

Suponha que a conta esteja em 1–10.

Para selecionar chaves que aparecem mais de uma vez:

//TOOL     EXEC PGM=ICETOOL
//TOOLMSG  DD SYSOUT=*
//DFSMSG   DD SYSOUT=*
//IN       DD DSN=VAGNER.CONTAS,DISP=SHR
//DUP      DD DSN=VAGNER.CONTAS.DUPLICADAS,
//            DISP=(NEW,CATLG,DELETE),
//            UNIT=SYSDA,
//            SPACE=(CYL,(5,2),RLSE)
//TOOLIN   DD *
  SELECT FROM(IN) TO(DUP) ON(1,10,CH) ALLDUPS
/*

Outras possibilidades podem selecionar:

  • primeira ocorrência;

  • última ocorrência;

  • valores que aparecem exatamente n vezes;

  • valores acima ou abaixo de determinada frequência;

  • registros únicos.

O operador SELECT utiliza classificação e pode preservar a ordem dos duplicados por meio de EQUALS. (IBM)


37. Validando campos numéricos

Antes de somar um campo packed ou zoned, convém verificar se os dados são válidos.

Um byte inválido pode derrubar a operação ou produzir resultado incorreto.

Com ICETOOL, pode-se utilizar VERIFY.

Exemplo conceitual:

  VERIFY FROM(IN) ON(45,6,PD)

Essa é uma excelente missão preventiva antes de processar arquivos vindos de:

  • plataformas distribuídas;

  • conversões ASCII/EBCDIC;

  • uploads manuais;

  • arquivos construídos por scripts;

  • parceiros externos;

  • layouts alterados sem controle.


38. Ordenando datas

Data no formato AAAAMMDD

Se o campo possui:

20260730
20251201
20270115

pode ser ordenado como CH ou ZD, desde que esteja consistentemente preenchido:

  SORT FIELDS=(1,8,CH,A)

O formato AAAAMMDD foi praticamente feito para ordenação lexicográfica.

Data DDMMYYYY

Considere:

30122025
01012026
15072024

Ordenar diretamente como texto não produz ordem cronológica.

Podemos ordenar por:

  1. ano;

  2. mês;

  3. dia.

  SORT FIELDS=(5,4,CH,A,
               3,2,CH,A,
               1,2,CH,A)

Ou criar uma chave temporária com INREC.

  INREC BUILD=(5,4,
               3,2,
               1,2,
               1,80)
  SORT FIELDS=(1,8,CH,A)
  OUTREC BUILD=(9,80)

A chave AAAAMMDD é acrescentada antes do registro, utilizada no SORT e removida na saída.

Esse truque é um clássico.


39. Ordenação case-insensitive

Em EBCDIC, letras maiúsculas e minúsculas possuem valores diferentes.

Uma lista com:

ANA
Ana
ana
BRUNO
Bruno

pode não ficar na ordem humana esperada.

Uma abordagem é criar uma chave temporária convertida para maiúsculas, ordenar por ela e depois remover a chave.

Exemplo conceitual:

  INREC BUILD=(1,30,TRAN=LTOU,
               1,100)
  SORT FIELDS=(1,30,CH,A)
  OUTREC BUILD=(31,100)

TRAN=LTOU transforma letras minúsculas em maiúsculas na chave de trabalho.


40. Concatenando vários arquivos de entrada

É possível concatenar datasets no SORTIN:

//SORTIN DD DSN=VAGNER.ARQ.JANEIRO,DISP=SHR
//       DD DSN=VAGNER.ARQ.FEVEREIRO,DISP=SHR
//       DD DSN=VAGNER.ARQ.MARCO,DISP=SHR

O SORT enxerga a concatenação como um fluxo de entrada.

Mas os datasets precisam ser compatíveis:

  • organização adequada;

  • atributos compatíveis;

  • layouts coerentes;

  • interpretação correta do registro.

Não concatene arquivos apenas porque possuem o mesmo LRECL.

Dois arquivos de 100 bytes podem ter layouts completamente diferentes.


41. Usando GDG

SORT e GDG formam uma dupla clássica.

//SORTIN DD DSN=VAGNER.MOVIMENTO.DIARIO(0),DISP=SHR
//SORTOUT DD DSN=VAGNER.MOVIMENTO.ORDENADO(+1),
//            DISP=(NEW,CATLG,DELETE),
//            SPACE=(CYL,(20,10),RLSE),
//            UNIT=SYSDA

Cuidados:

  • (0) refere-se normalmente à geração atual catalogada;

  • (+1) cria uma nova geração;

  • confirme o momento de catalogação;

  • lembre-se de que referências relativas podem assumir significado diferente conforme novas gerações são criadas no mesmo job.

Em jobs complexos, utilizar o mesmo (+1) em passos posteriores exige conhecimento preciso das regras de resolução do GDG.


42. Usando SORT com VSAM

DFSORT pode trabalhar com diferentes tipos de entrada e saída, inclusive VSAM em cenários suportados.

Mas o recruta deve tomar cuidado com:

  • organização do cluster;

  • chave VSAM;

  • REUSE;

  • abertura para entrada e saída;

  • tentativa de usar o mesmo cluster simultaneamente;

  • tamanho máximo e médio do registro;

  • arquivos variáveis;

  • códigos de retorno;

  • necessidade de descarregar e recarregar o cluster.

A própria documentação alerta que determinadas combinações de mesmo dataset VSAM como entrada e saída exigem condições específicas; caso contrário, o DFSORT encerra a operação. (IBM)

Em muitos processos, é mais seguro:

  1. descarregar;

  2. transformar;

  3. validar;

  4. carregar em novo cluster;

  5. trocar nomes ou executar procedimento controlado de substituição.


43. Return codes: o boletim da missão

Os códigos exatos devem ser confirmados pelas mensagens do produto e pelos padrões da instalação.

Como regra prática:

RC 0

Operação concluída normalmente.

RC 4

Aviso ou condição não fatal.

Pode indicar, por exemplo:

  • situação informativa;

  • condição programada;

  • comportamento que exige atenção.

RC 8 ou superior

Normalmente indica falha ou condição relevante.

Mas nunca interprete apenas o número.

Leia as mensagens:

ICE...

A mensagem detalhada é mais importante que o return code isolado.

O return code diz que alguém caiu. A mensagem diz onde estava a emboscada.


44. Erros clássicos do recruta

44.1 Posição errada

SORT FIELDS=(10,5,CH,A)

Mas o campo realmente começa em 11.

44.2 Esquecer o RDW em arquivo VB

Usa posição 1 quando deveria considerar a posição 5.

44.3 Tratar packed como texto

SORT FIELDS=(45,6,CH,A)

quando deveria ser:

SORT FIELDS=(45,6,PD,A)

44.4 Confundir tamanho lógico com tamanho físico

PIC S9(9)V99 COMP-3 não ocupa 11 bytes.

44.5 Usar posição original após INREC

O INREC muda o mapa do terreno.

44.6 Usar posição reformada antes do momento correto

Cada comando enxerga o registro em uma etapa específica.

44.7 Eliminar duplicados sem definir qual registro manter

SUM FIELDS=NONE não conhece a regra de negócio.

44.8 Sortear um arquivo que já estava ordenado

Talvez MERGE, COPY ou nenhuma operação fosse necessária.

44.9 Criar cinco passos quando um OUTFIL bastava

Mais passos significam:

  • mais I/O;

  • mais datasets;

  • mais pontos de falha;

  • mais JCL;

  • mais dificuldade de restart.

44.10 Esquecer registros vazios ou curtos em VB

Campos além do tamanho efetivo do registro podem causar problemas.

44.11 Confiar na ordem visual

Dados exibidos no ISPF podem esconder:

  • bytes não imprimíveis;

  • sinais packed;

  • zeros;

  • caracteres especiais;

  • diferenças entre espaço e low-value.

44.12 Ignorar a codificação

ASCII e EBCDIC não possuem a mesma sequência de caracteres.


45. Método passo a passo para escrever um SORT seguro

Passo 1 — Defina a missão

Escreva em português claro:

“Ler o arquivo de movimentos, selecionar transações aprovadas, ordenar por agência e conta, consolidar valores e produzir arquivos separados por região.”

Se você não consegue explicar a missão, ainda não está pronto para escrever o SYSIN.

Passo 2 — Obtenha o layout

Consulte:

  • copybook;

  • documentação;

  • amostra;

  • atributos do dataset;

  • origem do arquivo.

Passo 3 — Faça uma tabela de posições

CampoInícioTamanhoFormato
Agência14CH
Conta510CH
Data158CH
Valor236PD
Status291CH

Passo 4 — Examine dados reais

Use:

  • ISPF Browse;

  • modo hexadecimal;

  • File-AID ou ferramenta equivalente;

  • pequeno unload;

  • ICETOOL DISPLAY;

  • programa de diagnóstico.

Passo 5 — Faça primeiro uma amostra

Não comece testando com 500 milhões de registros.

Crie um dataset pequeno contendo:

  • menor chave;

  • maior chave;

  • duplicados;

  • valor zero;

  • valor negativo;

  • registro inválido;

  • status desconhecido;

  • primeiro e último grupo;

  • caracteres especiais.

Passo 6 — Escreva a operação mínima

Comece:

SORT FIELDS=COPY

Depois acrescente:

INCLUDE
INREC
SORT
SUM
OUTREC
OUTFIL

uma camada por vez.

Passo 7 — Valide contagens

Compare:

LIDOS
- DESCARTADOS
= GRAVADOS

Em múltiplas saídas:

ATIVOS + INATIVOS + CANCELADOS + REJEITADOS
= TOTAL DE ENTRADA

Passo 8 — Confirme a ordem

Verifique:

  • primeira chave;

  • última chave;

  • transição entre grupos;

  • duplicados;

  • chaves negativas ou especiais;

  • dados nulos ou espaços.

Passo 9 — Leia todas as mensagens

Não aceite apenas “RC=0”.

Veja:

  • opções usadas;

  • quantidade de registros;

  • alocação;

  • avisos;

  • mensagens de performance;

  • possíveis overrides da instalação.

As opções padrão podem ser alteradas pelos administradores do ambiente, portanto dois sistemas podem executar o mesmo JCL com defaults diferentes. (IBM)

Passo 10 — Documente a regra

Inclua comentários:

//* ORDENA MOVIMENTOS POR AGENCIA, CONTA E DATA
//* MANTEM O MOVIMENTO MAIS RECENTE POR CONTA
//* CAMPO DATA: POS 15, 8 BYTES, AAAAMMDD

O comentário de hoje é o mapa que salvará o recruta de amanhã.


46. Exemplo completo de produção

Missão

Ler movimentos bancários com layout FB de 80 bytes:

CampoPosiçãoTamanhoFormato
Agência14CH
Conta510CH
Data158CH
Hora236CH
Tipo291CH
Valor306PD
Status361CH
Restante3744CH

Requisitos:

  1. aceitar apenas status A;

  2. ordenar por agência e conta;

  3. dentro da conta, colocar data e hora mais recentes primeiro;

  4. criar saída de crédito;

  5. criar saída de débito;

  6. criar saída para tipos desconhecidos;

  7. adicionar data de processamento;

  8. produzir contagem no rodapé.

//MOVSORT  JOB (ACCT),'BELLACOSA',
//             CLASS=A,MSGCLASS=X,NOTIFY=&SYSUID
//*
//* PLATOON DO BATCH - CLASSIFICACAO DE MOVIMENTOS
//*
//ORDENA   EXEC PGM=SORT
//SYSOUT   DD SYSOUT=*
//SORTIN   DD DSN=VAGNER.MOVIMENTO.BRUTO,DISP=SHR
//*
//CREDITO  DD DSN=VAGNER.MOVIMENTO.CREDITO,
//            DISP=(NEW,CATLG,DELETE),
//            UNIT=SYSDA,
//            SPACE=(CYL,(50,20),RLSE),
//            DCB=(RECFM=FB,LRECL=110,BLKSIZE=0)
//*
//DEBITO   DD DSN=VAGNER.MOVIMENTO.DEBITO,
//            DISP=(NEW,CATLG,DELETE),
//            UNIT=SYSDA,
//            SPACE=(CYL,(50,20),RLSE),
//            DCB=(RECFM=FB,LRECL=110,BLKSIZE=0)
//*
//REJEITA  DD DSN=VAGNER.MOVIMENTO.REJEITADO,
//            DISP=(NEW,CATLG,DELETE),
//            UNIT=SYSDA,
//            SPACE=(CYL,(10,5),RLSE),
//            DCB=(RECFM=FB,LRECL=110,BLKSIZE=0)
//*
//SYSIN    DD *
  INCLUDE COND=(36,1,CH,EQ,C'A')

  SORT FIELDS=(1,4,CH,A,
               5,10,CH,A,
               15,8,CH,D,
               23,6,CH,D)

  OUTREC BUILD=(1,80,
                C' PROC=',
                DATE1,
                C' ',
                TIME1)

  OUTFIL FNAMES=CREDITO,
         INCLUDE=(29,1,CH,EQ,C'C'),
         TRAILER1=(C'TOTAL CREDITOS: ',COUNT)

  OUTFIL FNAMES=DEBITO,
         INCLUDE=(29,1,CH,EQ,C'D'),
         TRAILER1=(C'TOTAL DEBITOS: ',COUNT)

  OUTFIL FNAMES=REJEITA,
         SAVE,
         TRAILER1=(C'TOTAL REJEITADOS: ',COUNT)
/*

Este exemplo precisa ser adaptado aos padrões locais, especialmente:

  • sintaxe de data e hora desejada;

  • LRECL final;

  • formato dos trailers;

  • atributos de saída;

  • regras de negócio;

  • quantidade estimada de espaço;

  • produto SORT instalado.


47. Exemplo com dataset temporário e restart lógico

Imagine um job em três etapas:

  1. selecionar e normalizar;

  2. cruzar com cadastro;

  3. gerar relatórios.

//PREPARA  EXEC PGM=SORT
//SYSOUT   DD SYSOUT=*
//SORTIN   DD DSN=VAGNER.TRANSACOES.BRUTAS,DISP=SHR
//SORTOUT  DD DSN=&&NORMAL,
//            DISP=(NEW,PASS),
//            UNIT=SYSDA,
//            SPACE=(CYL,(100,50)),
//            DCB=(RECFM=FB,LRECL=60,BLKSIZE=0)
//SYSIN    DD *
  INCLUDE COND=(100,1,CH,EQ,C'A')

  INREC BUILD=(1,10,
               20,8,
               50,6,
               120,35,
               C'N')
               
  SORT FIELDS=(1,10,CH,A)
/*
//*
//CRUZA    EXEC PGM=SORT
//SYSOUT   DD SYSOUT=*
//SORTJNF1 DD DSN=&&NORMAL,DISP=(OLD,DELETE)
//SORTJNF2 DD DSN=VAGNER.CLIENTES.MESTRE,DISP=SHR
//SORTOUT  DD DSN=&&CRUZADO,
//            DISP=(NEW,PASS),
//            UNIT=SYSDA,
//            SPACE=(CYL,(100,50)),
//            DCB=(RECFM=FB,LRECL=120,BLKSIZE=0)
//SYSIN    DD *
  JOINKEYS FILE=F1,FIELDS=(1,10,A)
  JOINKEYS FILE=F2,FIELDS=(1,10,A)

  JOIN UNPAIRED,F1

  REFORMAT FIELDS=(F1:1,60,
                   F2:11,59,
                   ?)

  SORT FIELDS=COPY
/*
//*
//RELAT    EXEC PGM=SORT
//SYSOUT   DD SYSOUT=*
//SORTIN   DD DSN=&&CRUZADO,DISP=(OLD,DELETE)
//OK       DD DSN=VAGNER.RELATORIO.OK,
//            DISP=(NEW,CATLG,DELETE),
//            UNIT=SYSDA,
//            SPACE=(CYL,(20,10),RLSE)
//SEMCLI   DD DSN=VAGNER.RELATORIO.SEMCLIENTE,
//            DISP=(NEW,CATLG,DELETE),
//            UNIT=SYSDA,
//            SPACE=(CYL,(10,5),RLSE)
//SYSIN    DD *
  SORT FIELDS=COPY

  OUTFIL FNAMES=OK,
         INCLUDE=(120,1,CH,EQ,C'B')

  OUTFIL FNAMES=SEMCLI,
         SAVE
/*

Nesse tipo de fluxo, os temporários fazem sentido porque representam fronteiras claras entre etapas diferentes.

Entretanto, se restart for requisito crítico, um dataset permanente controlado por geração ou ciclo pode ser preferível. Datasets &&TEMP desaparecem ao final do job e podem não servir como checkpoint reutilizável em uma nova submissão.


48. Curiosidades do acampamento

Curiosidade 1 — O SORT pode substituir pequenos programas COBOL

Muitos programas escritos apenas para:

  • filtrar;

  • mover campos;

  • somar;

  • eliminar duplicados;

  • separar arquivos;

  • inserir constantes;

poderiam ser substituídos por DFSORT.

Isso não significa que todo programa deve virar SORT.

Mas antes de criar um novo módulo COBOL, pergunte:

Esta lógica é transformação de registros ou verdadeira regra de negócio?

Curiosidade 2 — Um SORT bem escrito pode reduzir janelas batch

Eliminar leituras, escritas e passos intermediários pode representar grande economia em ambientes de alto volume.

Curiosidade 3 — “Arquivo já ordenado” é uma afirmação perigosa

Um arquivo pode estar:

  • visualmente ordenado;

  • ordenado apenas pela primeira chave;

  • ordenado em ASCII, não EBCDIC;

  • ordenado crescentemente quando o programa espera decrescente;

  • ordenado sem estabilidade;

  • ordenado antes de uma concatenação desordenada.

Curiosidade 4 — A menor mudança no layout pode destruir o resultado

Adicionar dois bytes no início do arquivo desloca todas as posições posteriores.

O SORT continuará executando.

Talvez retorne RC 0.

E produzirá dados perfeitamente classificados pela coluna errada.

Esse é um dos cenários mais perigosos: o erro silencioso.

Curiosidade 5 — O nome ICETOOL combina com o produto

Enquanto o CPD esquenta, o ICETOOL entra em cena com seus comandos começando por ICE.

Curiosidade 6 — Nem todo RC 4 é derrota

Às vezes é uma condição planejada para controlar o fluxo do job.

Curiosidade 7 — O SORT conhece o registro em diferentes versões

O registro visto por INCLUDE pode não ser o mesmo visto por SORT, que pode não ser o mesmo visto por OUTFIL.

Compreender a ordem de processamento é metade do treinamento.


49. Easter eggs Bellacosa

Easter egg 1 — O sargento Elias dos datasets

INCLUDE é o soldado que olha cada registro e decide:

— Você vem conosco.

OMIT olha o mesmo registro e diz:

— Você fica.

Easter egg 2 — O sargento Barnes do batch

SUM FIELDS=NONE não negocia com duplicados.

Ele escolhe um sobrevivente e remove os demais.

Por isso, nunca o deixe decidir sozinho quando a regra de negócio exige saber exatamente qual registro deve permanecer.

Easter egg 3 — A floresta não é o que parece

No arquivo VB, os quatro bytes do RDW estão sempre à frente.

Invisíveis.

Esperando o recruta esquecer que eles existem.

Easter egg 4 — “Adagio for Strings” no CPD

Quando o job termina com RC 16 às cinco e cinquenta da manhã e a janela batch fecha às seis, algum operador deveria colocar Adagio for Strings para tocar no data center.

Easter egg 5 — Ninguém luta sozinho

O SORT prepara dados para:

  • COBOL;

  • CICS;

  • Db2;

  • IMS;

  • VSAM;

  • relatórios;

  • reconciliações;

  • fechamento contábil;

  • processamento de cartões;

  • folhas de pagamento.

Ele raramente recebe aplausos.

Mas, quando falha, todo o exército percebe.


50. Checklist do recruta antes de liberar o JCL

Dataset

  • Confirmei RECFM.

  • Confirmei LRECL.

  • Confirmei se o arquivo é FB ou VB.

  • Confirmei se há RDW.

  • Confirmei organização e volume.

  • Confirmei se a entrada pode estar vazia.

Layout

  • Calculei as posições.

  • Verifiquei campos packed.

  • Verifiquei campos binários.

  • Examinei dados em hexadecimal.

  • Confirmei sinais e decimais implícitos.

Regras

  • Sei quais registros entram.

  • Sei quais registros são eliminados.

  • Sei como duplicados devem ser tratados.

  • Sei qual registro deve sobreviver.

  • Sei a ordem exata das chaves.

  • Sei quais saídas serão produzidas.

Performance

  • Filtrei antes de ordenar.

  • Reduzi registros quando possível.

  • Evitei passos redundantes.

  • Avaliei OUTFIL.

  • Avaliei MERGE.

  • Não copiei SORTWKnn sem justificativa.

  • Estimei espaço de saída.

Validação

  • Testei arquivo vazio.

  • Testei um registro.

  • Testei duplicados.

  • Testei valores negativos.

  • Testei chave mínima e máxima.

  • Conferi contagens.

  • Conferi primeiro e último registro.

  • Li as mensagens completas.

  • Documentei as posições.


51. Dez comandos que todo recruta deve memorizar

//* 1. ORDENAR
  SORT FIELDS=(1,10,CH,A)
//* 2. COPIAR
  SORT FIELDS=COPY
//* 3. INCLUIR
  INCLUDE COND=(20,1,CH,EQ,C'A')
//* 4. OMITIR
  OMIT COND=(20,1,CH,EQ,C'C')
//* 5. REMOVER DUPLICADOS
  SORT FIELDS=(1,10,CH,A)
  SUM FIELDS=NONE
//* 6. SOMAR
  SORT FIELDS=(1,4,CH,A)
  SUM FIELDS=(20,6,PD)
//* 7. REFORMATAR ANTES
  INREC BUILD=(10,5,1,9)
//* 8. REFORMATAR DEPOIS
  OUTREC BUILD=(1,10,C'|',11,20)
//* 9. MULTIPLAS SAIDAS
  OUTFIL FNAMES=SAIDA1,INCLUDE=(1,1,CH,EQ,C'A')
  OUTFIL FNAMES=SAIDA2,SAVE
//* 10. CRUZAR ARQUIVOS
  JOINKEYS FILE=F1,FIELDS=(1,10,A)
  JOINKEYS FILE=F2,FIELDS=(1,10,A)

52. A última lição do pelotão

O recruta submeteu o job às cinco e doze.

O JES aceitou.

O passo iniciou.

Milhões de registros entraram no DFSORT como soldados perdidos em uma floresta fechada. Contas, agências, datas e valores atravessaram memória, buffers e áreas de trabalho.

Alguns registros foram eliminados.

Outros foram reformatados.

Duplicados desapareceram.

Valores foram consolidados.

Três arquivos surgiram na saída, cada um rigorosamente organizado.

Às cinco e vinte e nove, o job terminou:

MAXCC=0000

O veterano examinou as mensagens, conferiu as contagens e perguntou:

— Quantos registros entraram?

O recruta respondeu.

— Quantos foram rejeitados?

O recruta respondeu novamente.

— Qual duplicado foi mantido?

Dessa vez, o jovem mostrou a regra de data e hora descendente.

O veterano finalmente assentiu.

Não porque o job havia terminado com RC 0.

Mas porque o recruta sabia explicar por que o resultado estava correto.

No mainframe, qualquer um pode copiar uma instrução:

SORT FIELDS=(1,10,CH,A)

O verdadeiro profissional entende:

  • quais bytes estão sendo comparados;

  • como estão representados;

  • em que momento o registro foi transformado;

  • quanto espaço será utilizado;

  • qual duplicado sobreviverá;

  • o que acontecerá quando o arquivo estiver vazio;

  • como provar que a saída está certa.

Essa é a diferença entre executar um SORT e comandar o SORT.

E quando a madrugada cair sobre o CPD, os discos começarem a girar e milhões de registros marcharem para dentro do batch, lembre-se:

O caos pode ter milhões de linhas.
Mas basta uma chave correta para colocá-lo em ordem.

Bem-vindo ao pelotão, recruta.


segunda-feira, 12 de agosto de 2019

O Paciente 1890: Herman Hollerith, Cartões Perfurados e o Dia em que o Big Data Entrou na Sala de Emergência

Bellacosa Mainframe apresenta herman hollerith

☕ Um Café no Bellacosa Mainframe

O Paciente 1890: Herman Hollerith, Cartões Perfurados e o Dia em que o Big Data Entrou na Sala de Emergência

Imagine a cena.

Ano: 1890.

Local: Estados Unidos.

Na sala de emergência não há médicos, estetoscópios ou aparelhos de ressonância magnética.

Há funcionários públicos.

Muitos funcionários públicos.

Montanhas de papel.

Tabelas.

Listas.

Canetas.

Calculadoras mecânicas.

E um paciente em estado crítico.

O nome do paciente?

Censo dos Estados Unidos.

Sintomas?

Excesso de dados.

Processamento lento.

Escalabilidade praticamente inexistente.

Grande risco de erro humano.

Diagnóstico preliminar?

A população americana estava crescendo mais rápido do que a capacidade do governo de contar a própria população.

Se o Dr. House fosse analista de sistemas em 1890, provavelmente entraria na sala, olharia para aquelas toneladas de papel e diria:

— Não precisamos de mais funcionários. Precisamos parar de fazer isso como idiotas.

E, surpreendentemente, foi mais ou menos isso que Herman Hollerith percebeu.

A solução não seria contratar milhares de pessoas adicionais.

Seria automatizar o processamento dos dados.

E nesse momento começa uma das histórias mais importantes da computação.

Não com um computador eletrônico.

Não com COBOL.

Não com IBM.

Não com System/360.

Nem sequer com válvulas.

A história começa com um pedaço de papel perfurado.

E uma pergunta que ainda hoje atormenta qualquer programador COBOL trabalhando em um banco:

Como processar milhões de registros de maneira rápida, previsível e confiável?

Bem-vindo ao episódio de hoje do nosso hospital tecnológico.

Pegue o café.

O paciente tem aproximadamente 136 anos.

E, surpreendentemente, continua vivo.


🩺 Capítulo 1 — O paciente apresenta sintomas graves

Para entender Hollerith, precisamos primeiro entender o problema.

A Constituição dos Estados Unidos exige que o governo realize periodicamente um censo da população.

Isso não era apenas curiosidade estatística.

Os dados do censo influenciavam questões importantes como representação política, planejamento público e distribuição de recursos.

No século XIX, entretanto, coletar dados significava basicamente escrever coisas em papel.

Imagine milhões de pessoas respondendo perguntas como:

nome,

idade,

sexo,

profissão,

estado civil,

origem,

local de residência,

ocupação.

Agora imagine funcionários tentando transformar tudo isso em estatísticas nacionais.

Sem Excel.

Sem SQL.

Sem Python.

Sem Db2.

Sem SORT.

Sem DFSORT.

Sem ICETOOL.

Sem absolutamente nada que um programador moderno reconheceria como ferramenta computacional.

Era processamento humano.

O censo americano de 1880 havia se tornado particularmente problemático.

Sua tabulação completa levou muitos anos.

E aqui apareceu um problema assustador.

Se a população continuasse crescendo, existia o risco de o processamento de um censo não terminar antes do próximo começar.

Isso, em linguagem moderna, seria algo semelhante a executar:

JOB CENSUS80

START: 1880
END:   1888

e descobrir:

NEXT JOB: CENSUS90
START: 1890

O SLA já estava basicamente condenado.

Podemos imaginar o JES emitindo:

IEF450I CENSUS80 - TIME LIMIT EXCEEDED

Claro que JES ainda não existia.

Mas o problema operacional era exatamente esse.




🧠 Capítulo 2 — O diagnóstico de Hollerith

Herman Hollerith era engenheiro e estatístico.

Ele percebeu algo fundamental:

o gargalo não estava na coleta dos dados.

Estava na transformação dos dados em informação.

Essa distinção é importantíssima.

Até hoje empresas confundem essas duas coisas.

Ter dados não significa possuir informação.

Você pode ter:

10 bilhões de registros,

500 TB de logs,

milhões de transações,

anos de arquivos históricos.

Mas se não conseguir processá-los corretamente, eles têm valor limitado.

Em outras palavras:

DADO ≠ INFORMAÇÃO

Para transformar dado em informação precisamos de processamento.

E Hollerith procurou uma maneira de representar características humanas de forma que uma máquina pudesse identificá-las.

Nascia a ideia das perfurações codificadas.


🕳️ Capítulo 3 — O cartão perfurado entra no hospital

Pense em um cartão de papel.

Cada posição possível no cartão representa determinada informação.

Uma perfuração naquela posição significa uma coisa.

Ausência de perfuração significa outra.

Simplificando bastante:

IDADE   SEXO   ESTADO   PROFISSÃO
  |      |       |         |
  O      O       O         O

Hoje pensaríamos nisso como bits.

Algo semelhante a:

0
1
0
1

Naturalmente o sistema de Hollerith era diferente dos bits modernos.

Mas o conceito fundamental estava ali:

representar informação utilizando estados fisicamente detectáveis.

Em um computador moderno temos:

tensão alta  → 1
tensão baixa → 0

No cartão perfurado poderíamos pensar:

furo     → informação presente
sem furo → informação ausente

O papel havia se transformado em meio de armazenamento legível por máquina.

Isso é extraordinário.

Porque naquele momento aconteceu algo conceitualmente gigantesco:

a informação deixou de ser apenas legível por seres humanos.

Agora também podia ser interpretada mecanicamente.



⚡ Capítulo 4 — Como aquela geringonça funcionava?

Agora chegamos ao mecanismo digno de laboratório.

A tabuladora de Hollerith empregava contatos elétricos.

Um cartão era colocado sobre um conjunto de posições.

Agulhas metálicas desciam.

Quando encontravam papel:

nada acontecia.

Quando encontravam uma perfuração:

atravessavam o cartão e fechavam um contato elétrico, originalmente envolvendo recipientes com mercúrio.

Esse circuito acionava contadores.

Em versão simplificada:

CARTÃO
   ↓
LEITOR MECÂNICO
   ↓
DETECÇÃO DO FURO
   ↓
CIRCUITO ELÉTRICO
   ↓
CONTADOR
   ↓
RESULTADO

Não temos CPU.

Não temos memória RAM.

Não temos sistema operacional.

Mas temos algo importantíssimo:

entrada → processamento → saída.

A santa trindade da computação já estava ali.



💾 Capítulo 5 — O primeiro record que você nunca programou

Agora vamos trazer isso para o COBOL.

Você escreve:

01 WS-PESSOA.
   05 WS-IDADE       PIC 9(03).
   05 WS-SEXO        PIC X.
   05 WS-ESTADO      PIC X(02).
   05 WS-PROFISSAO   PIC X(20).

Para você isso é um registro.

Um record.

Mas pense no cartão de Hollerith como exatamente isso.

Cada cartão representava uma entidade.

Por exemplo:

Pessoa 000001
Pessoa 000002
Pessoa 000003
Pessoa 000004

Ou seja:

um cartão = um registro físico.

Décadas depois teríamos:

registro em fita
registro em disco
registro VSAM
linha Db2
documento JSON
mensagem MQ
evento Kafka

O suporte mudou.

O conceito permaneceu.

Essa é uma das grandes lições da computação.

Tecnologias desaparecem.

Abstrações sobrevivem.


📦 Capítulo 6 — Bem-vindo ao primeiro dataset de papel

Imagine agora dez mil cartões.

Você coloca todos dentro de uma caixa.

Parabéns.

Criamos aproximadamente isto:

CENSUS.PEOPLE.DATA

Claro que o dataset não existia literalmente.

Mas conceitualmente temos:

DATASET
  |
  +-- RECORD
  +-- RECORD
  +-- RECORD
  +-- RECORD

Na época:

CAIXA
  |
  +-- CARTÃO
  +-- CARTÃO
  +-- CARTÃO
  +-- CARTÃO

Você percebe como a evolução começa a ficar interessante?

O mainframe moderno não apareceu magicamente em 1964.

Existe uma longa linhagem intelectual.


🔀 Capítulo 7 — E então inventamos o SORT antes do SORT

Agora aparece outro problema.

Você tem milhares de cartões.

Mas eles estão misturados.

Pessoas de Nova York.

Texas.

Califórnia.

Homens.

Mulheres.

Crianças.

Profissões diferentes.

Se quiser saber quantas pessoas vivem em determinado estado, precisa agrupar os registros.

Entram em cena as máquinas classificadoras.

Elas separavam cartões conforme determinadas perfurações.

Em linguagem mainframe:

SORT FIELDS=(ESTADO,A)

Mais tarde:

SORT FIELDS=(SEXO,A,IDADE,A)

Talvez você nunca tenha pensado nisso dessa maneira, mas o humilde SORT possui uma ancestralidade muito antiga.

Hoje escrevemos:

//SORTSTEP EXEC PGM=SORT
//SYSOUT   DD SYSOUT=*
//SORTIN   DD DSN=ENTRADA,DISP=SHR
//SORTOUT  DD DSN=SAIDA,
//            DISP=(NEW,CATLG,DELETE)
//SYSIN    DD *
 SORT FIELDS=(1,2,CH,A)
/*

Em 1890 alguém precisava fazer essencialmente isto:

PEGAR CARTÕES
↓
IDENTIFICAR CAMPO
↓
SEPARAR
↓
AGRUPAR
↓
CONTAR

Mudou a interface.

A lógica sobreviveu.


🏭 Capítulo 8 — Nasce o batch

Batch significa lote.

Literalmente.

Um conjunto de coisas processadas juntas.

Imagine um operador chegando com 5.000 cartões.

Ele coloca o lote na máquina.

Executa determinado processamento.

Retira o resultado.

Depois vem o lote seguinte.

Temos então:

BATCH 001
BATCH 002
BATCH 003

Décadas depois:

JOB001
JOB002
JOB003

Hoje, no z/OS:

JES2
 ↓
JOB
 ↓
STEP
 ↓
PROGRAM
 ↓
DATASET

O hardware mudou dramaticamente.

Mas a ideia de separar processamento em unidades controláveis continuou.


🧾 Capítulo 9 — O ancestral espiritual do JCL

Imagine precisar entregar cartões para uma máquina.

Alguns cartões representam dados.

Outros poderiam representar instruções.

Décadas depois, computadores baseados em cartões adotariam exatamente essa lógica.

Um deck poderia conter:

JOB CONTROL
PROGRAM
INPUT DATA

Quando apareceu JCL, a filosofia já era familiar.

Você não apenas fornecia dados.

Também descrevia:

qual programa executar,

quais arquivos utilizar,

onde colocar a saída,

o que fazer em caso de erro.

Exemplo:

//BELLACOS JOB CLASS=A,MSGCLASS=X
//STEP01   EXEC PGM=MEUPGM
//ENTRADA  DD DSN=CLIENTES.MASTER,DISP=SHR
//SAIDA    DD DSN=CLIENTES.REPORT,
//            DISP=(NEW,CATLG,DELETE)

O JCL é muito mais sofisticado, evidentemente.

Mas seu espírito pertence a uma tradição antiga:

definir um trabalho de forma estruturada e reproduzível.


🧬 Capítulo 10 — A genealogia do mainframe

Agora precisamos desmontar um mito.

IBM não nasceu fazendo computadores.

Hollerith fundou uma empresa chamada:

Tabulating Machine Company.

Ela produzia equipamentos para processamento de informações.

Em 1911, sua empresa participou de uma consolidação empresarial que resultou na:

Computing-Tabulating-Recording Company — CTR.

Depois apareceu um personagem fundamental:

Thomas J. Watson Sr.

Em 1924, a CTR passou a utilizar o nome:

International Business Machines.

IBM.

Veja a genealogia:

Herman Hollerith
      ↓
Tabulating Machine Company
      ↓
CTR
      ↓
IBM
      ↓
máquinas de cartões
      ↓
computadores eletrônicos
      ↓
IBM System/360
      ↓
System/370
      ↓
S/390
      ↓
zSeries
      ↓
IBM Z

Agora fica muito mais fácil entender por que processamento de dados está praticamente no DNA da IBM.


🏥 Capítulo 11 — House entra na sala e pergunta: qual é a doença?

Qual era realmente a doença do censo?

Não era falta de dados.

Era incapacidade de processá-los suficientemente rápido.

Vamos chamar isso de:

DATA PROCESSING BOTTLENECK

Agora avance para 2026.

Uma empresa possui:

logs,

transações,

dados de sensores,

histórico de clientes,

documentos,

streams,

imagens,

telemetria.

Ela diz:

— Temos Big Data.

House provavelmente responderia:

— Não. Você tem Big Storage. Só vira Big Data quando consegue fazer alguma coisa útil com isso.

Essa distinção continua absolutamente válida.


🏦 Capítulo 12 — Imagine Hollerith trabalhando em um banco

Vamos trazer tudo para um cenário COBOL.

Suponha que você trabalhe em um banco.

Todo final do dia chegam milhões de transações.

Precisamos:

  1. ler movimentos;

  2. validar registros;

  3. ordenar por conta;

  4. atualizar saldo;

  5. calcular juros;

  6. gerar extratos;

  7. produzir relatórios;

  8. guardar histórico.

Fluxo:

TRANSAÇÕES
     ↓
VALIDAÇÃO
     ↓
SORT
     ↓
PROGRAMA COBOL
     ↓
ATUALIZAÇÃO
     ↓
RELATÓRIO

Agora coloque Hollerith em 1890:

CARTÕES
   ↓
VALIDAÇÃO
   ↓
CLASSIFICAÇÃO
   ↓
TABULAÇÃO
   ↓
CONTAGEM
   ↓
RELATÓRIO

Não é a mesma tecnologia.

Mas existe uma impressionante continuidade arquitetural.


🗃️ Capítulo 13 — O ancestral conceitual do arquivo mestre

Programadores COBOL antigos conhecem muito bem o conceito de:

MASTER FILE

Você possui um arquivo principal.

Por exemplo:

CLIENTES.MASTER

Durante o dia chegam movimentos:

CLIENTES.MOVIMENTO

À noite:

MASTER + MOVIMENTO
          ↓
       UPDATE
          ↓
     NOVO MASTER

Essa filosofia aparece naturalmente quando dados físicos precisam ser organizados em grandes conjuntos.

Com cartões, era comum trabalhar com conjuntos classificados que precisavam ser combinados, atualizados ou contados.

O mundo do processamento comercial nasceu muito antes do COBOL.

COBOL apenas herdou uma tradição.


💳 Capítulo 14 — Por que o cartão IBM tinha 80 colunas?

Aqui vem uma curiosidade que todo iniciante em COBOL deveria conhecer.

O famoso cartão perfurado IBM consolidou-se em um formato de 80 colunas.

Isso teve impacto gigantesco na programação.

Programas COBOL tradicionais eram organizados respeitando posições específicas.

Simplificando:

1-6    sequência
7      indicador
8-11   área A
12-72  área B
73-80  identificação

Por que essas limitações aparentemente estranhas?

Porque código-fonte era armazenado em cartões físicos.

Uma linha:

um cartão.

Um programa de 2.000 linhas?

Aproximadamente 2.000 cartões.

Agora imagine derrubar a caixa.

Bem-vindo ao ABEND psicológico.

Por isso existiam números sequenciais.

Se os cartões caíssem no chão, você poderia reorganizá-los.

Provavelmente rezando para qualquer entidade disponível no CPACF espiritual.


🥚 Easter Egg #1 — O verdadeiro motivo da coluna 72

Quando um iniciante pergunta:

— Por que COBOL antigo às vezes parece ter medo de passar da coluna 72?

Não era superstição.

Era arqueologia de hardware.

A linguagem carrega fósseis tecnológicos.

Assim como nosso corpo carrega estruturas herdadas da evolução, linguagens antigas carregam estruturas herdadas das máquinas onde nasceram.

House aprovaria a analogia.


⚙️ Capítulo 15 — Do cartão ao VSAM

Agora acompanhe a evolução conceitual.

Primeiro:

cartão

Depois:

fita magnética

Depois:

disco

Depois:

arquivos organizados

Depois:

VSAM

No VSAM podemos ter:

KSDS,

ESDS,

RRDS,

LDS,

entre outros.

Mas observe o princípio fundamental:

armazenar registros de maneira organizada para recuperação e processamento previsíveis.

Esse princípio não nasceu com VSAM.

VSAM é uma sofisticada manifestação de uma ideia muito mais antiga.


🗄️ Capítulo 16 — E depois chegou o banco de dados

Imagine então perceber:

— Talvez não seja muito inteligente cada programa manter seu próprio arquivo independente.

Entram bancos de dados.

IMS.

Db2.

Agora podemos representar informações utilizando estruturas relacionais.

Exemplo:

SELECT ESTADO,
       COUNT(*)
FROM PESSOA
GROUP BY ESTADO;

Hollerith provavelmente entenderia imediatamente o objetivo.

Ele apenas ficaria fascinado com a velocidade.

Sua máquina fazia contagens mecanicamente.

Db2 pode realizar operações sobre milhões ou bilhões de registros utilizando processadores moderníssimos.

Mas a pergunta continua:

Quantas pessoas pertencem a determinada categoria?


🔍 Capítulo 17 — GROUP BY é descendente intelectual da tabuladora

Pense:

SELECT SEXO, COUNT(*)
FROM CENSO
GROUP BY SEXO;

Agora volte a 1890.

A máquina identifica determinadas perfurações.

Separa.

Conta.

Produz totais.

Conceitualmente:

READ
GROUP
COUNT
REPORT

Esse é provavelmente o aspecto mais bonito dessa história.

Não estamos olhando apenas para hardware velho.

Estamos vendo ideias computacionais em estado embrionário.


📊 Capítulo 18 — Big Data já existia antes de chamarmos de Big Data

Naturalmente não existiam petabytes em 1890.

Mas Big Data é relativo.

Um dataset é "grande" quando começa a superar nossa capacidade prática de processá-lo utilizando métodos existentes.

Para 1890, milhões de registros humanos eram um gigantesco problema de dados.

O censo era, em termos daquele período, uma aplicação de processamento em massa.

Hoje o problema poderia ser:

10 bilhões de transações

Em 1890:

dezenas de milhões de habitantes

A questão é sempre a mesma:

VOLUME
+
TEMPO
+
CONFIABILIDADE

⏱️ Capítulo 19 — Performance não é luxo

Essa é uma excelente lição para programadores COBOL iniciantes.

Imagine um programa que lê 100 registros.

Se ele é lento, talvez ninguém perceba.

Agora imagine:

100.000.000 registros

Uma diferença minúscula por registro pode virar horas.

É exatamente por isso que mainframe possui obsessão histórica por:

I/O,

buffers,

índices,

access paths,

SORT,

CPU,

elapsed time,

WLM,

paralelismo.

Em grande escala:

pequenas ineficiências ficam gigantescas.

Hollerith descobriu isso antes de existir CPU.


🧪 Capítulo 20 — Passo a passo: transforme o censo em um Job COBOL

Vamos brincar.

Imagine que recebemos o Census 1890 hoje.

Arquivo:

CENSUS.INPUT

Layout:

01 CENSUS-RECORD.
   05 CENSUS-ID        PIC 9(09).
   05 CENSUS-AGE       PIC 9(03).
   05 CENSUS-SEX       PIC X.
   05 CENSUS-STATE     PIC X(02).
   05 CENSUS-OCCUP     PIC X(20).

Precisamos descobrir população por estado.

Primeiro fazemos SORT:

//SORT01 EXEC PGM=SORT
//SORTIN DD DSN=CENSUS.INPUT,DISP=SHR
//SORTOUT DD DSN=CENSUS.BYSTATE,
// DISP=(NEW,CATLG,DELETE)
//SYSIN DD *
 SORT FIELDS=(13,2,CH,A)
/*

Depois COBOL:

PERFORM UNTIL EOF-SW = 'Y'

   READ CENSUS-FILE
      AT END
         MOVE 'Y' TO EOF-SW
      NOT AT END
         ADD 1 TO STATE-COUNT
   END-READ

END-PERFORM.

Naturalmente um programa real seria mais elaborado.

Mas perceba:

Hollerith fazia conceitualmente a mesma operação usando eletromecânica.


🚨 Capítulo 21 — E se um cartão estivesse errado?

Excelente pergunta.

Aí entramos na qualidade de dados.

Um campo incorreto em 1890 poderia gerar estatística incorreta.

Um registro incorreto hoje pode provocar:

pagamento errado,

saldo errado,

cobrança indevida,

fraude,

decisão regulatória incorreta.

Por isso processamento empresarial desenvolveu obsessão por controles.

Hoje temos:

VALIDAÇÃO
CHECKSUM
RECONCILIAÇÃO
AUDITORIA
LOG
RESTART
RECOVERY

Tudo converge para uma pergunta:

Posso confiar no resultado?


🛡️ Capítulo 22 — Esse é o verdadeiro DNA do mainframe

Muita gente acha que mainframe significa:

"computador muito poderoso".

É uma definição incompleta.

Mainframe é sobretudo uma arquitetura orientada para processamento empresarial altamente confiável.

Os pilares incluem:

confiabilidade, disponibilidade, segurança, escalabilidade, throughput, integridade e auditabilidade.

Um banco não quer apenas saber:

"Meu programa rodou?"

Quer saber:

"Ele rodou corretamente?"

"Processou tudo?"

"Processou duas vezes?"

"Perdeu alguma coisa?"

"Consigo provar o resultado?"

"Se falhar, consigo reiniciar?"

Essas perguntas descendem diretamente dos grandes problemas de processamento de dados.


🔄 Capítulo 23 — Restart: porque até máquinas ficam doentes

Imagine um batch com 200 milhões de registros.

Ele executa quatro horas.

Falha no registro:

199.875.431

Você quer começar novamente do zero?

Provavelmente não.

Por isso sistemas empresariais desenvolveram mecanismos de:

checkpoint,

restart,

commit,

rollback,

recovery.

House diria:

— O programa não precisa nunca ficar doente. Precisa sobreviver quando ficar.

Essa talvez seja uma excelente definição de resiliência.


🥚 Easter Egg #2 — O primeiro DBA talvez usasse caixas

Antes de catálogo Db2, tabelas de sistema e índices B-tree, alguém precisava saber onde estavam os cartões.

Imagine:

CAIXA 001 → NEW YORK
CAIXA 002 → TEXAS
CAIXA 003 → OHIO

Parabéns.

Temos o ancestral conceitual do catálogo.

Naturalmente ninguém deveria colocar no currículo:

"DBA de caixas de sapato desde 1890."

Mas a analogia é divertida.


🤖 Capítulo 24 — Hollerith encontraria IA e reconheceria o problema

Se transportássemos Hollerith até 2026 e mostrássemos inteligência artificial, provavelmente ele ficaria maravilhado.

GPUs.

LLMs.

Vetores.

Embeddings.

Machine learning.

Mas quando perguntássemos:

— Qual continua sendo nosso problema?

Talvez ele respondesse:

— Vocês ainda estão tentando transformar enorme quantidade de informação em algo útil.

Exatamente.

Mudamos brutalmente nossas máquinas.

Mas nossos grandes problemas continuam envolvendo:

coletar,

representar,

armazenar,

classificar,

processar,

interpretar.


🧠 Capítulo 25 — Data Lake, Db2 ou caixa de cartões: a pergunta continua igual

Imagine três épocas.

1890:

CARTÕES

1970:

FITAS

2026:

OBJECT STORAGE

A pergunta:

Onde está o dado?

Depois:

Como encontro?

Depois:

Como processo?

Depois:

Posso confiar?

Tecnologia muda.

Governança permanece.


🥚 Easter Egg #3 — PROC CENSUS

Se o universo tivesse criado z/OS em 1890, talvez existisse:

//CENSUS90 JOB (USA),'HOLLERITH',
// CLASS=A,MSGCLASS=X
//*
//SORTPOP EXEC PGM=SORT
//*
//TABULATE EXEC PGM=HOLLERTH
//*
//REPORT EXEC PGM=CENSRPT

E provavelmente alguém reclamaria:

JOB HELD - PRINTER OUT OF PAPER

Até hoje continuamos perdendo batalhas contra impressoras.

Algumas tecnologias são eternas.


🎓 Capítulo 26 — Cinco lições para quem está começando em COBOL

Quando você estudar COBOL, tente não decorar apenas sintaxe.

Entenda a filosofia.

Quando encontrar:

READ
WRITE
REWRITE
START
DELETE

pense:

estou manipulando registros.

Quando encontrar:

JOB
EXEC
DD

pense:

estou descrevendo processamento.

Quando encontrar DFSORT:

pense:

estou organizando dados para torná-los processáveis.

Quando encontrar VSAM:

pense:

estou escolhendo uma organização física e lógica adequada.

Quando encontrar Db2:

pense:

estou abstraindo acesso estruturado aos dados.

Essa mudança mental transforma completamente seu aprendizado.


🔬 Capítulo 27 — House olha para o gráfico

No final do episódio alguém pergunta:

— Afinal, Hollerith inventou o mainframe?

Não.

Diagnóstico errado.

Hollerith não inventou o mainframe.

Também não inventou COBOL.

Não inventou computador eletrônico.

Mas ajudou a consolidar vários princípios fundamentais do processamento de dados mecanizado.

E esses princípios posteriormente seriam incorporados em sistemas empresariais.

Ele ajudou a demonstrar que grandes volumes de informações poderiam ser:

estruturados,

representados,

classificados,

contados,

processados automaticamente.

Esse é o elo histórico importante.


🧬 Capítulo 28 — A linhagem intelectual

Podemos representar assim:

CENSO
 ↓
DADOS
 ↓
CARTÕES
 ↓
TABULAÇÃO
 ↓
AUTOMAÇÃO
 ↓
PROCESSAMENTO COMERCIAL
 ↓
IBM
 ↓
COMPUTADORES
 ↓
MAINFRAMES
 ↓
COBOL
 ↓
JCL
 ↓
VSAM / IMS / DB2
 ↓
IBM Z

Não é uma linha evolutiva perfeitamente direta.

História tecnológica nunca é.

Existem inúmeros inventores, empresas, concorrentes e caminhos paralelos.

Mas a influência de Hollerith e da indústria de tabulação sobre a história da IBM e do processamento empresarial é indiscutível.


🏛️ Capítulo 29 — Do Census Bureau ao IBM Z

Agora imagine as duas pontas dessa história.

Uma máquina eletromecânica identifica perfurações em papel.

Um IBM Z executa bilhões de instruções, protege transações criptograficamente, suporta milhares de workloads simultâneos e processa operações empresariais críticas.

Visualmente:

não poderiam ser mais diferentes.

Conceitualmente:

há uma familiaridade surpreendente.

Ambos existem porque organizações possuem dados demais para serem processados manualmente.

Ambos tentam resolver:

escala,

velocidade,

confiabilidade,

repetibilidade.


☕ Capítulo Final — O paciente nunca esteve realmente doente

House fecha o prontuário.

Olha pela janela.

Toma café — sim, nesta versão ele abandonou o vicodin e descobriu uma máquina de espresso instalada ao lado de um IBM z17.

O residente pergunta:

— Então qual era a doença?

House responde:

— Crescimento.

— Crescimento?

— Dados crescem. Empresas crescem. Populações crescem. Transações crescem. O problema começa quando sua capacidade de processamento não cresce junto.

Silêncio.

Essa talvez seja a maior lição deixada por Hollerith.

A humanidade sempre produziu informação.

Durante milhares de anos conseguimos processá-la manualmente.

Então nossas sociedades cresceram.

Governos cresceram.

Empresas cresceram.

Bancos cresceram.

Populações cresceram.

E chegou um momento em que cérebro, papel e caneta não eram mais suficientes.

Precisávamos de máquinas.

Primeiro máquinas mecânicas.

Depois eletromecânicas.

Depois válvulas.

Transistores.

Circuitos integrados.

Mainframes.

Cloud.

IA.

Mas existe uma linha invisível atravessando tudo isso.

Uma ideia simples:

dados só têm valor quando conseguimos processá-los de forma confiável.

O cartão perfurado desapareceu.

As máquinas de Hollerith desapareceram.

As caixas desapareceram.

Grande parte das fitas desapareceu.

Os antigos leitores de cartões desapareceram.

Mas:

records continuam existindo.

Sort continua existindo.

Batch continua existindo.

Jobs continuam existindo.

Datasets continuam existindo.

Processamento centralizado continua existindo.

Auditoria continua existindo.

Confiabilidade continua existindo.

E COBOL continua existindo.

Talvez essa seja a grande piada histórica.

Todo mundo olha para um IBM Z moderno e enxerga uma máquina futurista.

Mas, se você retirar as camadas de silício, virtualização, criptografia, APIs e inteligência artificial, bem lá no fundo ainda existe uma pergunta feita há mais de um século:

Tenho uma enorme quantidade de registros.

Como diabos vou processar tudo isso corretamente?

Herman Hollerith levantaria a mão.

Um programador COBOL levantaria outra.

E provavelmente ambos começariam a discutir SORT.

Enquanto isso, no fundo da sala, alguma impressora continuaria offline.

Porque existem problemas que nem 136 anos de evolução tecnológica conseguiram resolver.

Bem-vindo ao Bellacosa Mainframe.

Onde sistemas "legados" às vezes são apenas ideias tão boas que se recusaram a morrer.


domingo, 4 de agosto de 2019

🍺 Os Petiscos de Boteco Paulistano – A Engenharia Social do Balcão

 




🍺 Os Petiscos de Boteco Paulistano – A Engenharia Social do Balcão
por El Jefe – Bellacosa Mainframe Midnight Lunch Edition

Existem bytes, bits e buffers.
E existe o balcão de boteco, onde o sistema operacional da vida boêmia roda desde o tempo do chope bem tirado e do papo fiado.
Ali, alinhados como componentes de um painel de controle analógico, estão eles — os petiscos de boteco paulistano: tremoço, amendoim, picles, ovo colorido, cebola em conserva, azeitona, salame, mortadela, e aquele ar de “mais uma rodada, por favor”.

🧄 Origem – do armazém ao balcão democrático
Essas delícias nasceram nos armazéns e empórios dos anos 1940 e 1950, quando o boteco ainda era extensão da quitanda.
O freguês pedia uma pinga e, pra “forrar o estômago”, vinha um punhado de tremoço ou amendoim.
Tudo simples, direto, sem menu nem delivery.
O balcão era o mainframe da vizinhança: centralizava histórias, processava boatos e servia uptime de 24 horas nos dias bons.

O tremoço, por exemplo, veio com os imigrantes portugueses — semente amarga que precisava ser deixada de molho por dias para virar petisco.
O amendoim, mais americano, se abrasileirou nas fábricas da Paulistânia.
Já os picles e cebolinhas em conserva trazem DNA ítalo-germânico, herança dos bares de imigrantes que se multiplicaram pelo Brás e pela Mooca.
E o ovo colorido… ah, esse é pura alquimia de boteco: cozido, mergulhado em vinagre, corante e mistério.

🥚 Os ícones do tabuleiro boêmio
O ovo rosa é o mascote não oficial da boemia.
Ninguém sabe quem teve a ideia de tingir ovos, mas a teoria mais aceita diz que foi um dono de bar que queria “diferenciar” seu balcão.
Resultado: o ovo virou ímã de curiosos e símbolo de coragem — só os fortes enfrentam um ovo de boteco com maionese caseira e copo americano ao lado.

O tremoço, por outro lado, é o snack dos estrategistas: você come um, dois, três, e quando percebe já está filosofando com o garçom sobre a Primeira Academia do Palmeiras, discutido quem era melhor Dudu ou Ademir? E a conversa não acaba.


E o amendoim? É o fio condutor das conversas infinitas — o loop infinito do bar, que nunca termina, só reinicia com mais uma cerveja.

🥩 Salame, mortadela e as carnes frias do balcão
Nas antigas rotisserias e bares do centro, era comum o garçom cortar salame ou mortadela em fatias grossas, servidas com azeitonas e picles, como se fosse um antipasto operário.
E foi assim que o boteco criou sua própria charcutaria popular — rústica, sem frescura, mas com sabor de conversa boa e pão francês amanhecido.

📜 Lendas, histórias e subversões etílicas
Há quem diga que o primeiro ovo colorido paulistano nasceu no Bar do Estadão, nos anos 60, por um erro de cozinha: corante vermelho caído no vinagre.
Outros juram que o tremoço era senha de confiança — só cliente antigo podia se servir à vontade, direto do vidro.
E tem a velha lenda urbana do ovo azul da Barra Funda, que teria derrubado um político em plena campanha.

Nos anos 80, os petiscos ganharam nova vida com o boteco universitário — o ovo rosa virou meme antes da internet, o amendoim virou moeda de troca por histórias e o tremoço, item de sobrevivência entre uma cerveja e outra.

🍋 Adaptações e modernidades indevidas
Chegaram os “botecos gourmet”, e com eles o “tremoço orgânico com flor de sal”, o “ovo caipira curado na beterraba artesanal” e o “mix de embutidos defumados no carvalho”.
Mas o paulistano raiz sabe: petisco bom vem em vidro antigo, com pegador torto, azeite reciclado e risada de balcão.
É o tipo de coisa que não se embeleza — se vive.

💬 Fofoquices do balcão
Conta o garçom Zé da Sé que Cauby Peixoto era freguês fiel do ovo colorido — dizia que dava “sorte antes do show”.
E que o amendoim do Bar Léo já serviu de aperitivo para Vinícius de Moraes, que filosofou: “o boteco é o templo onde o álcool é comunhão e o tremoço, hóstia popular”.

💡 Dicas do Bellacosa Mainframe
Quer viver o protocolo real de um boteco raiz?

  • Peça um copo americano trincado de chope.

  • Escolha um petisco de vidro com tampa de alumínio.

  • Observe o ambiente: cada conserva ali tem mais uptime que muito servidor IBM Z.

  • E lembre-se: nunca confie em quem não come tremoço com a mão.

🖤 Reflexão do El Jefe Midnight Lunch
O petisco de boteco é o mainframe emocional da cidade.
Ele processa saudades, distribui gargalhadas, faz backup de histórias e nunca desliga.
Enquanto houver um ovo rosa num balcão de inox e alguém dizendo “só mais uma”, São Paulo continua rodando estável, firme, resiliente — como um CICS da madrugada.


🍺 Bellacosa Mainframe – porque há mais sabedoria num pote de tremoço do que em muita reunião de diretoria.


sábado, 3 de agosto de 2019

☕💥 A Jornada do Padawan COBOL – Parte 8 Desvendando o Universo dos CALLs no Mainframe

 

Bellacosa Mainframe apresenta o call em COBOL parte VIII

☕💥 A Jornada do Padawan COBOL – Parte 8

Desvendando o Universo dos CALLs no Mainframe

Metal C, DLLs Avançadas, SAF, RACF, APF, Dataspaces, Hiperspaces, Coupling Facility e os Segredos dos Arquitetos Supremos do IBM Z

Ou como descobrir que existe um mundo tão profundo no z/OS que até alguns desenvolvedores COBOL veteranos preferem fingir que ele não existe

Por Vagner Bellacosa – Bellacosa Mainframe


O dia em que o Padawan percebe que ainda estava na entrada da caverna

Depois de sete capítulos aprendendo:

✔ CALL

✔ CICS

✔ Binder

✔ LE

✔ Assembler

✔ SVC

✔ SRB

✔ zIIP

O Padawan acredita ter dominado o Mainframe.

Então um Sysprog aparece.

Abre um membro.

E mostra:

__asm("MODESET KEY=ZERO");

E diz:

Bem-vindo ao mundo dos Arquitetos.


Metal C

Metal C é praticamente uma mistura de:

C

Assembler

z/OS Internals


É C.

Sem Runtime.

Sem libc.

Sem proteção.


Exemplo


#pragma metal


int main()
{

/* acesso direto ao zOS */

}



Onde é usado?

JES

RACF

DFSMS

TCPIP

SAF

SMPE


DLLs no z/OS

Pouca gente sabe.

IBM possui suporte sofisticado.


Exemplo


CALL 'MINHADLL'

USING AREA.



Internamente

Program Objects

DLL Support

LE


Benefícios

Reuso.

Menor memória.

Atualizações independentes.


SAF

Security Authorization Facility


SAF é o porteiro.

Do z/OS.


Aplicação diz:

Posso fazer isso?

SAF responde.

Sim.

Não.

Talvez.


Visualmente



PROGRAMA


↓

SAF


↓

RACF


↓

DECISÃO



RACF

O mago da segurança.


Controla.

Usuários.

Perfis.

Datasets.

CICS.

DB2.

APIs.


Exemplo

PERMIT PROD.LOADLIB


CLASS DATASET



APF

Authorized Program Facility


Território perigoso.


Programa APF

Pode.

Trocar chave.

Executar SVC.

Acessar memória.


Programa comum

Não.


Storage Keys

IBM protege memória.


Keys

0

até

15


Aplicação comum

Key 8

Kernel

Key 0


Dataspaces

Área enorme.

Fora espaço tradicional.


Até GBs.


Muito usada.

SMF.

Analytics.

Sort.


Visualmente


Address Space


↓

Dataspace


↓

Milhões registros



Hiperspaces

Primo rico.

Do Dataspace.


Mais rápido.

Menos I/O.


Coupling Facility

Um dos segredos.

Do Sysplex.


Imagine

20 Mainframes.

Trabalhando juntos.


Coupling Facility

É a memória compartilhada.


Visualmente


LPAR1


↓

CF


↑


LPAR2




Estruturas

Cache

List

Lock


DB2 usa.

Muito.


MQ usa.


CICS usa.


XCF

Cross System Coupling Facility


Permite.

Comunicação.

Entre LPARs.


WLM

Workload Manager


Decide.

Quem recebe CPU.


Banco.

Prioridade alta.


Teste.

Baixa.


PC-Bit

Poucos conhecem.


Permite.

Troca protegida.

Entre espaços.


Muito usado.

RACF.

DB2.


Callable Services

IBM fornece centenas.


Exemplo

IGGCSI00

CSVQUERY

BPXWDYN

IRRSIM00


BPXWDYN

Favorito dos veteranos.


Alocação dinâmica.


Exemplo


CALL 'BPXWDYN'


USING CMD.



Substitui.

SVC99.

Em vários casos.


Segredos Bellacosa

Dica 1

Nunca APF sem necessidade.


Dica 2

Dataspaces são incríveis.


Dica 3

Aprenda SAF.


Dica 4

RACF é obrigatório.


Dica 5

CF é magia pura.


Easter Egg IBM

Existe uma categoria.

De profissionais.

Que consegue ler isto:


MODESET KEY=ZERO


PC 0,15


MODESET KEY=EIGHT


E compreender tudo.


São conhecidos.

Como.

Arquitetos Supremos IBM Z


Checklist Jedi

✅ Metal C

✅ SAF

✅ RACF

✅ APF

✅ Dataspaces

✅ Hiperspaces

✅ Coupling Facility

✅ WLM

✅ XCF

✅ Callable Services

✅ Storage Keys

✅ Program Objects


A Filosofia Jedi do CALL – Parte 8

O Padawan iniciante pensa:

CALL chama programas.

O desenvolvedor experiente pensa:

CALL movimenta dados.

O especialista compreende:

CALL é um mecanismo de integração entre módulos.

O Sysprog entende:

CALL é apenas uma abstração elegante construída sobre registradores, áreas de armazenamento, serviços do supervisor, segurança SAF, gerenciamento de workload, memória compartilhada e décadas de engenharia refinada do z/Architecture.

E o Arquiteto Supremo IBM Z sabe que, quando um desenvolvedor escreve:

CALL 'SUBPGM'
USING WS-AREA

ele está acionando silenciosamente uma cadeia tecnológica composta por compiladores, Binder, LE, Assembly, serviços do z/OS, mecanismos de proteção, subsistemas de segurança e otimizações de hardware capazes de manter funcionando, há décadas, alguns dos sistemas mais críticos do planeta.


Próxima aventura do Padawan COBOL – Parte 9

"As Runas Perdidas do Mainframe: JES2, SMF Internals, SRM, RMF, SRBs enclavados, Sysplex Distributor, HiperSockets, Crypto Express, Telum AI e os segredos dos Engenheiros IBM que poucos profissionais chegam a explorar."


Vagner Renato Bellacosa, IBM Champion e especialista em IBM Mainframe
IBM Z17 SYSTEM ONLINE
Sobre o autor

Vagner Renato Bellacosa

IBM Champion 2026 • Especialista em IBM Mainframe

Vagner Renato Bellacosa trabalha com IBM Mainframe desde 1988 , é IBM Champion e especialista em COBOL, CICS, Db2, z/OS e IBM Z. Compartilha experiências profissionais, conhecimento técnico, história da computação e práticas do universo mainframe para aproximar novas gerações das tecnologias que sustentam empresas, bancos e governos ao redor do mundo.

IBM Champion IBM Z COBOL CICS Db2 z/OS Mainframe desde 1988
GitHub LinkedIn
Inicializando conteúdo...