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 |
log file sync alto quase sempre é código, não discoUm 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
- 1. Oracle Database
- 3. Redo, Undo e Consistência de Leitura
- 4. Otimizador, Planos e Bind Variables
- 5. RAC, Data Guard e Alta Disponibilidade
- 2. Arquitetura de Processos e Memória
- 1. PostgreSQL vs MySQL vs Oracle
Parte de MOC Oracle · Concepts Guide (docs)