sql-server - SqlQueryNotificationStoredProcedure的错误已经填满 SQL Server 日志

SQL Server日志正在以快速被填充,错误消息如下所示:

The activated proc '[dbo].[SqlQueryNotificationStoredProcedure-b65a194e-e29f-4ba0-8f5a-79f0875bd609]' running on queue 'MyDatabase.dbo.SqlQueryNotificationService-b65a194e-e29f-4ba0-8f5a-79f0875bd609' output the following: 'Cannot execute as the database principal because the principal "dbo" does not exist, this type of principal cannot be impersonated, or you do not have permission.'

这些消息引用的任何存储过程都不存在。

这个问题与这个描述的类似,本文提到该问题应该在2008 SP1中修复,但是,我已经在运行SP1了。

如果我运行以下命令。


select * from sys.service_queues

我注意到有很多排队的项目像SqlQueryNotificationService-f944d750-8530-4762-adcf-6948e8da991f 。

但是,如果我尝试用下面的命令杀死它们。


drop queue [SqlQueryNotificationService-78f5b757-45f0-4a4d-83f5-91e1d7e46294]

...我收到一条错误消息: 队列'sqlquerynotificationservice-78f5b757-45f0-4a4d-83f5-91e1d7e46294'不能被删除,因为它被绑定到一个或多个服务。

时间:

Cannot execute as the database principal because the principal "dbo" does not exist, this type of principal cannot be impersonated, or you do not have permission.

你必须首先修复此问题:


ALTER AUTHORIZATION ON DATABASE::<dbname> TO [sa];

如果你想知道发生了什么,我建议在我的博客上看一些文章: the Mysterious Notification and when it rains , it pours .在你的情况下,是两个问题的折叠:

  • 导致数据库具有孤立dbo的管理错误,这通常是由一个不相关的机构(Windows )的SID创建的数据库附加/还原的结果,不同计算机上的本地帐户,
  • 在SqlDependency中,代码在完成时忽略Stop()的编码错误,从而失败了SqlDependency临时基础结构,

通常,SqlDependency临时基础结构的激活过程会删除临时队列/服务/过程,但是,在您的情况下,是由于孤立的dbo而无法运行激活的事实。

修复孤立的dbo (通过在我的文章的开头运行变更)后,激活过程将能够运行,它们将清除所有临时队列,服务和过程。

删除基础服务后,我停止了错误日志的填充:


select * from sys.services

-- do this for every service:
drop service [SqlQueryNotificationService-7d871b6d-3868-452c-b75b-d5c5b13d0301]

然后我可以返回并删除所有队列。

现在的问题是如何防止将来发生这种情况。

只删除SqlQueryNotificationStoredProcedure SPs :


use <your DB name>;
declare @procName varchar(500)
declare cur cursor 

for select [name] from sys.objects WHERE type in (N'P', N'PC') and name like 'SqlQueryNotificationStoredProcedure%'
open cur
fetch next from cur into @procName
while @@fetch_status = 0
begin
exec ('drop procedure [' + @procName+']')
fetch next from cur into @procName
end
close cur
deallocate cur

...