trilha

Tecnologias/02 - Bancos de Dados/01 - Relacionais/03 - Oracle6 min

Instance, SGA e Processos

Conceito

A distinção que confunde todo mundo no primeiro dia

DATABASE  = os ARQUIVOS no disco (datafiles, control files, redo logs)
INSTANCE  = a MEMÓRIA (SGA) + os PROCESSOS que servem aqueles arquivos

Normalmente é 1:1. Mas:

  • RAC: várias instances (em máquinas diferentes) servindo um database.
  • Uma instance pode subir sem montar database (STARTUP NOMOUNT), o que é como se faz recuperação.

Daí os estágios de inicialização, que aparecem em todo procedimento de DBA:

SHUTDOWN → NOMOUNT (só SGA + processos) → MOUNT (leu o control file)
         → OPEN (datafiles abertos, usuários entram)

A SGA: memória compartilhada, componente por componente

Componente Função Análogo
Buffer cache páginas de dados shared_buffers / buffer pool
Shared pool → library cache planos de execução e SQL parseado — (o Postgres não compartilha planos entre sessões!)
Shared pool → data dictionary cache metadados cache de catálogo
Redo log buffer redo antes do disco wal_buffers
Large pool backup, paralelismo, shared server —
Java pool / Streams pool JVM interna, replicação —
In-Memory Column Store colunar em RAM (opção paga) —

A library cache é o componente sem equivalente direto e o que gera mais surpresa: no Oracle, planos de execução são compartilhados entre sessões. Isso é uma otimização enorme (parsear SQL é caro) e a origem do problema mais clássico do produto — SQL sem bind variables entope a library cache. Ver 4. Otimizador, Planos e Bind Variables.

A PGA: memória privada por sessão

Área Função
Sort area ORDER BY, GROUP BY, hash join
Session memory variáveis, informação de sessão
Cursor state cursores abertos

O gerenciamento moderno é automático:

ALTER SYSTEM SET MEMORY_TARGET = 12G;        -- SGA + PGA automáticos (mais simples)
-- ou, com mais controle:
ALTER SYSTEM SET SGA_TARGET = 8G;
ALTER SYSTEM SET PGA_AGGREGATE_TARGET = 4G;
ALTER SYSTEM SET PGA_AGGREGATE_LIMIT = 6G;   -- teto rígido: mata a sessão abusiva

Compare com o Postgres: lá, work_mem é um limite por operação que você multiplica mentalmente pelo número de conexões. Aqui, PGA_AGGREGATE_TARGET é um orçamento global que o banco distribui. O modelo Oracle é mais seguro contra OOM e menos previsível por query.

Os processos de fundo

Processo Função Se ele morre
SMON recuperação de instância, coalescência instância inutilizável
PMON limpa após sessão morta, registra no listener conexões órfãs acumulam
DBWn grava buffers sujos nos datafiles escrita para
LGWR grava o redo log buffer no disco COMMIT para
CKPT atualiza cabeçalhos no checkpoint recuperação mais longa
ARCn arquiva redo logs cheios banco congela se ARCHIVELOG e o destino encher
MMON/MMNL AWR: coleta e snapshots perde histórico de diagnóstico
LREG registra serviços no listener clientes não conectam

LGWR é o processo do caminho crítico: todo COMMIT espera ele. E ARCn é o processo que mais causa incidente por motivo bobo — se o destino de arquivamento enche, o banco para de aceitar transações (ele não pode reciclar um redo log que ainda não foi arquivado).

Multitenant: CDB e PDB

Desde o 12c, a arquitetura é multitenant e, desde o 21c, é a única (não existe mais "non-CDB"):

CDB (container database)  ← uma SGA, um conjunto de processos, um redo
├── CDB$ROOT              ← metadados comuns
├── PDB$SEED              ← template
├── PDB "vendas"          ← um "banco" completo, com seus schemas
└── PDB "financeiro"

O ganho é consolidação: N bancos compartilham memória e processos, e um PDB pode ser desconectado de um CDB e conectado em outro (unplug/plug) — inclusive como método de upgrade e de migração para a nuvem.

ALTER SESSION SET CONTAINER = vendas;   -- o comando que você vai usar toda hora
SELECT name, open_mode FROM v$pdbs;

Trade-offs

Plano compartilhado é ótimo e frágil. Reaproveitar plano economiza CPU de parse e memória. Em troca: um plano ruim gerado a partir de um valor de bind atípico é reutilizado por todas as sessões (bind peeking), e SQL literal fragmenta a library cache até dar ORA-04031.

Memória automática esconde e simplifica. MEMORY_TARGET funciona bem para a maioria dos casos e dificulta o diagnóstico quando não funciona — o banco realoca sozinho entre buffer cache e shared pool, e você vê o efeito sem ver a causa.

Multitenant consolida recursos e acopla destinos. PDBs compartilham SGA, processos e redo: um PDB abusivo afeta os vizinhos. Existem Resource Manager e limites por PDB, e é mais uma coisa para configurar.

O trade-off central: o Oracle centraliza recursos (memória, planos, processos) para obter eficiência global, e paga com acoplamento — uma sessão mal comportada, um SQL sem bind ou um PDB voraz têm efeito no servidor inteiro. É o oposto do Postgres, onde o isolamento por processo limita o dano e desperdiça recurso.

Exemplo prático

As views de diagnóstico que você usa todo dia

-- panorama de memória: como a SGA está dividida agora
SELECT component, current_size/1024/1024 AS mb, min_size/1024/1024 AS min_mb
  FROM v$sga_dynamic_components WHERE current_size > 0;

-- sessões ativas e o que cada uma espera (o "pg_stat_activity" do Oracle)
SELECT s.sid, s.serial#, s.username, s.status, s.event, s.wait_class,
       s.seconds_in_wait, s.sql_id, s.machine, s.program
  FROM v$session s
 WHERE s.type = 'USER' AND s.status = 'ACTIVE'
 ORDER BY s.seconds_in_wait DESC;

-- as classes de espera dominantes (onde o tempo do banco vai)
SELECT wait_class, total_waits, ROUND(time_waited/100) AS segundos
  FROM v$system_wait_class
 WHERE wait_class <> 'Idle' ORDER BY time_waited DESC;

-- pressão na library cache (bind variables!)
SELECT namespace, gets, gethitratio, pins, reloads, invalidations
  FROM v$librarycache WHERE namespace = 'SQL AREA';

As classes de espera e o que fazem pensar

wait_class Interpretação
User I/O (db file sequential read) leitura por índice; normal, ou índice ruim
User I/O (db file scattered read) full table scan — investigue o plano
Concurrency (latch: shared pool) SQL sem bind variables fragmentando a library cache
Concurrency (buffer busy waits) contenção no mesmo bloco: sequência, tabela quente
Commit (log file sync) COMMIT esperando LGWR: disco de redo lento, ou commit por linha em loop
Configuration (log file switch) redo logs pequenos ou arquivamento atrasado
Application (enq: TX - row lock contention) lock de linha: é a aplicação, não o banco
O log file sync alto quase sempre é código, não disco

Um COMMIT dentro de um laço que insere 100 mil linhas produz 100 mil fsync. A correção é agrupar em transações maiores (ou usar FORALL), não trocar o storage. Ver 6. PL-SQL na Prática.

Como isso falha em produção

Erro/sintoma Causa
ORA-04031: unable to allocate shared memory shared pool fragmentado por SQL literal
Banco congelou, sem erro no app destino de ARCHIVELOG cheio; ARCn não consegue arquivar
ORA-00020: maximum number of processes exceeded PROCESSES insuficiente ou vazamento de conexão no app
log file sync dominando commit em loop, ou redo em disco lento
Latência subiu sem mudar nada MEMORY_TARGET realocou SGA; ou plano compartilhado mudou
ORA-01017/ORA-28000 em massa senha expirada por profile (política corporativa)
Uma sessão consumiu a PGA toda falta PGA_AGGREGATE_LIMIT

Aprofundamento aplicado

Seguir uma alteração do cliente ao armazenamento

Uma atualização precisa localizar os blocos, construir informação de undo, modificar o estado em memória e produzir redo. A confirmação depende da persistência de redo conforme a configuração; não exige que cada bloco de dados modificado já tenha sido escrito em seu local definitivo.

Isso separa dois sintomas: espera na confirmação pode envolver o caminho de redo; pressão de escrita de blocos pode envolver o trabalho dos escritores e o armazenamento. Apenas aumentar a SGA não corrige necessariamente nenhum deles.

Recurso Pergunta durante um incidente
Buffer cache As páginas úteis estão sendo reutilizadas?
Shared pool Há excesso de parse ou muitos SQLs quase idênticos?
PGA e temporários Sorts e hashes excedem a memória disponível?
Redo e armazenamento A persistência das confirmações acompanha o volume?

Exercício: explique por que matar um processo cliente, reiniciar uma instância e perder um datafile são eventos diferentes. Resultado esperado: diferencie sessão, memória da instância e arquivos persistentes, ligando cada falha ao tipo de recuperação.

Referência: processos e estruturas de memória.

Relacionado


Parte de MOC Oracle · Concepts Guide (docs)

Buscar

Busca por título, seção e texto das notas