Undo
                    Os dados de undo são informações necessárias para se reverter ou desfazer efeitos de instruções DML. Quando executamos uma operação de DML em uma transação, o Oracle mantém versões de pré-atualização dos dados (Before Image) em um segmento de undo para que possam ser revertidas automaticamente no caso de erro, ou explicitamente pelo usuário através do comando rollback. Os dados de undo também são importantes para fornecer a leitura consistente, por exemplo, ao fazermos uma consulta no banco de dados, o final dessa consulta deve ser consistente com a versão do banco tal como ele estava no momento que a consulta iniciou. O processo do servidor que executa a consulta lerá os segmentos de undo e construirá o que se chama de “leitura consistente” dos blocos que estão sendo consultados caso eles tenham sido modificados depois que a consulta se iniciou. A partir da versão 9i os dados de undo também são importantes para consultas em flashback. Flashback é uma funcionalidade que permite consultar uma imagem do passado de um banco de dados. Durante o recovery do banco de dados os dados de undo também são usados para desfazer quaisquer transações não cometidas que foram aplicadas para os datafiles. Sem dúvida os dados de undo são de extrema importância para o correto funcionamento de um banco de dados Oracle. Os dados de undo são usados para:


  • Desfazer transações quando a instrução ROLLBACK é emitida.
  • Recuperar um banco de dados.
  • Fornecer uma leitura consistente.
  • Consultar dados a partir de um ponto anterior no tempo usando Oracle Flashback Query.
  • Recuperar corrupções lógicas usando Oracle Flashback Features.

Tablespace de undo

                O ideal é criar uma tablespace de undo no momento da criação do banco de dados, pois quando a instância inicializa o banco de dados automaticamente seleciona a primeira tablespace de undo disponível. Se nenhuma tablespace estiver disponível então a instância inicia e armazena seus registros de undo na tablespace system. Isso pode resultar em graves problemas de perfomance.

                Uma tablespace de undo pode ser criada como qualquer outra tablespace, mas com algumas limitações. Após a criação da tablespace podemos fazer operações comuns como: mover ou redimensionar datafiles, adicionar datafiles, mas não podemos, por exemplo, tornar uma tablespace read-only (somente leitura). A partir da versão 9i a Oracle fornece um mecanismo totalmente automatizado chamado “Automatic Undo Management” o que significa que o servidor automaticamente gerencia os segmentos de undo e alocação de extends conforme necessários. Para habilitar o “Automatic Undo Management” basta definir o parâmetro “undo_management” para “auto”. Por padrão esse parâmetro tem o valor “manual”

             Podemos criar quantas tablespaces de undo forem necessárias, mas somente uma pode está ativa no momento. Quando uma transação se inicia o Oracle atribui a ela um segmento de undo e a medida que essa transação cresce o Oracle adicionará um novo extend a esse segmento de modo que a transação possa continuar. Quando a carga de trabalho diminuir o Oracle encolherá e excluirá os segmentos, novamente de forma automática. Os dados de undo podem ser divididos em dois modos: undo ativo e o undo expirado. O undo “ativo” são os dados que são necessários para desfazer transações que estão sendo executadas. Os dados ativos nunca podem ser sobrescritos até que a transação se complete. O undo “expirado” são os dados já escritos em disco, que o Oracle não é mais obrigado a armazenar, mas esses dados podem ser necessários para leituras consistentes se houver consultas demoradas sendo executadas. Os segmentos de undo são usados de forma circular, pois ao se emitir um COMMIT os dados de undo que representavam a before imagem da transação são marcados como “expirados”, ou seja, esse dado não é mais necessário para se desfazer a transação em curso, então estes dados podem ser sobrescritos. Mas esse comportamento pode complicar caso esse dado expirado seja necessário para garantir uma leitura consistente de uma transação demorada ainda em curso. Neste caso o Oracle irá se possível estender a tablespace em vez de sobrescrevê-lo.

Problemas envolvendo tablespaces de undo

  • O dimensionamento da tablespace de undo é um dos passos mais importantes no momento da criação da base de dados, pois o planejamento para o tamanho da tablespace de undo deve refletir o número de transações e o tamanho ideal para acomodar a consulta mais demorada. Sempre deve haver espaço disponível para que todas as transações continuem e que todas as consultas tenham sucesso. È importante ter espaço adicional para que não seja preciso sobrescrever dados expirados que ainda são necessários para leituras consistentes de grandes consultas. Se não tiver espaço disponível para estender uma transação em curso, os dados expirados irão ser sobrescritos e as consultas demoradas que precisam desse dado expirado irão receber o famoso erro “ORA-1555, snapshot too old”. Se uma transação precisar estender o seu segmento de undo e não tiver espaço disponível, por exemplo, a tablespace não tem mais espaço livre, ou não contém dados de undo expirados, a transação falhará com o erro “ORA-30036, unable to extend segment in undo tablespace” a instrução que se deparou com erro será desfeita, mas o restante da transação permanece intacto e não escrito em disco. Lembrando que o algoritmo que atribui espaço para os segmentos de undo determina que o erro “ORA-30036”só surgirá caso a tablespace de undo não consiga se auto-estender ou contenha somente dados de undo não expirados, ou seja, contém a transações ativas que estão usando dados de undo não expirados, essas transações não podem ser sobrescritas. O erro “ORA-1555” será emitido caso uma consulta falha na consistência de leitura, ou seja, ela atingiu um bloco que foi modificado desde que a consulta iniciou e ao se dirigir ao segmento de undo para buscar a versão anterior a modificação (before image), esse dado havia sido sobrescrito. Existem alguns parâmetros que controlam como esse algoritmo deve se comportar em algumas situações. São eles:
  • undo_management: Esse parâmetro define como será feito o gerenciamento de segmentos de undo. Por padrão esse parâmetro tem o valor “manual”, ou seja, o gerenciamento dos segmentos de undo será totalmente de responsabilidade do DBA. Esse padrão é imposto por questões de compatibilidade com versões antigas. A Oracle recomenda fortemente que se use o “Automatic Undo Management” por motivos de desempenho e administração, para usar a recomendação da Oracle defina esse parâmetro com o valor “auto”. Esse parâmetro é estático, ou seja, é preciso desligar a instância para fazer a sua modificação.
  • undo_tablespace: Esse parâmetro é usado para indicar para instância qual é a tablespace de undo que será usada para armazenar os segmentos de undo. Esse parâmetro é dinâmico, ou seja, pode ser alterado sem que seja preciso desligar a instância.
  •  undo_retention: Esse parâmetro define em segundos um “alvo” que a instância tentará garantir que os dados expirados que sejam necessários para garantir a leitura consistente de uma consulta. Por exemplo, uma consulta demora cerca de 40minutos para se executar, para que o Oracle tente não sobrescrever os dados expirados necessários para essa consulta, podemos definir esse parâmetro para 2400 (40 x 60). Neste caso estamos definindo um tempo em segundos para que o Oracle tente manter esses dados expirados. Caso a tablespace de undo não contenha mais espaço para se estender, o Oracle não irá garantir essa retenção definida, pois como dito antes, esse valor é um alvo, ou seja, uma tentativa. Se a tablespace não puder ser estendida, os dados expirados serão sobrescritos da mesma forma.

                Vale lembrar que por padrão o Oracle sempre tenta manter as transações em curso, isso significa que se uma transação precisar de mais espaço para estender seu segmento de undo e não tiver esse espaço disponível, o Oracle irá sobrescrever os dados expirados, e se esse dado expirado for necessário para leitura consistente de uma consulta, essa receberá o erro “ORA-1555, snapshot too old ”. Isso mostra que por padrão as transações em curso têm preferência sobre as consultas.

                Esse comportamento pode mudar caso habilitamos a garantia de retenção. Essa opção está disponível a partir da versão 10g e dita que nunca serão sobrescritos os dados até que se tenha transcorrido o tempo especificado no parâmetro undo_retention. Isso significa que todas as consultas se completarão com sucesso, desde que elas terminem dentro do tempo de retenção. Um exemplo válido seria: O parâmetro undo_retention está definido com o valor 2400, e a opção de retenção garantida habilitada. Uma consulta que demora cerca de 40 minutos terá sucesso independente se outras transações ativas estão precisando de segmentos de undo disponíveis. As transações ativas irão receber o erro “ORA-30036, unable to extend segment in undo tablespace” caso a tablespace não puder se estender. Para testar o que estou falando vou fazer algumas simulações, vamos para parte mais legal.