Control Interval — a unidade de I/O
O Control Interval (CI) é a unidade mínima de transferência entre disco e memória no VSAM. Toda vez que o VSAM precisa ler ou gravar dados, ele movimenta um CI inteiro — mesmo que o programa precise de um único registro.
Um CI contém:
┌─────────────────────────────────────────────────────────┐
│ CI = CISZ bytes (ex: 4096 bytes) │
│ │
│ ┌──────────┬──────────┬──────────┬───────┬────┬────┐ │
│ │ Registro │ Registro │ Registro │ │RDF │CIDF│ │
│ │ 1 │ 2 │ 3 │ Free │ │ │ │
│ │ (120 B) │ (120 B) │ (120 B) │ space │ 3B │ 4B│ │
│ └──────────┴──────────┴──────────┴───────┴────┴────┘ │
│ │
│ Dados → crescem da esquerda para a direita │
│ RDF+CIDF → ficam sempre no final (direita) │
└─────────────────────────────────────────────────────────┘
O tamanho do CI é definido no parâmetro CONTROLINTERVALSIZE (ou CISZ) do IDCAMS. Se não especificado, o VSAM escolhe automaticamente com base no tamanho do registro e do track do disco.
CIDF e RDF — os campos de controle
Ao final de cada CI existem campos de controle que o VSAM usa internamente — nunca acessíveis pelo programa de aplicação:
CIDF — Control Interval Definition Field (4 bytes)
Um por CI. Descreve o espaço livre disponível no CI:
| Campo no CIDF | Conteúdo |
|---|---|
| Offset do freespace | Byte onde começa o espaço livre dentro do CI |
| Tamanho do freespace | Quantos bytes livres existem no CI |
RDF — Record Definition Field (3 bytes cada)
Um ou mais RDFs por CI, um para cada registro (em registros de comprimento fixo há apenas dois RDFs). Cada RDF descreve um registro:
| Campo no RDF | Conteúdo |
|---|---|
| Comprimento do registro | Tamanho em bytes do registro descrito |
| Contador de repetições | Quantos registros consecutivos têm esse mesmo tamanho (otimização para registros fixos) |
Control Area — agrupando CIs
Uma Control Area (CA) é um conjunto de CIs contíguos no disco. O VSAM aloca espaço em CAs — não em CIs individuais. Quando o dataset precisa de mais espaço (secondary allocation), o VSAM aloca uma nova CA completa.
Dataset VSAM
├── CA 1 (ex: 1 cylinder)
│ ├── CI 1 [reg A, reg B, reg C | freespace | RDF RDF RDF | CIDF]
│ ├── CI 2 [reg D, reg E | freespace | RDF RDF | CIDF]
│ ├── CI 3 [freespace completo | | | CIDF] ← CA freespace
│ └── ...
├── CA 2
│ ├── CI 1 [reg F, reg G, reg H | freespace | RDF RDF RDF | CIDF]
│ └── ...
└── ...
O tamanho da CA é determinado pela geometria do disco — geralmente um cilindro. No VSAM moderno com discos virtuais (VDISK/EAV), o conceito de cilindro é abstraído, mas a CA ainda existe como unidade de alocação secundária.
Estrutura do KSDS — dados e índice
Um dataset KSDS tem dois componentes físicos separados no disco:
| Componente | Conteúdo | Nome no IDCAMS |
|---|---|---|
| Data Component | Os registros em si, ordenados pela chave primária, armazenados em CIs e CAs | sufixo .DATA |
| Index Component | Estrutura B-tree com os valores de chave e ponteiros para os CIs correspondentes no Data Component | sufixo .INDEX |
Para localizar um registro por chave, o VSAM faz:
1. Lê o índice (sequence set) → encontra o CI que contém a chave
2. Lê o CI do data component → varre os registros até achar a chave
3. Retorna o registro para o programa
Mínimo: 2 I/Os (1 index + 1 data)
Na prática: índice costuma estar em buffer → 1 I/O (só o data CI)
Freespace — CI% e CA%
O freespace é espaço intencionalmente deixado vazio dentro dos CIs e das CAs no momento da carga inicial do dataset. Esse espaço existe para acomodar inserções futuras sem precisar reorganizar os dados imediatamente.
É definido no IDCAMS com o parâmetro FREESPACE(ci% ca%):
FREESPACE(20 10)
│ │
│ └── 10% de cada CA é reservada como CIs completamente vazios
└────────────── 20% de cada CI é reservado como bytes livres dentro do CI
CI% — freespace dentro do CI
Determina quantos bytes de cada CI ficam livres após a carga inicial. Com FREESPACE(20 0) e CISZ de 4096 bytes:
Bytes disponíveis para dados: 4096 × (1 - 0,20) = 3277 bytes
Bytes reservados como freespace: 4096 × 0,20 = 819 bytes
Quando um novo registro é inserido numa posição já existente, o VSAM usa esse espaço livre para encaixá-lo sem mover dados para outro CI.
CA% — freespace dentro da CA
Determina quantos CIs de cada CA ficam completamente vazios após a carga inicial. Com FREESPACE(0 10) e uma CA com 20 CIs:
CIs com dados: 20 × (1 - 0,10) = 18 CIs
CIs completamente vazios: 20 × 0,10 = 2 CIs
Esses CIs vazios são usados quando um CI fica completamente cheio e não cabe mais nenhum registro — o que desencadeia um CI Split.
Escolhendo CI% e CA% na prática
| Perfil de uso | CI% | CA% | Justificativa |
|---|---|---|---|
| Somente leitura (tabela de referência) | 0 | 0 | Sem inserções — maximiza densidade e reduz I/Os |
| Poucas inserções distribuídas | 10–15 | 5 | Absorve inserções sem splits frequentes |
| Muitas inserções aleatórias | 20–30 | 10–15 | Dataset transacional com INSERT intenso |
| Cargas em ordem crescente de chave | 0 | 0 | Inserções no final nunca causam splits no meio |
CI Split — quando o CI fica cheio
Um CI Split ocorre quando o VSAM precisa inserir um registro em um CI que não tem freespace suficiente para acomodá-lo. O VSAM então:
Antes do CI Split:
┌─────────────────────────────────────┐
│ reg A │ reg B │ reg C │ reg D │ sem │
│ (10) │ (10) │ (10) │ (10) │ esp │
└─────────────────────────────────────┘
↑ inserir reg B2 aqui — não há espaço!
Depois do CI Split:
┌──────────────────────────┐ ┌──────────────────────────┐
│ reg A │ reg B │ reg B2 │ │ reg C │ reg D │ free │
└──────────────────────────┘ └──────────────────────────┘
CI original (metade dos dados) CI novo (metade restante)
↑ veio do CA freespace
O VSAM move aproximadamente metade dos registros do CI original para um CI vazio da CA (do CA freespace). Depois encaixa o novo registro na posição correta.
CA Split — quando a CA fica cheia
Um CA Split ocorre quando um CI Split não pode ser completado porque a CA não tem mais nenhum CI vazio (CA freespace esgotado). O VSAM então:
1. Aloca uma nova CA (secondary extent)
2. Move aproximadamente metade dos CIs da CA cheia para a nova CA
3. Executa o CI Split normalmente no espaço liberado
4. Atualiza o índice para refletir a nova organização
Escolhendo o tamanho do CI
O CONTROLINTERVALSIZE (CISZ) influencia diretamente a performance de leitura e escrita. Valores válidos são múltiplos de 512, de 512 até 32768 bytes (para o data component). O index component tem CISZ menor, geralmente 512 ou 1024.
| CI maior | CI menor |
|---|---|
| Mais registros por I/O → melhor para leitura sequencial | Menos registros por I/O → melhor para acesso aleatório |
| CI Split move mais dados → mais custoso | CI Split move menos dados → mais barato |
| Mais dados em buffer → mais registros em cache | Menos overhead de buffer |
| Indicado para relatórios, cargas batch | Indicado para transações CICS de acesso direto |
Cálculo orientativo do CISZ
Fórmula básica para KSDS:
CISZ = (registros por CI desejados × tamanho do registro)
+ (registros por CI × 3 bytes de RDF)
+ 4 bytes de CIDF
+ freespace CI%
Exemplo: registro de 200 bytes, 15 registros por CI, 20% freespace
CISZ mínimo = (15 × 200) + (15 × 3) + 4 = 3049 bytes
Com 20% freespace: 3049 / 0,80 = 3812 bytes
→ arredondar para o próximo múltiplo de 512: CISZ = 4096
Monitorando com LISTCAT
O comando LISTCAT do IDCAMS exibe as estatísticas de uso de um dataset VSAM. É a principal ferramenta para identificar fragmentação e necessidade de reorganização.
//* JCL para LISTCAT com estatísticas detalhadas
//LISTCAT EXEC PGM=IDCAMS
//SYSPRINT DD SYSOUT=*
//SYSIN DD *
LISTCAT ENTRIES(BANCO.PROD.CNTFILE) -
ALL
/*
Os campos mais importantes na saída do LISTCAT para monitorar saúde do dataset:
| Campo no LISTCAT | Significado | Sinal de alerta |
|---|---|---|
| CI-SPLITS | Total de CI Splits desde a última reorganização | Crescimento rápido indica freespace insuficiente |
| CA-SPLITS | Total de CA Splits desde a última reorganização | Qualquer valor > 0 merece atenção; > 10 indica necessidade urgente de REORG |
| EXTENTS | Número de extents alocados | > 5 extents indica fragmentação física severa |
| REC-TOTAL | Total de registros no dataset | Comparar com REC-DELETED para ver densidade real |
| REC-DELETED | Registros marcados como deletados (slots vazios) | Alto REC-DELETED com baixo REC-TOTAL = desperdício de espaço |
| FREESPACE-%CI | Percentual atual de freespace nos CIs | Muito baixo = risco de splits iminentes |
| FREESPACE-%CA | Percentual atual de freespace nas CAs | Zero = próximo CA Split causará alocação de extent |
* trecho típico de saída do LISTCAT ALL
DATA ---BANCO.PROD.CNTFILE.DATA
STATISTICS
REC-TOTAL-----------1250000
REC-DELETED-----------12500
CI-SPLITS--------------3821 ← alto! freespace CI% muito baixo
CA-SPLITS----------------47 ← crítico! reorganizar urgente
ALLOCATION
SPACE-TYPE----------CYLINDER
SPACE-PRI----------------100
SPACE-SEC-----------------20
EXTENTS-------------------14 ← muito fragmentado
Quando reorganizar
Reorganizar um dataset VSAM significa exportar todos os registros em ordem de chave e reimportá-los para um dataset novo (ou para o mesmo após deletar e recriar). Isso elimina fragmentação, restaura o freespace definido e consolida os extents.
| Indicador | Ação recomendada |
|---|---|
| CA-SPLITS > 10 | Reorganização urgente |
| EXTENTS > 5 | Reorganização em breve |
| Degradação visível de tempo de resposta em transações CICS | Investigar CI/CA-SPLITS e EXTENTS; reorganizar se confirmado |
| REC-DELETED > 20% de REC-TOTAL | Muitos slots vazios desperdiçando espaço; reorganizar |
| Dataset com carga batch noturna e zero inserções durante o dia | Reconstruir do zero toda noite com REPRO — mais eficiente que freespace |
A reorganização em si é feita com o IDCAMS — seja com REPRO (cópia) ou com o par DELETE + DEFINE + REPRO. O artigo seguinte cobre esses comandos em detalhe.
IMBED (guardar o sequence set do índice no primeiro track de cada CA) e REPLICATE (duplicar o sequence set em cada track da CA) para reduzir I/Os de índice. Esses parâmetros são obsoletos em DFSMS moderno — o gerenciador de buffers resolve o mesmo problema de forma mais eficiente. Se você os encontrar em JCLs antigos, ignore-os com segurança.