Tecnologias/02 - Bancos de Dados/01 - Relacionais/03 - Oracle7 min
Redo, Undo e Consistência de Leitura
Conceito
O Oracle implementa MVCC como o InnoDB — versões antigas no undo — mas com um mecanismo de leitura mais explícito e um erro famoso que sai dele.
SCN: o relógio lógico do banco
O SCN (System Change Number) é um contador monotônico que marca cada mudança confirmada. Ele é o equivalente do LSN do Postgres e aparece em tudo: recuperação, Data Guard, Flashback, consistência de leitura.
Consistência de leitura, passo a passo
Quando sua query começa, o Oracle registra o SCN atual. Ao ler um bloco:
o bloco contém mudança com SCN > o meu SCN de início?
└─ sim → vá ao UNDO e RECONSTRUA o bloco como ele era no meu SCN
(isso se chama "consistent read" — CR)
└─ não → leia direto
Duas consequências importantes:
- Leitura nunca bloqueia escrita e vice-versa — o slogan histórico da Oracle, e é verdade.
- Reconstruir custa I/O de undo. Uma query longa sobre uma tabela muito alterada faz muito trabalho de reconstrução, mesmo lendo "pouco".
ORA-01555: snapshot too old
O undo é circular: espaço de transações confirmadas é reciclado quando alguém precisa. Se sua query longa pede uma versão antiga cujo undo já foi sobrescrito, o Oracle não tem como reconstruir — e falha:
14:00 query começa (SCN = 1000)
14:02 outras transações alteram a tabela, confirmam, e o undo delas expira
14:35 a query chega naquele bloco e precisa da versão do SCN 1000
→ ORA-01555
O erro é sempre a mesma combinação: query longa + tabela quente + undo pequeno. As saídas, em ordem de preferência:
-- 1) encurtar a query (a correção de verdade)
-- 2) dar retenção suficiente ao undo
ALTER SYSTEM SET UNDO_RETENTION = 10800; -- segundos (3 h)
ALTER TABLESPACE undotbs1 RETENTION GUARANTEE; -- prioriza retenção
-- (⚠ pode fazer DML falhar por falta de undo)
-- 3) aumentar o undo tablespace
E o antipadrão histórico que causa o erro: COMMIT dentro do laço que percorre um
cursor. Cada commit libera undo que a própria query em andamento ainda vai precisar. Ver
6. PL-SQL na Prática.
Redo, ARCHIVELOG e recuperação
transação → redo log buffer (SGA) → LGWR → redo log online (grupos, circulares)
└→ ARCn → archived redo log (para PITR)
Redo logs online são circulares (tipicamente 3+ grupos, multiplexados em discos
diferentes). Quando o grupo 1 enche, o banco muda para o 2 e ARCn arquiva o 1.
Se o destino de arquivamento enche, ARCn não consegue arquivar; o banco não pode
reciclar o redo online não arquivado; e ele congela toda a atividade de escrita. O
app trava sem erro claro. Monitore %USED do db_recovery_file_dest (a FRA) como
métrica de primeira linha.
-- espaço da Fast Recovery Area: monitore isto
SELECT name, space_limit/1024/1024/1024 AS gb_limite,
space_used/1024/1024/1024 AS gb_usado,
ROUND(100*space_used/space_limit, 1) AS pct
FROM v$recovery_file_dest;
Flashback: o recurso sem equivalente
Como o undo guarda as versões anteriores, o Oracle expõe isso em SQL:
-- consultar o passado (limitado pelo UNDO_RETENTION)
SELECT * FROM pedidos AS OF TIMESTAMP (SYSTIMESTAMP - INTERVAL '10' MINUTE)
WHERE id = 4711;
-- ver todas as versões de uma linha e quem as mudou
SELECT versions_starttime, versions_operation, versions_xid, status
FROM pedidos VERSIONS BETWEEN TIMESTAMP
(SYSTIMESTAMP - INTERVAL '1' HOUR) AND SYSTIMESTAMP
WHERE id = 4711;
-- desfazer um UPDATE errado sem restore (precisa de ROW MOVEMENT habilitado)
ALTER TABLE pedidos ENABLE ROW MOVEMENT;
FLASHBACK TABLE pedidos TO TIMESTAMP (SYSTIMESTAMP - INTERVAL '15' MINUTE);
-- tabela dropada por engano: vem da recycle bin
FLASHBACK TABLE pedidos TO BEFORE DROP;
-- e o nível nuclear: o banco inteiro (exige flashback logs habilitados)
FLASHBACK DATABASE TO SCN 12345678;
FLASHBACK DATABASE reverte o banco todo em minutos, em vez de horas de restore de
backup. É o recurso que mais claramente justifica o preço em ambientes onde RTO é
contratual — ver RTO e RPO e Estratégias de Disaster Recovery.
Trade-offs
Undo dá rollback correto e transação longa envenena o sistema. Diferente do
Postgres (onde a transação longa bloqueia a limpeza e gera
bloat), aqui ela consome retenção de undo e provoca ORA-01555 em outras sessões. O
sintoma aparece longe da causa.
Flashback é maravilhoso e limitado pelo undo. AS OF TIMESTAMP só alcança até
UNDO_RETENTION. Para dias ou semanas atrás é preciso Flashback Data Archive (Total
Recall) — que é opção paga — ou restore de backup.
RETENTION GUARANTEE troca um erro por outro. Ele garante retenção de undo, e quando
o tablespace de undo lota, DML começa a falhar (ORA-30036). Você trocou "query longa
falha" por "escrita falha" — decida qual dói menos.
NOARCHIVELOG é mais rápido e indefensável em produção. Sem arquivamento não há PITR:
qualquer recuperação volta ao último backup completo. Só faz sentido em ambiente
descartável.
O trade-off central: o Oracle centralizou no undo três funções — rollback, MVCC e viagem no tempo. Isso é elegante e cria um recurso compartilhado disputado: a mesma configuração que protege a leitura consistente pode derrubar a escrita, e a decisão de dimensionamento é sua.
Exemplo prático
Diagnosticar ORA-01555
-- quem são as transações longas consumindo/segurando undo
SELECT s.sid, s.username, s.event,
t.start_time, t.used_ublk * 8192/1024/1024 AS undo_mb,
ROUND((SYSDATE - TO_DATE(t.start_time,'MM/DD/YY HH24:MI:SS'))*24*60) AS minutos
FROM v$transaction t JOIN v$session s ON s.saddr = t.ses_addr
ORDER BY t.start_time;
-- o histograma de uso de undo: quanto de retenção eu REALMENTE tenho?
SELECT begin_time, tuned_undoretention,
undoblks, maxquerylen AS maior_query_seg, ssolderrcnt AS erros_01555
FROM v$undostat ORDER BY begin_time DESC FETCH FIRST 12 ROWS ONLY;
maxquerylen vs tuned_undoretention é a comparação decisiva: se a maior query dura mais
que a retenção efetiva, ORA-01555 é questão de tempo.
Recuperação: os dois níveis
-- erro de aplicação em uma tabela (minutos atrás): Flashback resolve
FLASHBACK TABLE pedidos TO TIMESTAMP (SYSTIMESTAMP - INTERVAL '20' MINUTE);
-- perda de datafile / corrupção: RMAN
-- $ rman target /
-- RMAN> RESTORE DATABASE;
-- RMAN> RECOVER DATABASE UNTIL TIME "TO_DATE('2026-09-08 14:31','YYYY-MM-DD HH24:MI')";
-- RMAN> ALTER DATABASE OPEN RESETLOGS;
Configuração defensável
-- arquivamento ligado, com dois destinos
ALTER SYSTEM SET LOG_ARCHIVE_DEST_1 = 'LOCATION=USE_DB_RECOVERY_FILE_DEST';
ALTER SYSTEM SET DB_RECOVERY_FILE_DEST_SIZE = 200G;
-- undo com retenção coerente com a maior query legítima
ALTER SYSTEM SET UNDO_RETENTION = 7200;
-- redo grande o bastante para não trocar de grupo a cada minuto
-- (alvo: uma troca a cada 15-20 min em pico)
SELECT group#, bytes/1024/1024 AS mb, members, status FROM v$log;
-- flashback database, se o RTO justificar o custo em disco
ALTER DATABASE FLASHBACK ON;
ALTER SYSTEM SET DB_FLASHBACK_RETENTION_TARGET = 1440; -- minutos (24 h)
Como isso falha em produção
| Erro/sintoma | Causa |
|---|---|
ORA-01555 snapshot too old |
query longa + undo insuficiente; ou COMMIT dentro do laço do cursor |
| Banco congelado, escrita parada | FRA/destino de archive cheio |
ORA-30036: unable to extend segment in undo tablespace |
RETENTION GUARANTEE + undo pequeno |
log file sync alto |
COMMIT por linha, ou redo em disco lento |
log file switch (archiving needed) |
arquivamento não acompanha a geração de redo |
| Flashback não alcança o momento desejado | UNDO_RETENTION menor que o necessário |
| Recuperação impossível | banco em NOARCHIVELOG |
Aprofundamento aplicado
Uma consulta longa precisa reconstruir o passado
Uma consulta começa em um ponto lógico e outras sessões continuam modificando os dados.
Ao encontrar blocos alterados, o Oracle pode precisar de undo para reconstruir a versão
adequada. Se essa informação não estiver mais disponível, a consulta pode falhar com
ORA-01555; isso não significa que a linha atual desapareceu.
Referência: consistência de leitura.
Cenário: um relatório leva duas horas sobre uma tabela muito atualizada. As opções incluem reduzir a duração por plano e índices, dimensionar retenção/espaço de undo conforme a carga ou executar a análise sobre uma cópia com estratégia própria. Uma réplica ou exportação altera também atualidade e operação, então precisa de contrato.
Exercício: desenhe a linha do tempo com início da consulta, alteração concorrente, reutilização do undo e leitura tardia do bloco. Resultado esperado: localizar a informação histórica necessária e distinguir redo, usado na recuperação, de undo, que participa da reconstrução da visão e do rollback.
Relacionado
- 2. Instance, SGA e Processos
- 4. Otimizador, Planos e Bind Variables
- 6. PL-SQL na Prática
- 3. Redo, Undo e Locks
- 4. MVCC, Tuplas e VACUUM
- 3. MVCC e Isolamento na Prática
- RTO e RPO
Parte de MOC Oracle · Concepts Guide (docs)