如何杀死已经被杀死的流氓蜘蛛?

Mar*_*lli 5 sql-server dbcc transaction tempdb kill

我有一个无法杀死的顽固 spid,它阻止了我的 tempdb的事务日志被截断

这就是我发现这个流氓 spid 的方法:

if object_id('tempdb..#OpenTranStatus','U') is not null
   drop table #OpenTranStatus

CREATE TABLE #OpenTranStatus (
ActiveTransaction varchar(25),
Details sql_variant
);
 
-- Execute the command, putting the results in the table.
INSERT INTO #OpenTranStatus
EXEC ('DBCC OPENTRAN (sqlwatch) with tableresults')
SELECT * FROM #OpenTranStatus
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

这是它正在运行(或保留)的查询:

select d.database_id , sd.sqlwatch_database_id, sd.sql_instance
        into #d
        from dbo.vw_sqlwatch_sys_databases d

        inner join [dbo].[sqlwatch_meta_database] sd 
            on sd.[database_name] = d.[name] collate database_default
            and sd.[database_create_date] = case when d.name = 'tempdb' then '1970-01-01 00:00:00.000' else d.[create_date] end
            and sd.sql_instance = @sql_instance

        left join [dbo].[sqlwatch_config_exclude_database] ed
            on d.[name] like ed.database_name_pattern collate database_default
            and ed.snapshot_type_id = @snapshot_type_id
        where ed.snapshot_type_id is null
        option (keep plan)
Run Code Online (Sandbox Code Playgroud)

它已经运行了60 多个小时:

在此输入图像描述

它已经被杀死了。

所以我尝试做的事情:

alter database sqlwatch set single_user with rollback immediate
Run Code Online (Sandbox Code Playgroud)

但没用

kill 54 with statusonly
Run Code Online (Sandbox Code Playgroud)

SPID 54:正在进行事务回滚。预计回滚完成:0%。预计剩余时间:0 秒。

在此输入图像描述

问题:

我怎样才能停止spid54?

J.D*_*.D. 9

\n

SPID 54:正在进行事务回滚。预计回滚完成:0%。预计剩余时间:0 秒。

\n
\n

不幸的是,一旦进程开始回滚,除了等待之外,我们无能为力。事务所做的所有更改(在您的情况下将一堆记录插入临时表中)都需要撤消。它还需要重新获取之前获取的大部分相同锁,以便进行回滚。如果基础表之一上现有的不兼容锁阻止了这一操作,则回滚将挂起,直到该阻止解决为止。“最好的部分”是回滚是单线程发生的,并且通常需要比查询被终止之前运行的所有时间更长的时间。

\n

唯一的其他选项通常是非正常终止,例如重新启动 SQL Server 服务或重新启动服务器计算机本身。这存在数据丢失和/或损坏的风险,并且数据库可能仍以恢复状态重新上线。不幸的是,这不适用于您的情况:

\n
\n

它位于关键服务器上...我试图避免重新启动服务或服务器。

\n
\n

FWIW,微软通过一项称为加速数据库恢复的功能极大地改进了 SQL Server 2019 及更高版本中的恢复和回滚过程:

\n
\n

加速数据库恢复\xe2\x80\xaf(ADR) 通过重新设计 SQL 数据库引擎恢复过程,提高了数据库可用性,特别是在存在长时间运行事务的情况下。

\n

在较高层面上,ADR 通过对所有物理数据库修改进行版本控制并仅撤消逻辑操作来实现快速数据库恢复,逻辑操作是有限的并且几乎可以立即撤消。崩溃时处于活动状态的任何事务都被标记为已中止,因此,并发用户查询可以忽略这些事务生成的任何版本。

\n
\n

恢复过程步骤进行了重组,以便在启用后几乎可以立即进行回滚:

\n

加速数据库恢复过程

\n

这是一个很棒的功能,不幸的是它也不适用于您的情况:

\n
\n

SQL Server 2016

\n
\n

我唯一能想到的另一件事是,您可以尝试使该数据库脱机,但我相信它不太可能起作用,并且将等待锁定当前回滚的事务。

\n

您还可以运行sp_WhoIsActive以查看服务器上当前正在执行的其他内容是否有可能阻止回滚或大量占用服务器资源(也可能是可杀死的)。sp_WhoIsActive至少应该通过查看回滚命令的 CPU 时间和读写次数继续增加来告诉您是否有进展。

\n

不幸的是,您可能只是在等待,这可能需要几天的时间。

\n

  • @Sean sqlwatch 视图加入到`dm_hadr_database_replica_states`,这将解释等待https://github.com/marcingminski/sqlwatch/blob/main/SqlWatch.Monitor/Project.SqlWatch.Database/dbo/Views/vw_sqlwatch_sys_databases.sql (2认同)