Sqlserver
 sql >> Base de Dados >  >> RDS >> Sqlserver

Como você limpa o log de transações do SQL Server?


Tornar um arquivo de log menor deve realmente ser reservado para cenários em que ele encontrou um crescimento inesperado que você não espera que aconteça novamente. Se o arquivo de log crescer para o mesmo tamanho novamente, não será possível reduzi-lo temporariamente. Agora, dependendo das metas de recuperação do seu banco de dados, essas são as ações que você deve executar.

Primeiro, faça um backup completo


Nunca faça alterações em seu banco de dados sem garantir que você possa restaurá-lo caso algo dê errado.

Se você se preocupa com a recuperação pontual


(E por recuperação pontual, quero dizer que você se preocupa em poder restaurar para qualquer coisa que não seja um backup completo ou diferencial.)

Presumivelmente, seu banco de dados está em FULL modo de recuperação. Se não, certifique-se de que é:
ALTER DATABASE testdb SET RECOVERY FULL;

Mesmo se você estiver fazendo backups completos regulares, o arquivo de log crescerá e crescerá até que você execute um log backup - isso é para sua proteção, não para consumir desnecessariamente seu espaço em disco. Você deve executar esses backups de log com bastante frequência, de acordo com seus objetivos de recuperação. Por exemplo, se você tiver uma regra de negócios que afirma que não pode perder mais de 15 minutos de dados em caso de desastre, você deve ter um trabalho que faça backup do log a cada 15 minutos. Aqui está um script que irá gerar nomes de arquivos com carimbo de data/hora com base na hora atual (mas você também pode fazer isso com planos de manutenção etc., apenas não escolha nenhuma das opções de redução nos planos de manutenção, elas são horríveis).
DECLARE @path NVARCHAR(255) = N'\\backup_share\log\testdb_' 
  + CONVERT(CHAR(8), GETDATE(), 112) + '_'
  + REPLACE(CONVERT(CHAR(8), GETDATE(), 108),':','')
  + '.trn';

BACKUP LOG foo TO DISK = @path WITH INIT, COMPRESSION;

Observe que \\backup_share\ deve estar em uma máquina diferente que represente um dispositivo de armazenamento subjacente diferente. Fazer backup deles na mesma máquina (ou em uma máquina diferente que usa os mesmos discos subjacentes ou em uma VM diferente que esteja no mesmo host físico) não ajuda muito, pois se a máquina explodir, você perderá seu banco de dados e seus backups. Dependendo de sua infraestrutura de rede, pode fazer mais sentido fazer backup localmente e depois transferi-los para um local diferente nos bastidores; em ambos os casos, você deseja retirá-los da máquina de banco de dados primária o mais rápido possível.

Agora, uma vez que você tenha os backups de log regulares em execução, deve ser razoável reduzir o arquivo de log para algo mais razoável do que o que foi ampliado até agora. Isso não significa executar SHRINKFILE repetidamente até que o arquivo de log tenha 1 MB - mesmo se você estiver fazendo backup do log com frequência, ele ainda precisa acomodar a soma de quaisquer transações simultâneas que possam ocorrer. Os eventos de crescimento automático do arquivo de log são caros, pois o SQL Server precisa zerar os arquivos (ao contrário dos arquivos de dados quando a inicialização instantânea do arquivo está habilitada) e as transações do usuário precisam esperar enquanto isso acontece. Você quer fazer essa rotina crescer-encolher-crescer-encolher o mínimo possível e certamente não quer que seus usuários paguem por isso.

Observe que você pode precisar fazer backup do log duas vezes antes que uma redução seja possível (obrigado Robert).

Então, você precisa encontrar um tamanho prático para o seu arquivo de log. Ninguém aqui pode te dizer o que é isso sem saber muito mais sobre seu sistema, mas se você tem reduzido frequentemente o arquivo de log e ele está crescendo novamente, uma boa marca d'água é provavelmente 10-50% maior do que a maior que já foi . Digamos que chegue a 200 MB e você queira que todos os eventos de crescimento automático subsequentes sejam de 50 MB, então você pode ajustar o tamanho do arquivo de log desta forma:
USE [master];
GO
ALTER DATABASE Test1 
  MODIFY FILE
  (NAME = yourdb_log, SIZE = 200MB, FILEGROWTH = 50MB);
GO

Observe que, se o arquivo de log tiver atualmente> 200 MB, talvez seja necessário executar isso primeiro:
USE yourdb;
GO
DBCC SHRINKFILE(yourdb_log, 200);
GO

Se você não se importa com a recuperação pontual


Se este for um banco de dados de teste e você não se importa com a recuperação pontual, verifique se o banco de dados está em SIMPLE modo de recuperação.
ALTER DATABASE testdb SET RECOVERY SIMPLE;

Colocando o banco de dados em SIMPLE o modo de recuperação garantirá que o SQL Server reutilize partes do arquivo de log (essencialmente eliminando transações inativas) em vez de crescer para manter um registro de todos transações (como FULL recuperação faz até você fazer backup do log). CHECKPOINT eventos ajudarão a controlar o log e garantir que ele não precise crescer, a menos que você gere muita atividade de t-log entre CHECKPOINT s.

Em seguida, você deve ter certeza absoluta de que esse crescimento de log foi realmente devido a um evento anormal (digamos, uma limpeza anual de primavera ou a reconstrução de seus maiores índices) e não devido ao uso normal e diário. Se você reduzir o arquivo de log para um tamanho ridiculamente pequeno e o SQL Server apenas precisar aumentá-lo novamente para acomodar sua atividade normal, o que você ganhou? Você conseguiu usar o espaço em disco que liberou apenas temporariamente? Se você precisar de uma correção imediata, poderá executar o seguinte:
USE yourdb;
GO
CHECKPOINT;
GO
CHECKPOINT; -- run twice to ensure file wrap-around
GO
DBCC SHRINKFILE(yourdb_log, 200); -- unit is set in MBs
GO

Caso contrário, defina um tamanho e uma taxa de crescimento apropriados. Conforme o exemplo no caso de recuperação pontual, você pode usar o mesmo código e lógica para determinar qual tamanho de arquivo é apropriado e definir parâmetros de crescimento automático razoáveis.

Algumas coisas que você não quer fazer


  • Faça backup do registro com TRUNCATE_ONLY opção e, em seguida, SHRINKFILE . Por um lado, este TRUNCATE_ONLY A opção foi preterida e não está mais disponível nas versões atuais do SQL Server. Segundo, se você estiver em FULL modelo de recuperação, isso destruirá sua cadeia de logs e exigirá um novo backup completo.

  • Desanexe o banco de dados, exclua o arquivo de log e anexe novamente . Eu não posso enfatizar o quão perigoso isso pode ser. Seu banco de dados pode não voltar, pode aparecer como suspeito, você pode ter que reverter para um backup (se tiver um), etc. etc.

  • Use a opção "reduzir banco de dados" . DBCC SHRINKDATABASE e a opção do plano de manutenção para fazer o mesmo são más ideias, especialmente se você realmente só precisa resolver um problema de log. Direcione o arquivo que você deseja ajustar e ajuste-o de forma independente, usando DBCC SHRINKFILE ou ALTER DATABASE ... MODIFY FILE (exemplos acima).

  • Reduza o arquivo de registro para 1 MB . Isso parece tentador porque, ei, o SQL Server me permite fazer isso em determinados cenários e observar todo o espaço que ele libera! A menos que seu banco de dados seja somente leitura (e é, você deve marcá-lo como tal usando ALTER DATABASE ), isso levará a muitos eventos de crescimento desnecessários, pois o log precisa acomodar as transações atuais, independentemente do modelo de recuperação. Qual é o sentido de liberar esse espaço temporariamente, apenas para que o SQL Server possa recuperá-lo lenta e dolorosamente?

  • Crie um segundo arquivo de registro . Isso proporcionará alívio temporário para a unidade que encheu seu disco, mas é como tentar consertar um pulmão perfurado com um band-aid. Você deve lidar com o arquivo de log problemático diretamente em vez de apenas adicionar outro problema em potencial. Além de redirecionar alguma atividade de log de transações para uma unidade diferente, um segundo arquivo de log realmente não faz nada para você (ao contrário de um segundo arquivo de dados), pois apenas um dos arquivos pode ser usado por vez. Paul Randal também explica por que vários arquivos de log podem mordê-lo mais tarde.

Seja proativo


Em vez de reduzir seu arquivo de log para uma pequena quantidade e deixá-lo constantemente crescer automaticamente a uma pequena taxa por conta própria, defina-o para um tamanho razoavelmente grande (um que acomode a soma do seu maior conjunto de transações simultâneas) e defina um crescimento automático razoável configuração como um fallback, para que não tenha que crescer várias vezes para satisfazer transações únicas e para que seja relativamente raro que ele tenha que crescer durante as operações normais de negócios.

As piores configurações possíveis aqui são 1 MB de crescimento ou 10% de crescimento. Engraçado, esses são os padrões do SQL Server (dos quais reclamei e solicitei alterações sem sucesso) - 1 MB para arquivos de dados e 10% para arquivos de log. O primeiro é muito pequeno hoje em dia, e o último leva a eventos cada vez mais longos (digamos, seu arquivo de log é de 500 MB, o primeiro crescimento é de 50 MB, o próximo crescimento é de 55 MB, o próximo crescimento é de 60,5 MB , etc. etc. - e em I/O lento, acredite, você realmente notará essa curva).

Leitura adicional


Por favor, não pare aqui; embora muitos dos conselhos que você vê por aí sobre a redução de arquivos de log sejam inerentemente ruins e até potencialmente desastrosos, há algumas pessoas que se preocupam mais com a integridade dos dados do que com a liberação de espaço em disco.

Uma postagem no blog que escrevi em 2009, quando vi algumas postagens "aqui está como reduzir o arquivo de log".

Uma postagem no blog que Brent Ozar escreveu há quatro anos, apontando para vários recursos, em resposta a um artigo da SQL Server Magazine que não foram publicados.

Uma postagem no blog de Paul Randal explicando por que a manutenção do t-log é importante e por que você também não deve reduzir seus arquivos de dados.

Mike Walsh tem uma ótima resposta cobrindo alguns desses aspectos também, incluindo motivos pelos quais você pode não conseguir reduzir seu arquivo de log imediatamente.