Na segunda parte desta série, descrevi a hierarquia estrutural do log de transações. Como este post está preocupado principalmente com os arquivos de log virtuais (VLFs) que descrevi, recomendo que você leia a segunda parte antes de continuar.
Quando tudo estiver bem, o log de transações fará um loop infinito, reutilizando os VLFs existentes. Esse comportamento é o que chamo de natureza circular do log . Às vezes, no entanto, algo vai acontecer para evitar isso, e o log de transações cresce cada vez mais, adicionando mais e mais VLFs. Neste post, vou explicar como tudo isso funciona, ou às vezes não.
VLFs e truncamento de log
Todos os VLFs têm uma estrutura de cabeçalho contendo metadados sobre o VLF. Um dos campos mais importantes na estrutura é o status do VLF, e os valores que nos interessam são zero, o que significa que o VLF está inativo , e dois, significando que o VLF está ativo . É importante porque um VLF inativo pode ser reutilizado, mas um ativo não. Observe que um VLF é totalmente ativo ou totalmente inativo.
Um VLF permanecerá ativo enquanto os registros de log necessários estiverem nele, para que não possa ser reutilizado e substituído (vou abordar os próprios registros de log na próxima vez). Exemplos de motivos pelos quais os registros de log podem ser necessários incluem:
- Há uma transação de longa duração da qual os registros de log fazem parte, portanto, eles não podem ser liberados até que a transação tenha sido confirmada ou finalizada a reversão
- Um backup de log ainda não fez backup desses registros de log
- Essa parte do log ainda não foi processada pelo Log Reader Agent para replicação transacional ou Change Data Capture
- Essa parte do log ainda não foi enviada para um espelho de banco de dados assíncrono ou réplica de grupo de disponibilidade
É importante observar que, se não houver motivos para um VLF permanecer ativo, ele não mudará para inativo novamente até que um processo chamado truncamento de log ocorre – mais sobre isso abaixo.
Usando um log de transações hipotético simples com apenas cinco VLFs e números de sequência de VLF começando em 1 (lembre-se da última vez que na realidade eles nunca o fazem), quando o log de transações é criado, o VFL 1 é imediatamente marcado como ativo, pois sempre houve para ser pelo menos um VLF ativo no log de transações — o VLF no qual os blocos de log estão sendo gravados no momento. Nosso cenário de exemplo é mostrado na Figura 1 abaixo.
Figura 1:Hipotético, novo log de transações com 5 VLFs, números de sequência 1 a 5.
À medida que mais registros de log são criados e mais blocos de log são gravados no log de transações, o VLF 1 é preenchido, portanto, o VLF 2 precisa se tornar ativo para que mais blocos de log sejam gravados, conforme mostrado na Figura 2 abaixo.
Figura 2:a atividade passa pelo log de transações.
O SQL Server rastreia o início da transação não confirmada (ativa) mais antiga e esse LSN é mantido no disco sempre que ocorre uma operação de ponto de verificação. O LSN do registro de log mais recente gravado no log de transações também é rastreado, mas é rastreado apenas na memória, pois não há como persistir no disco sem executar várias condições de corrida. Isso não importa, pois é usado apenas durante a recuperação de falhas, e o SQL Server pode calcular o LSN do “fim” do log de transações durante a recuperação de falhas. Pontos de verificação e recuperação de falhas são tópicos para postagens futuras da série.
Eventualmente, o VLF 2 será preenchido e o VLF 3 ficará ativo e assim por diante. O ponto crucial da natureza circular do log de transações é que os VLFs anteriores no log de transações se tornam inativos para que possam ser reutilizados. Isso é feito por um processo chamado truncamento de log , que também é comumente chamado de limpeza de log . Infelizmente, esses dois termos são terríveis equívocos porque nada é realmente truncado ou limpo.
O truncamento de log é simplesmente o processo de examinar todos os VLFs no log de transações e determinar quais VLFs ativos podem agora ser marcados como inativos novamente, pois nenhum de seus conteúdos ainda é exigido pelo SQL Server. Quando o truncamento de log é executado, não há garantia de que quaisquer VLFs ativos possam ser inativos - depende inteiramente do que está acontecendo com o banco de dados.
Há dois equívocos comuns sobre o truncamento de log:
- O log de transações fica menor (o equívoco de “truncamento”). Não, não há - não há alteração de tamanho do truncamento de log. A única coisa capaz de tornar o log de transações menor é um DBCC SHRINKFILE explícito.
- Os VLFs inativos são zerados de alguma forma (o equívoco de “limpeza”). Não – nada é gravado no VLF quando ele fica inativo, exceto alguns campos no cabeçalho do VLF.
A Figura 3 abaixo mostra nosso log de transações onde os VLFs 3 e 4 estão ativos e o truncamento de log foi capaz de marcar os VLFs 1 e 2 como inativos.
Figura 3:truncamento de log marca VLFs anteriores como inativos.
Quando o truncamento de log ocorre depende de qual modelo de recuperação está em uso para o banco de dados:
- Modelo simples:o truncamento de log ocorre quando uma operação de ponto de verificação é concluída
- Modelo completo ou modelo com log em massa:o truncamento de log ocorre quando um backup de log é concluído (desde que não haja um backup completo ou diferencial simultâneo em execução, caso em que o truncamento de log é adiado até que o backup de dados seja concluído)
Não há exceções para isto.
Natureza Circular do Log
Para evitar que o log de transações tenha que crescer, o truncamento de log deve ser capaz de marcar VLFs como inativos. O primeiro VLF físico no log deve estar inativo para que o log de transações tenha sua natureza circular.
Considere a Figura 4 abaixo, que mostra que os VLFs 4 e 5 estão em uso e o truncamento de log marcou os VLFs 1 a 3 como inativos. Mais registros de log são gerados, mais blocos de log são gravados no VLF 5 e, eventualmente, ele é preenchido.
Figura 4:A atividade preenche o VLF físico mais alto no log de transações. em>
Nesse ponto, o gerenciador de log para o banco de dados verifica o status do primeiro VLF físico no log de transações, que em nosso exemplo é VLF 1, com número de sequência 1. VLF 1 está inativo, portanto, o log de transações pode ser agrupado e comece a encher novamente desde o início. O gerenciador de log altera o primeiro VLF para ativo e aumenta seu número de sequência para ser um maior que o número de sequência de VLF mais alto atual. Portanto, torna-se VLF 6 e o registro continua com o bloco de log sendo gravado nesse VLF. Essa é a natureza circular do log, conforme mostrado abaixo na Figura 5.
Figura 5:a natureza circular do log de transações e a reutilização de VLF.
Quando as coisas dão errado
Quando o primeiro VLF físico no log de transações não está inativo, o log de transações não pode ser contornado, então ele crescerá (desde que esteja configurado para isso e haja espaço em disco suficiente). Isso geralmente acontece porque há algo impedindo que o truncamento de log desative VLFs. Se você achar que o log de transações de um banco de dados está crescendo, você pode consultar o SQL Server para descobrir se há um problema de truncamento de log usando este código simples abaixo:
SELECT [log_reuse_wait_desc] FROM [master].[sys].[databases] WHERE [name] = N'MyDatabase';
Se o truncamento de log foi capaz de desativar um ou mais VLFs, o resultado será NADA. Caso contrário , você receberá um motivo pelo qual o truncamento de log não pôde desativar nenhum VLF. Há uma longa lista de possíveis motivos descritos aqui na seção Fatores que podem atrasar o truncamento de log.
É importante entender a semântica de qual é o resultado:é o motivo pelo qual o truncamento do log não pôde fazer nada a última vez que tentou executar . Por exemplo, o resultado pode ser ACTIVE_BACKUP_OR_RESTORE, mas você sabe que esse backup completo de longa duração terminou. Isso significa apenas que na última tentativa de truncamento de log, o backup ainda estava em execução.
Na minha experiência, o motivo mais comum para impedir o truncamento de log é LOG_BACKUP; ou seja, vá realizar um backup de log! Mas também há um comportamento estranho e interessante com LOG_BACKUP . Se você vir continuamente o resultado LOG_BACKUP mas você sabe que os backups de log estão acontecendo com sucesso, é porque há muito pouca atividade no banco de dados e o VLF atual é o mesmo da última vez que um backup de log foi realizado. Então, LOG_BACKUP significa “vá fazer um backup de log” ou “todos os registros de log com backup são do VLF atual, então não pode ser desativado”. Quando o último acontece, pode ser confuso.
Retornando…
Manter a natureza circular do log de transações é muito importante para evitar crescimentos de log dispendiosos e a necessidade de tomar medidas corretivas. Normalmente, isso significa garantir que os backups de log ocorram regularmente para facilitar o truncamento de log e o dimensionamento do log de transações para poder conter operações grandes e de longa duração, como recompilações de índice ou operações de ETL, sem que ocorra crescimento de log.
Na próxima parte da série, abordarei os registros de log, como eles funcionam e alguns exemplos interessantes.