Usando o SQL Server 2008 e posterior, desejo adicionar uma coluna de versão de linha a uma tabela grande, mas quando simplesmente
ALTER TABLE [Tablename]
ADD Rowversion [Rowversion] NOT NULL
Então a tabela fica indisponível para atualizações por muito tempo.
Quais estratégias posso usar para reduzir esse tempo de inatividade? Vou considerar qualquer coisa. Quanto mais simples melhor, claro, mas vou considerar qualquer estratégia.
Meu pensamento é que, como último recurso, eu poderia manter uma tabela de preparação de cópia mantida por gatilhos e, em seguida, sp_renomear a tabela de preparação para a tabela original. Mas espero algo mais simples/fácil.
Considere a criação de uma nova tabela com o mesmo esquema mais a coluna rowversion e adicione uma visualização sobre ambas as tabelas que faça uma união total. Faça com que as pessoas usem a exibição e escrevam gatilhos em vez de nas tabelas e exibições subjacentes.
As inserções devem ser enviadas para a nova tabela, as atualizações devem mover os dados para a nova tabela e as exclusões devem ser aplicadas a ambas as tabelas.
Em seguida, faça movimentações em lote em segundo plano, movendo o máximo de registros possível de uma vez para a nova tabela. Você ainda pode ter problemas de simultaneidade enquanto isso está acontecendo e alguns planos de execução ruins, mas permite que você fique online enquanto os movimentos estão acontecendo.
Idealmente, você inicia o processo em uma tarde de sexta-feira para minimizar o efeito sobre os usuários finais e tenta concluí-lo antes da manhã de segunda-feira. Assim que estiver no lugar, você pode alterar a exibição para apontar apenas para a nova tabela e os planos de execução craptaculares desaparecem. Idealmente.
Para evitar que os gatilhos sejam disparados quando os dados estiverem sendo migrados em lotes, observe o número de linhas nas tabelas excluídas/inseridas no gatilho e pule as atividades se elas estiverem próximas do número de linhas em seu lote.
No final, Michael decidiu pular a exibição (e não excluir da tabela original) para obter planos mais estáveis. A troca estava segurando essencialmente duas cópias da mesa. Ele o transformou em uma série de postagens de blog .
Se você tiver tempo para planejar com antecedência, há uma solução muito mais fácil... (geralmente)
Os longos bloqueios são quase certamente causados por divisões de página na camada de armazenamento. Portanto, force-os em sua própria programação.
VARBINARY(8)
.0x0000000027F95A5B
por exemplo)Usei isso com sucesso para adicionar uma coluna de versão de linha a uma tabela de linhas de 150 milhões em menos de 10 minutos.
Advertência... se você tiver uma tabela com campos varchar grandes (especialmente
varchar(max)
), o SQL Server decide reconstruir a tabela em vez de reutilizar o espaço recém-disponível. Ainda tentando descobrir uma maneira de contornar isso.Se
TIMESTAMP
você está adicionando éNULLABLE
:VARBINARY(8)
colunaDepois de preenchida, em instruções SQL consecutivas,
DROP
aVARBINARY(8)
coluna que você acabou de adicionar e preencher e adicionar aTIMESTAMP NULL
coluna.Se
TIMESTAMP
você está adicionando éNOT NULLABLE
:BINARY(8)
colunaDepois de preenchida, em instruções SQL consecutivas,
DROP
aBINARY(8)
coluna que você acabou de adicionar e preencher eADD THE TIMESTAMP NOT NULL
coluna.