Estou usando o sqlwatch para monitorar alguns dos meus servidores e ele tem um trabalho que exclui em lote de uma tabela chamadadbo.sqlwatch_logger_snapshot_header
Tive muitos problemas de locking e bloqueio pois essa tabela é utilizada por diferentes processos, então desabilitei todos os outros jobs com exceção daquele que trata dessa tabela.
Usei o seguinte script para desabilitar todos os outros trabalhos do sqlwatch:
use distribution
set nocount on
set transaction isolation level read uncommitted
declare @Job_id uniqueidentifier
declare @job_name varchar(300)
declare @category_name varchar(300)
declare @body varchar(max)
declare @flag tinyint
declare @enabled bit = 0; --0 - disable 1-enable
declare @subject varchar(300) = case when @enabled = 0 then 'Disabling sqlwatch jobs on' + @@servername else 'Enabling sqlwatch jobs on' + @@servername end;
declare @job_enabled bit;
set @flag = 0
set @body = 'The following jobs are going to be ' +
case when @enabled = 0 then 'Disabled' else 'Enabled' end
+ ' : '+char(10)+Char(13)
IF OBJECT_ID('tempdb.[dbo].[#LogReaderAgents]') IS NOT NULL
DROP TABLE [dbo].[#LogReaderAgents]
CREATE TABLE [dbo].[#LogReaderAgents] (
[job_id] UNIQUEIDENTIFIER NOT NULL,
[job_name] SYSNAME NOT NULL,
[category_name] SYSNAME NOT NULL,
[enabled] TINYINT NOT NULL)
INSERT INTO [dbo].[#LogReaderAgents] ([job_id],[job_name],[category_name],[enabled])
select job_id, job_name = sj.name, category_name=sc.name, sj.enabled
from msdb.dbo.sysjobs sj
inner join msdb.dbo.syscategories sc
on sj.category_id = sc.category_id
where 1=1
and sj.name like 'SQLWATCH%'
-- and sc.category_id in (10,13)
and sj.name not in ('SQLWATCH-INTERNAL-RETENTION')
-- exec sp_gettabledef 'dbo.#LogReaderAgents'
-- exec sp_GetInsertList 'TEMPDB','DBO.#LogReaderAgents'
DECLARE c1 CURSOR FOR
SELECT Job_id,job_name, category_name, [enabled]
FROM #LogReaderAgents
OPEN c1
FETCH NEXT FROM c1
INTO @Job_id,@job_name,@category_name,@job_enabled
WHILE @@FETCH_STATUS = 0
begin
if (select top (1) stop_execution_date from msdb.dbo.sysjobactivity ja
where Job_ID = @Job_id
and
ja.start_execution_date IS NOT NULL
order by Start_execution_date desc) is not NULL
begin
set @flag = 1
Print @job_name +' is ' + case when @job_enabled=1 then 'Enabled' else 'disabled' end
exec msdb..sp_update_job @job_id = @job_id, @enabled = @enabled
set @Body = @Body + char(10)+char(13) + @job_name + ' -- ' + @category_name +' is ' + case when @job_enabled=1 then 'Enabled' else 'disabled' end
end
FETCH NEXT FROM c1
INTO @Job_id,@job_name,@category_name,@job_enabled
end
CLOSE c1
DEALLOCATE c1
entretanto, depois disso o trabalho ainda está em execução, mas não vejo nenhuma alteração no número de registros que estão nesta tabela.
aqui está o trabalho executando um procedimento e fazendo uma exclusão em lote:
o progresso tem sido lento, mas constante, havia 37,2 milhões de linhas
agora existem 36,9 milhões
então basicamente está funcionando, então tudo bem.
Agora minha pergunta:
Suponha que eu tivesse que interromper este trabalho por qualquer motivo,
é uma exclusão em lote, se eu tivesse que interromper este trabalho agora, quantas linhas foram afetadas, qual seria o custo de reverter o que ainda não foi confirmado?
Você pode usar
sys.dm_tran_database_transactions
para descobrir quanto log foi gravado e, portanto, se ele precisa ser revertido.Observe que
database_transaction_log_record_count
é quantos registros de log são gerados e não quantas linhas são afetadas.Quanto tempo levaria para esses dados serem revertidos: quem sabe? Depende muito do sistema e não se esqueça de que as reversões são de thread único.