Cenário:
Temos duas tabelas Tbl1
e Tbl2
no Servidor do Assinante. O Tbl1
está sendo replicado do Publisher Server A
e possui dois gatilhos - inserir e atualizar. Os gatilhos estão inserindo e atualizando os dados em arquivos Tbl2
.
Agora, temos que limpar (aprox. 900 milhões de registros) dos Tbl2
quais tem um total de 1.000+ milhões de registros. Abaixo está a distribuição de dados de um mês a um minuto.
- Um mês - 14986826 linhas
- Um dia - 483446 linhas
- Uma hora - 20143 linhas
- Um minuto - 335 linhas
O que estou procurando;
A maneira mais rápida de limpar esses dados sem nenhum problema de produção, consistência de dados e possivelmente sem tempo de inatividade. Então, estou pensando em seguir os passos abaixo, mas preso :(
Passos:
- BCP Retirar os dados necessários da tabela Tbl2 existente (cerca de 100 milhões de registros, pode demorar aprox. 30 minutos).
- Vamos supor que eu comecei a fazer a atividade em 1Fab2018 22:00, ela terminou em 1Fab2018 22:30. Quando a atividade for concluída, a tabela Tbl2 obterá novos registros que se tornarão delta
- Crie uma nova tabela no banco de dados com o nome Tbl3
- BCP nos dados exportados para a tabela recém-criada Tbl3 (cerca de 100 milhões de registros, pode levar aprox. 30 minutos)
- Parar o trabalho de replicação
Depois que o BCP-in for concluído, use o script tsql para inserir os novos dados delta.
O desafio é - Como lidar com a declaração de “atualização” do delta?
Iniciar a replicação
Pergunta adicional:
Qual é a melhor maneira de lidar com o cenário?
Como você está excluindo 90% das linhas, recomendo copiar as linhas que você precisa manter em uma nova tabela com a mesma estrutura, usar
ALTER TABLE ... SWITCH
para substituir a tabela existente pela nova tabela e simplesmente descartar a tabela antiga. Consulte esta página do Microsoft Docs para obter a sintaxe.Um banco de ensaio simples, sem replicação que mostra o princípio geral:
Primeiro, vamos criar um banco de dados para nosso teste:
Aqui, criamos algumas tabelas, com um gatilho para mover linhas da tabela "A" para "B", aproximando sua configuração.
Aqui, inserimos 1.000.000 de linhas em "A" e, por causa do gatilho, essas linhas também serão inseridas em "B".
Limpe o log de transações, para evitar ficar sem espaço. NÃO EXECUTE isso em produção, pois ele envia os dados do log de transações para o dispositivo "NUL".
Esse código cria uma transação para garantir que nenhuma das tabelas afetadas possa ser gravada enquanto migramos as linhas:
O
sp_getapplock
esp_releaseapplock
impedem que várias instâncias desse código sejam executadas ao mesmo tempo. Isso seria útil se você habilitasse esse código para ser reutilizado por meio de uma GUI.(Observe que os bloqueios de aplicativos só são eficazes se todos os processos que acessam o recurso implementarem explicitamente a mesma lógica de bloqueio manual de recursos - não há mágica que "bloqueie" a tabela da mesma maneira que o SQL Server bloqueia automaticamente linhas, páginas etc. operação de inserção/atualização.)
Agora, testamos o processo de inserção de linhas em "A", para garantir que elas sejam inseridas em "B" pelo gatilho.