Uma operação "ALTER INDEX ALL REBUILD" no SQL Server 2012 falhou porque o log de transações ficou sem espaço. Os índices nunca foram reorganizados ou reconstruídos; portanto, a fragmentação é superior a 80% em quase todos eles.
O banco de dados usa um modelo de recuperação simples. Supus que, após cada operação de índice executada pelo formulário "ALL" do comando, os dados do log de transações fossem liberados antes da próxima reconstrução do índice. É assim que realmente funciona ou as recriações do índice são registradas como se fizessem parte de uma única transação?
Em outras palavras, eu poderia reduzir o crescimento do log de transações escrevendo um script para executar cada reconstrução individualmente? Existem outros fatores a serem considerados?
fonte
Respostas:
1) Liberação de log: o modelo de recuperação SIMPLE não limpa o log após cada transação, mas nos pontos de verificação. ( link para mais informações)
2a) RECONSTRUIR TUDO: sim, RECONSTRUIR TUDO funciona como uma única transação. As recriações de índice dentro têm suas próprias transações, mas a operação geral não é totalmente confirmada até o final. Portanto, sim, você pode limitar o crescimento do arquivo de log reconstruindo índices individuais (e possivelmente emitindo comandos CHECKPOINT).
2b) Prova! Aqui, tenha um script de demonstração. (Desenvolvido no desenvolvimento de 2016) Primeiro, configure um banco de dados de teste, com tabela e índices:
Agora você pode comparar a atividade de log entre REBUILD ALL e reconstruir individualmente
Observe como a primeira transação aberta (ID de transação 0000: 000002fa para mim) não é confirmada até o final de REBUILD ALL, mas, para as recriações de índice por índice, elas são confirmadas sucessivamente.
fonte
Tal como está, esta é uma transação única.
fonte
A pergunta é trivial para uma reconstrução offline . Claro que é uma transação única. Imagine o caos que aconteceria se a operação dividisse cada índice em sua própria transação, pois teria que liberar os bloqueios ao confirmar e depois adquiri-los novamente. Enquanto a trava SCH-M da tabela crítica foi liberada, os índices podem ser eliminados e novos índices podem ser criados, como a instrução lidaria com esses casos? Sem mencionar que a tabela pode ser descartada e até recriada entre as duas transações! Incluindo o caso em que a tabela é descartada e uma tabela diferente é criada com o mesmo ID de objeto (sim, isso pode acontecer) ...
E se você aumentar a pergunta para dizer o que acontece se a reconstrução do índice for uma reconstrução online ? É uma transação única ou muitas? A resposta é complexa, pois na verdade existem várias transações internas envolvidas . No entanto, o ponto principal é que há uma transação de arquivamento geral que abrange toda a operação (a instrução ALTER) e isso fixa o log no local (não pode truncar), portanto, a operação precisa ser planejada de maneira a permitir dados ~ 1.6x tamanho para o modo de recuperação COMPLETO ou tamanho de dados 0,2x para o modo BULK_LOGGED / SIMPLE. Consulte o artigo vinculado para obter mais detalhes.
Você pode argumentar que por que o build offline não emprega as mesmas transações internas do modo online e divide a operação? Os problemas que eu mencionei sobre a tabela ser alterada / eliminada entre as operações de índice individuais (por exemplo, 'estabilidade do esquema' da tabela) ainda exigiriam que exista uma transação abrangente que mantenha um SCH-S na tabela durante toda a duração da instrução. Como essa transação também deve conter o SCH-S durante a recuperação, ela deve ser registrada e, como tal, haverá um registro de log BEGIN XACT que fixará o log e evitará o truncamento por toda a duração da instrução. Eu sei que esse problema específico estava sendo resolvido no período de tempo do SQL 2016-2017 (devido a problemas de tamanho de log do SQL Azure),
mas não tenho certeza de que progresso foi feito. Parece que está em pré-visualização agora:A reconstrução do índice online recuperável está em visualização pública do SQL Server 2017 CTP 2.0 .fonte
Sim, eu tive esse mesmo problema com uma tabela muito grande. Sempre que eu emitia ALTER INDEX ALL, o log de transações aumentaria muito, mas se emitisse ALTER INDEX individualmente, o uso do espaço de log seria menor.
fonte
A resposta anterior do Remus de que a indexação online requer 1,6x o tamanho do índice no modo de recuperação COMPLETO não está correta. A proporção de espaço de log de transações necessário para reconstruir um índice on-line em FULL pode ser muito maior e observamos muitas vezes o tamanho do índice, especialmente quando o índice que está sendo reconstruído é compactado, pois o log de transações não é compactado. Isso por si só deve deixar claro que o log de transações durante uma reconstrução on-line em COMPLETO pode ter pelo menos algumas vezes o tamanho do índice. Adicione uma sobrecarga de registro de tlog que não é totalmente documentada pela Microsoft, mas geralmente é estimada em 60 bytes por linha, e o tamanho proporcional do log durante uma reconstrução de índice online sob recuperação total pode ser muitas vezes o tamanho do índice que está sendo reconstruído, especialmente se o índice está compactado
fonte
Rdfozz está correto, é a melhor maneira de decidir se seu maior índice pode ser reconstruído com base no armazenamento atual. Basta executar
dm_exec_requests
enquanto a operação está acontecendo (ou SQL Profiler) para ver se todos os índices estão sendo reconstruídos. Também consideraria alterar o modelo de recuperação para o log em massa. É isso que eu faço e ainda existem backups de log de transações durante a janela. Veja abaixo o artigo https://technet.microsoft.com/en-us/library/ms191484(v=sql.105).aspxfonte