Arquitetura do ESE (Mecanismo de Armazenamento Extensível)

 

Aplica-se a: Exchange Server 2007 SP3, Exchange Server 2007 SP2, Exchange Server 2007 SP1, Exchange Server 2007

Tópico modificado em: 2008-11-19

Os bancos de dados de caixa de correio do Exchange e a fila dos servidores de Transporte de Hub e de Transporte de Borda utilizam banco de dados ESE (Mecanismo de Armazenamento Extensível). O ESE é um gerenciador de tabela do ISAM (Método de Acesso Seqüencial Indexado) para vários usuários com recursos completos de DML (Linguagem de Manipulação de Dados) e DDL (Linguagem de Definição de Dados). O ESE permite que os aplicativos armazenem registros e cria índices para acessar esses registros de formas diferentes.

Há duas versões do ESE:

  • ESENTl   O mecanismo de bancos de dados para Active Directory e vários componentes do Microsoft Windows. Diferentemente de outras versões do ESE (que usam arquivos de log de 5 MB e páginas de 4 KB), a implementação do ESENT para Active Directory usa arquivos de log de 10 MB e páginas de 8 KB.

  • ESE98   Mecanismo de banco de dados do Exchange 2000 Server, Exchange Server 2003 e Exchange Server 2007.

  • O ESE era conhecido anteriormente como JET (Joint Engine Technology) Blue. O JET Blue não é a igual à versão do JET encontrada no Microsoft Access (conhecida como "JET Red").

Transações

O ESE é um mecanismo de banco de dados sofisticado, baseado em transações. Uma transação é uma série de operações que são tratadas como uma unidade atômica (indivisível). Todas as operações de uma transação são concluídas e salvas permanentemente ou, então, nenhuma operação é realizada. Considere, por exemplo, as operações envolvidas ao se mover uma mensagem da Caixa de Entrada para a pasta de Itens Excluídos. A mensagem é excluída de uma pasta, adicionada a outra pasta e as propriedades da pasta são atualizadas. Se ocorrer uma falha, você não deseja que haja duas cópias da mensagem, nenhuma cópia ou valores de propriedade de pasta (como contagem de itens) inconsistentes com o conteúdo real da pasta.

Para evitar problemas como este, o ESE agrupa as operações em uma transação. O ESE verifica se nenhuma operação é aplicada permanentemente até que a transação seja confirmada no arquivo do banco de dados. Quando a transação é confirmada no arquivo do banco de dados, todas as operações são aplicadas permanentemente.

Se o servidor parar de responder, o ESE também faz a recuperação automática quando o servidor é reiniciado e reverte as transações não confirmadas. Se houver uma falha no ESE antes da confirmação de uma transação, toda a transação será revertida e será como se ela nunca tivesse ocorrido. Se o ESE parar de responder após a transação estar confirmada, a transação permanecerá e as alterações serão visíveis para os clientes.

Transações ACID

Transações como as relacionadas na seção anterior normalmente são chamadas transaçõesACID. ACID é um acrônimo dos seguintes atributos:

  • Atômico   Este termo indica que uma alteração de status da transação é tudo ou nada. O status Atômico inclui alterações de bancos de dados e mensagens e ações em transdutores.

  • Consistente   Este termo indica que uma transação é uma transformação correta do estado. As ações adotadas como um grupo não violam nenhuma das restrições de integridade associadas ao estado. Isso requer que a transação seja um programa correto.

  • Isolado   Este termo indica que, mesmo que as transações sejam executadas simultaneamente, para cada transação (t) parece que as outras transações foram executadas antes de t ou depois de t, mas não ambos.

  • Durável   Transações confirmadas são preservadas no banco de dados, mesmo que o sistema pare de responder.

O armazenamento de versão

O armazenamento de versão permite que o ESE rastreie e gerencie as transações atuais. Portanto, o ESE pode passar as partes Isolado e Consistente do teste ACID. O armazenamento de versão mantém uma lista na memória com as modificações feitas no banco de dados.

O armazenamento de versão é utilizado nas seguintes situações:

  • Reversão   Se uma transação precisar ser revertida, ele examina o armazenamento de para obter a lista de operações executadas por ele. Executando o inverso de todas as operações, a transação pode ser revertida.

  • Detecção de conflito de gravação   Se duas sessões diferentes tentarem modificar o mesmo registro, o armazenamento de versão percebe e rejeita a segunda modificação.

  • Leituras passíveis de repetição   Quando uma sessão inicia uma transação, ela sempre encontra a mesma visualização do banco de dados, mesmo que outras sessões modifiquem os registros visualizados. Quando uma sessão lê um registro, o armazenamento de versão é consultado para determinar que versão do registro a sessão deve visualizar. Leituras repetíveis fornecem um nível de isolamento em que, após o cliente iniciar uma transação, ele vê o status do banco de dados conforme ele estava antes da transação ser iniciada, independentemente das modificações feitas por outros clientes ou sessões. As leituras repetíveis são implementadas usando o armazenamento de versão. Com uma lista de modificações feitas ao banco de dados na memória, é possível determinar que visualização de um registro qualquer sessão em particular deve exibir.

  • Adiamento antes do log de imagem   Esta é uma otimização complexa que permite que o ESE registre menos dados do que em mecanismos de bancos de dados similares.

Isolamento instantâneo

Após o início de uma transação, o ESE garante que a sessão exiba uma imagem única e consistente do banco de dados, de acordo com o que ela apresenta no início da transação, mais as alterações. Como outras sessões também podem modificar os dados e confirmar suas transações, estas alterações são invisíveis para qualquer transação iniciada antes da confirmação. Um usuário pode modificar um registro apenas se o usuário estiver visualizando a versão mais recente. Caso contrário, haverá uma falha JET_errWriteConflict na atualização. Versões anteriores à última transação serão automaticamente descartadas.

Os ESE apresenta um nível de isolamento de transação denominado Isolamento instantâneo. O isolamento instantâneo permite que os usuário acessem a última linha confirmada usando uma visualização transicionalmente consistente do banco de dados. O isolamento instantâneo é um algoritmo de controle de simultaneidade descrito pela primeira vez no artigo A Critique of ANSI SQL Isolation Levels (página em inglês). O isolamento instantâneo é implementado pelo ESE usando leituras repetíveis.

Estrutura de banco de dados do ESE

Todos os dados dentro do arquivo de banco de dados em formato rich-text são armazenados em árvores B+. O "B" de árvore B+ significa "equilibrado". "Árvore" se refere a um arranjo similar a uma estrutura de pastas em um sistema de arquivos, onde uma raiz é pai dos itens (páginas de bancos de dados) que, por sua vez, são pais de itens adicionais. As árvores B+ foram desenvolvidas para fornecer acesso rápido aos dados em disco. Como a leitura e a gravação em um disco são muito mais lentas do que a execução dessas operações na memória, uma árvore B+ é dividida em páginas de 8 KB. Isto permite que o ESE obtenha os dados necessários usando o número mínimo de E/Ss de disco. Um banco de dados ESE pode conter até 2 elevado à 31ª potência em páginas de 8 KB para um tamanho total máximo de banco de dados de aproximadamente 16 terabytes. Na verdade, o tamanho do banco de dados é limitado pela sua habilidade de fazer backup, restaurar e executar outras operações de manutenção (como desfragmentação offline e reparos no banco de dados) em tempo hábil.

Páginas do banco de dados

O tamanho de página no ESE é definido pelo aplicativo que a utiliza. Por exemplo, o ESE98 (Exchange 2000 Server e Exchange Server 2003) usa páginas de quatro KB, enquanto o ESENT (Active Directory) usa páginas de oito KB. Cada uma destas páginas de quatro e oito KB contêm apontadores para outras páginas ou para os dados reais armazenados na árvore B+. O apontador e as páginas de dados são misturados no arquivo.

Para melhorar o desempenho sempre que possível, as páginas são armazenadas em cache em um buffer de memória pelo maior tempo possível. Isto reduz a necessidade de consulta ao disco. Cada página começa com um cabeçalho de 40 bytes, que inclui os valores a seguir:

  • pgnoThis   Este valor indica o número da página.

  • DbtimeDirtied   Este valor indica o Dbtime em que a página foi modificada pela última vez.

  • pgnoPrev   Este valor indica o número da página esquerda adjacente da folha.

  • pgnoNext   Este valor indica o número da página direita adjacente da folha.

  • ObjidFDP   Esse valor indica o ID do objeto de uma página especial no banco de dados, denominado FDP (Father of the Data Page), que indica a que árvore B+ esta página pertence. A página FDP é usada nos reparos.

  • cbFree   Este valor indica o número de bytes disponíveis na página.

  • cbUncommittedFree   Este valor indica o número de bytes não confirmados disponíveis (bytes que estão livres, mas podem ser usados para reversão) na página.

  • ibMicFree   Este valor indica o deslocamento da página para o próximo byte disponível no topo da página.

Soma de verificação ECC

A soma de verificação ECC (Error Correcting Code) permite a correção de erros de apenas um bit em páginas de banco de dados (no arquivo .edb).

Ela contém duas somas de verificação de 32 bits. A primeira é uma soma de verificação XOR em que o número da página é usado como propagador no cálculo. A segunda soma de verificação de 32 bits é uma soma ECC, que permite a correção de erros de um único bit na página.

Consistência do banco de dados e erros -1018

Quando uma página é lida, o ESE examina um indicador na página para ver se ela possui o formato correto de soma de verificação. A soma de verificação adequada é então calculada. Se houver uma falha de correspondência no formato da soma de verificação atual, o ESE tentará corrigir o erro. Se o erro não puder ser corrigido automaticamente, o Exchange relatará um erro -1018.

O armazenamento do Exchange pode ser responsável pela auto-geração de um erro -1018, se ele executar uma das ações a seguir:

  • Construir uma página com a soma de verificação incorreta.

  • Construir uma página corretamente, mas informar ao sistema operacional para gravar a página no local incorreto.

Se um administrador de sistema encontrar um erro -1018 ou executar testes de hardware de diagnóstico e estes testes não reportarem problemas, o administrador pode concluir que o Exchange deve ser o responsável por esse problema, pois o hardware passou na análise inicial.

Freqüentemente, investigações adicionais da Microsoft onde fornecedores descobrem problemas sutis em unidades de hardware, firmware ou dispositivos que são responsáveis por danos ao arquivo de banco de dados.

Testes normais de diagnóstico podem não detectar falhas transitórias por diversos motivos. Problemas no firmware ou no software de driver podem não estar ao alcance dos programas de diagnóstico. Os testes de diagnóstico podem não conseguir simular longos tempos de execução ou cargas complexas. Além disso, a adição de monitoramento de diagnóstico ou log de depuração podem mudar o sistema o suficiente para evitar que o problema ocorra novamente.

A simplicidade e a estabilidade dos mecanismos do Exchange que geram somas de verificação e gravam páginas no arquivo de banco de dados sugerem que um erro -1018 provavelmente não seja causado pelo Exchange. Os mecanismos de detecção de página incorreta e soma de verificação são simples e confiáveis, e permanecem essencialmente iguais desde a primeira versão do Exchange, com a exceção de mudanças pequenas para adaptar as alterações de formato de página de banco de dados entre versões de banco de dados.

Uma soma de verificação é gerada para uma página que está prestes a ser gravada em disco após todos os outros dados serem gravados na página, incluindo o próprio número da página. Depois que o Exchange adicionar a soma de verificação à página, o Exchange instruirá o sistema operacional do Microsoft Windows Server a gravar a página em disco usando as APIs padrão publicadas do servidor Windows.

A soma de verificação de uma página pode ser gerada corretamente, mas a página pode ser gravada no local incorreto no disco rígido. Isto pode ser causado por um erro de memória temporário, como um "bit flip." Por exemplo, suponha que o Exchange construa uma nova versão da página 70. Não haverá um erro na página em si, mas a cópia do número da página usado pelo controlador do disco ou pelo sistema operacional será alterado aleatoriamente. Esse problema pode ocorrer se 70 (binário 1000110) tiver sido alterado para 6 (binário 000110) por uma célula de memória instável. A soma de verificação da página continuará correta, mas o local da página no banco de dados estará errado. O Exchange reportará um erro -1018 na página quando detectar que o número lógico da página não corresponde ao local físico da página.

Outro tipo de erro de numeração (causado pelo Exchange) poderá ocorrer se o Exchange gravar o número da página incorreto na página. Isso, entretanto, causa outros erros, não o erro -1018. Se o Exchange gravar 71 na página 70 e então executar a soma de verificação da página corretamente, a página será gravada no local 71 e passará nos testes de soma de verificação e número de página.

Um único erro -1018 relatado em um banco de dados do Exchange geralmente não faz com que o banco de dados do Exchange seja interrompido ou resulte em um sintoma diferente da presença do próprio erro -1018. A página pode estar em uma pasta não acessada com freqüência, como as pastas Itens Enviados ou Itens Excluídos, ou em um anexo que seja raramente aberto ou que esteja vazio.

Mesmo que um único erro -1018 não cause uma perda de dados significativa, os erros -1018 são motivo de preocupação, porque são uma prova de que seu sistema de armazenamento não armazenou ou recuperou dados corretamente pelo menos uma vez. Apesar de o erro -1018 poder ser um problema temporário que nunca mais ocorra, é provável que este erro seja um alerta de um problema que pode vir a se tornar progressivamente pior. Mesmo se o primeiro erro -1018 for relatado para uma página vazia no banco de dados, não será possível saber qual a próxima página que poderá ser danificada. Se uma tabela crítica global estiver danificada, o banco de dados do Exchange poderá não iniciar e o reparo do banco de dados poderá não ser bem-sucedido ou ser parcialmente bem-sucedido.

Após o registro de um erro -1018, considere e planeje a possibilidade de ocorrer uma falha iminente ou um dano aleatório adicional ao banco de dados antes de você localizar e eliminar a principal causa do erro.

Equilíbrio de árvore de banco de dados

Uma das principais funções do ESE é manter a árvore de banco de dados sempre equilibrada. O processo de equilíbrio da árvore é terminado quando todas as páginas estão divididas ou mescladas. Conforme você poderá ver na figura a seguir, o mesmo número de nós do nível raiz está sempre no nível de folha da árvore. Portanto, a árvore está equilibrada.

Árvore equilibrada

Árvore equilibrada

Do ponto de vista do ESE, uma tabela de banco de dados é uma coleção de árvores B+. Cada tabela consiste em uma árvore B+ que contém dados, apesar de poder haver árvores B+ de índice secundário para fornecer diferentes visualizações de dados. Se uma coluna ou um campo se tornar muito largo para caber em uma árvore B+, ele será dividido em uma árvore B+ separada, denominada árvore de valor longo.

A definição dessas tabelas e de suas árvores B+ associadas é armazenada em outra árvore B+, denominada catálogo do sistema. A perda do catálogo do sistema é um problema sério. Portanto, o ESE mantém duas cópias idênticas desta árvore B+ em cada banco de dados.

Divisão

Quando uma página fica quase cheia, cerca de metade dos dados é colocada em uma página secundária e uma chave extra é colocada na página pai da página secundária. O processo é executado a menos que a página pai também esteja cheia. Neste caso, a página pai é dividida e um apontador é adicionado à página pai. Em último caso, todas as páginas do ponteiro até o bloco da raiz podem ter que ser divididas. Se for necessário dividir o bloco da raiz, um nível adicional de páginas será inserido na árvore. De forma figurada, a árvore cresce na altura.

Mesclar

Quando uma página está quase vazia, ela é mesclada com a página adjacente, os apontadores da página pai são atualizados e, se necessário, a página é mesclada. Em último caso, se todos as páginas de apontadores até o bloco de raiz forem mescladas, a árvore encolherá de tamanho. Para chegar a uma folha (dados), o ESE começa no nó da raiz e segue os apontadores da página até chegar ao nó da folha desejado.

Fan-Out

A estrutura de uma árvore B+ no ESE tem um fan-out muito alto. Um fan-out alto significa que o ESE pode chegar a qualquer dado em uma tabela de 50 GB com não mais que quatro leituras de disco (três páginas e apontador e a página de dados em si). O ESE armazena mais de 200 apontadores de página por página de quatro KB, permitindo que o ESE use as árvores com um número mínimo de níveis pai/filho (também chamados de árvores rasas). O ESE também armazena a chave da árvore atual, que permite que o ESE pesquise rapidamente a estrutura da árvore atual. O diagrama precedente é uma árvore com três níveis de pai/filho; uma árvore com quatro níveis de pai/filho pode armazenar muitos gigabytes de dados.

Índices

Uma árvore B+ tradicional é indexada de uma forma particular. Ela usa uma chave e os dados devem ser recuperados com essa chave. Por exemplo, os registros na tabela de mensagens são indexados no identificador único da mensagem, denominado MTS-ID (message transfer service). Entretanto, um usuário provavelmente desejará ver os dados na tabela de mensagens ordenados de uma forma mais amigável.

Os índices, ou, mais especificamente índices secundários, são utilizados para recuperar os dados. Cada índice secundário é outra árvore B+ que mapeia a chave secundária escolhida para a chave primária. Isso torna as árvores B+ pequenas se comparadas aos dados indexados por elas.

Para entender como um índice secundário é utilizado, considere o que ocorre quando um usuário muda as formas como as mensagens são apresentadas em uma pasta. Se você mudar a visualização de uma pasta no Outlook para que a visualização seja orientada por assunto em vez de hora de recebimento, o Outlook fará com que o ESE construa um novo índice secundário na tabela de pasta de mensagens.

Quando você altera as visualizações em uma pasta grande pela primeira vez, haverá um atraso. Se você prestar atenção no servidor, verá um pequeno aumento na atividade de disco. Quando voltar para a visualização anterior, o índice já estará construído e a resposta será muito mais rápida.

As árvores B+ de índices secundárias dos serviços do Microsoft Exchange Information Store existem por oito dias. Se não forem usadas, o serviço do Armazenamento de Informações do Microsoft Exchange as excluirá como operação em segundo plano.

Valores longos

Uma coluna ou um registro no ESE não pode transpor páginas na árvore B+ de dados. Há valores (como PR_BODY, que é o corpo de uma mensagem) que rompem o limite de 4KB por página. Eles são mencionados como valores longos (LV). A árvore B+ de valor longo de uma tabela é usada para armazenar esses valores grandes.

Se um dado for inserido em uma tabela ESE e ele for muito grande para a árvore B+ de dados, ele será dividido em quatro páginas de quatro KB na árvore B+ de valor longo separada da tabela. O registro na árvore B+ de dados contém um apontador para o valor longo. Este apontador é denominado ID de valor longo (LID) e significa que o registro possui um apontador para LID 256.

Formato de registro

Uma coleção de árvores B+ representa uma tabela e uma tabela é uma coleção de linhas. Uma linha também é chamada de registro. Um registro consiste em muitas colunas. O tamanho máximo de um registro, e portanto, o número de colunas exibidas em um único registro, é determinado pelo tamanho da página do banco de dados menos o tamanho do cabeçalho. O ESE possui um tamanho de página de quatro KB. Portanto, o tamanho máximo do registro é aproximadamente de 4,050 bytes (4,096 bytes, menos o tamanho do cabeçalho da página).

Tipo de dados da coluna

Cada definição de coluna deve especificar o tipo de dados armazenado na coluna. O ESE oferece suporte a tipos de dados descritos na tabela a seguir.

Tipos de dados da coluna do mecanismo de armazenamento extensível

Tipo de dados da coluna Descrição

Bit

NULL, 0, ou diferente de 0

Byte não assinado

Inteiro não assinado de 1 byte

Curto

Inteiro assinado de 2 bytes

Curto não assinado

Inteiro não assinado de 2 bytes

Longo

Inteiro não assinado de 4 bytes

Longo não assinado

Inteiro não assinado de 4 bytes

LongLong

Inteiro não assinado de 8 bytes

Moeda

Inteiro não assinado de 8 bytes

IEEE Único

Número de ponto flutuante de 4 bytes

IEEE Duplo

Número de ponto flutuante de 8 bytes

Data e Hora

Data e hora de 8 bytes (data integral, hora fracionária)

GUID

Identificador exclusivo de 16 bytes

Binário

Cadeia de caracteres binários, comprimento <= 255

Texto

Cadeia de caracteres ANSI ou Unicode, comprimento <= 255 bytes

Binário longo

Cadeia de caracteres binários de valor alto, comprimento < 2 GB

Texto longo

Cadeia de caracteres ANSI ou Unicode de valor alto, comprimento < 2 GB

Os tipos de dados da coluna encaixam-se em duas categorias. A primeira categoria é a de colunas fixas e variáveis. A segunda é a de colunas etiquetadas. Cada coluna é definida por uma estrutura FIELD de 16 bytes mais a estrutura do nome da coluna.

Quando uma tabela é criada em um banco de dados do ESE, a tabela é definida com uma matriz de estruturas FIELD. Esta matriz identifica as colunas individuais da tabela. Dentro desta matriz, cada coluna é representada por um valor de índice, denominado ID de coluna. Isto é semelhante a uma matriz simples em que você pode referenciar membros da matriz por ID, como matriz[0], matriz[1] e assim por diante. As colunas são acessadas rapidamente por ID, mas uma pesquisa por nome de coluna requer uma varredura linear pela matriz de estruturas FIELD.

Colunas fixas e variáveis

As colunas fixas contêm um comprimento de dados fixo. Cada registro ocupa uma quantidade definida de espaço de registro, mesmo que nenhum valor seja definido. Os IDs de tipo de dados de 1 a 10 podem ser definidos como colunas fixas. Cada tabela pode definir até 126 colunas fixas (ID de coluna 1 a 127).

As colunas variáveis podem conter até 256 bytes de dados. Uma matriz de deslocamento é armazenada no registro com o conjunto de colunas variáveis mais alto. Cada coluna requer dois bytes. Os IDs de tipo de dados de 10 e 11 podem ser definidos como colunas variáveis. Cada tabela pode definir até 127 colunas variáveis (ID coluna 128 a 256).

Colunas marcadas

O ESE define colunas que ocorrer raramente ou que possuem várias ocorrências em um único registro como colunas marcadas. Uma coluna marcada não definida não incorre em sobrecarga de espaço. Uma coluna marcada pode ter ocorrências repetidas no mesmo registro. Se uma coluna marcada for representada em um índice secundário, cada ocorrência distinta será referenciada pelo índice.

As colunas marcadas podem conter uma quantidade ilimitada e variável de dados. O ID da coluna e o comprimento são armazenados com os dados. Todos os tipos de dados podem ser definidos como colunas marcadas. Cada tabela pode definir até 64.993 colunas marcadas.