Cenário:
Nós escrevemos software de banco on-line e, por enquanto (devido a decisões de design herdadas), estamos usando o Quartz 2.2 agora como um sistema de filas para executar algumas operações de longo prazo. [Vamos deixar de lado a discussão sobre se é a ferramenta certa, funcionou bem por muitos anos até atualizarmos para 2.2]
Parte desse quartz.net possui as seguintes tabelas (relacionadas) para esquema: https://gist.github.com/jcolebrand/8695603
Portanto, o processo é inserir registros nesta tabela, digamos, 80 mil registros. (Tenho três replicações do quartz.net atendendo a três configurações diferentes, uma com 80k de registros, outra com 50k, outra com 280k, então varia). Nós os inserimos de alguma outra tabela que é a tabela de registro, então reconstruir esta tabela não é uma perda terrível. O problema é descrito abaixo.
Eu tenho uma ferramenta que pode agendar essas tarefas em massa (a maioria das quais é única e acontecerá de duas semanas a vinte anos no futuro, novamente, trata-se do banco de dados e não das opções de arquitetura) e posso depurar a etapa completamente, veja as linhas serem inseridas na tabela sem preocupação. Posso monitorar a tabela e ver se eles são inseridos. Eu então volto 30 minutos depois (bem, esta parte varia. Não é determinístico quando eles desaparecem) e verifico se os registros estão faltando.
De 80k em uma instância, estou perdendo aproximadamente 2.700 registros. E quando executo minha ferramenta, vejo todos eles sincronizados e, depois de algum tempo, eles evaporaram novamente.
Aqui estão as coisas que eu tentei:
- verificando o relatório de todas as transações no SSMS
- verificando o relatório de todas as transações de bloqueio no SSMS
- deixar meu aplicativo de agendamento aberto por muito tempo (caso, por alguma mágica, houvesse uma transação aberta e não confirmada)
- reiniciando o aplicativo de serviço do Windows Quartz.net mantendo o banco de dados
- inserindo registros com o serviço windows quartz.net desabilitado
Coisas que não experimentei:
- reiniciando o servidor SQL
- minhas consultas não usam "with(nolock)" [ouvi dizer que isso é ruim para o dia-a-dia]
Coisas que acho que devo fazer e não sei como:
- execute o SQL Profiler na instância e monitore as instruções "excluir"
- mágica para determinar se há uma transação não confirmada
- sacrificar unicórnios
- telefone para um amigo
- duplo diário
@@versão:
Microsoft SQL Server 2008 R2 (SP2) - 10.50.4000.0 (X64)
28 de junho de 2012 08:36:30
Copyright (c) Microsoft Corporation
Standard Edition (64 bits) no Windows NT 6.1 (Build 7601: Service Pack 1) (Hypervisor )
EDITAR 2014-01-30
É imperativo, por razões internas, que eu possa demonstrar precisamente por que os registros estão desaparecendo, incluindo, entre outros:
- exclusão por um usuário
- transação não confirmada
- deleção pelo próprio Quartz
- alguns outros fenômenos inexplicáveis
- efeito Borboleta
- efeito de gatilho
- unicórnios
Sempre que possível, preciso da instrução específica envolvida na exclusão.
TL;DR
Então, basicamente, o TL;DR é: os registros são inseridos. Por algum período de tempo de até pelo menos 30 minutos, o registro é definitivamente exibido em consultas na tabela. Depois de algum tempo, os registros não são mais exibidos em consultas na tabela.
O que da? O que estou deixando passar? Como você perfilaria isso EM PRODUÇÃO para ver o que está acontecendo aqui?