自动 SP_WhoIsActive SQL 活动捕获问题

sha*_*mim 4 sql-server sql-server-2008-r2 sql-server-agent jobs sp-whoisactive

我在生产服务器上有一个 SQL 代理作业,它不断失败并显示以下消息。它应该使用SP_WHOISACTIVE存储的 proc 以定期安排的时间间隔捕获 SQL Server 活动。

以用户身份执行:警告:聚合或其他 SET 操作消除了空值。[SQLSTATE 01003](消息 8153)

警告:空值被聚合或其他 SET 操作消除。[SQLSTATE 01003](消息 8153)

警告:空值被聚合或其他 SET 操作消除。[SQLSTATE 01003](消息 8153)

违反 PRIMARY KEY 约束“PK_WhoIsActive”。无法在对象“monitoring.WhoIsActive”中插入重复键。重复的键值为 (Jan 20 2017 8:25AM, 109)。[SQLSTATE 23000](错误 2627)

该语句已终止。[SQLSTATE 01000](错误 3621)。

步骤失败。

知道是什么原因造成的吗?

我应该遵循哪些步骤来修复此错误?

小智 5

从主键名称看来,您正在运行 Adam Machanic 的 sp_WhoIsActive 并将结果存储在表中。

如果是这种情况,警告是正常的,并且是由您在调用 sp_WhoIsActive 时设置的选项引起的。主键违规是导致作业失败的原因。

看一下主键的定义。

我相信您会发现需要更改 Primay Key 以确保唯一性。

在我的实现中,我将表保留为堆,并且没有在该表上定义主键。我只在表中保留几天的数据并且不将其用于复制。

这是一篇关于如何实现它的文章: Brent Ozar 实现 sp_WhoIsActive


IT *_*nja 5

使用SP_WHOISACTIVESP_WHO2通过 SQL 代理作业自动捕获 SQL Server 活动

知道是什么原因造成的吗?

显然,您当前的进程在尝试在表上插入重复数据时存在问题,该表的约束不允许复制此类数据,其中值是Jan 20 2017 8:25AM, 109每个定义的PK_WhoIsActive主键。

我应该遵循哪些步骤来修复此错误?

我已经复制了我在下面的此类任务中成功使用的逻辑。我运行了一次创建表逻辑(两者都运行),但将其保存到注释掉或跳过的 SQL 代理步骤中,仅供将来参考。

我在下面分享SP_WHOISACTIVESP_WHO2捕获方法和逻辑,但请确保您在数据库上运行SP_WHO2进程,因为它的逻辑是隐式的。请务必在SP_WHOISACTIVE进程中指定表和数据库名称,因为其逻辑是明确的。

SP_WhoIsActive 表捕获

创建表

DECLARE @destination_table VARCHAR(4000);

SET @destination_table = 'WhoIsActive_Cap';

DECLARE @schema VARCHAR(4000);

EXEC sp_WhoIsActive @get_transaction_info = 1
    ,@get_plans = 1
    ,@return_schema = 1
    ,@schema = @schema OUTPUT;

SET @schema = REPLACE(@schema, '<table_name>', @destination_table);

PRINT @schema

EXEC (@schema);
Run Code Online (Sandbox Code Playgroud)

捕获到表

SET @destination_table = '[<DB_Name>].dbo.WhoIsActive_Cap'

EXEC Master.dbo.sp_WhoIsActive @get_transaction_info = 1
    ,@get_plans = 1
    ,@destination_table = @destination_table;

-- remove records older than 7 days but adjust accordingly for your needs
DELETE
FROM [<DB_Name>].dbo.WhoIsActive_Cap
WHERE collection_time < dateadd(dd, -7, getdate())
Run Code Online (Sandbox Code Playgroud)

SP_WHO2 表捕获

创建表

CREATE TABLE dbo.who2cap (
    SPID INT
    ,[Status] VARCHAR(100)
    ,[Login] VARCHAR(100)
    ,HostName VARCHAR(50)
    ,BlkBy VARCHAR(10)
    ,DBName VARCHAR(255)
    ,Command VARCHAR(500)
    ,CPUTime INT
    ,DiskIO INT
    ,LastBatch VARCHAR(20)
    ,ProgramName VARCHAR(500)
    ,SPID2 INT
    ,REQUESTID INT
    )
Run Code Online (Sandbox Code Playgroud)

捕获到表

CREATE TABLE #who2cap (
    SPID INT
    ,[Status] VARCHAR(100)
    ,[Login] VARCHAR(100)
    ,HostName VARCHAR(50)
    ,BlkBy VARCHAR(10)
    ,DBName VARCHAR(255)
    ,Command VARCHAR(500)
    ,CPUTime INT
    ,DiskIO INT
    ,LastBatch VARCHAR(20)
    ,ProgramName VARCHAR(500)
    ,SPID2 INT
    ,REQUESTID INT
    )

INSERT #who2cap
EXEC sp_who2

-- remove old entries (currently set to 3 weeks)
DELETE
FROM dbo.who2cap
WHERE logdt < dateadd(dd, - 21, getdate())

INSERT INTO dbo.who2cap
SELECT getdate()
    ,*
FROM #who2cap

DROP TABLE #who2cap
Run Code Online (Sandbox Code Playgroud)