Sql server 队列停止(禁用),但不显示任何有害消息

Sql server 队列停止(禁用),但不显示任何有害消息,sql-server,sql-server-2005,service-broker,Sql Server,Sql Server 2005,Service Broker,我有一个无需任何理由就能停止的队列,在这个队列中我实现了一个posion消息处理。在处理过程中,它会记录并丢弃任何有毒消息 一年多以来,它一直运转良好。但最近(问题开始于四周前),它每周停止一两次。仅在本周,它就停止了两次 当我查看含有新中毒消息的表时,没有!!当我启用队列时,处理将成功恢复,“有毒消息”情况不会重现 关于队列的任务:每天接收大约2-3000条消息。它用于在事务外部运行存储过程。每一条消息都可以持续一段时间进行处理(进行大量的选择、插入和更新) 让我解释一下这一点:数据库具有在事

我有一个无需任何理由就能停止的队列,在这个队列中我实现了一个posion消息处理。在处理过程中,它会记录并丢弃任何有毒消息

一年多以来,它一直运转良好。但最近(问题开始于四周前),它每周停止一两次。仅在本周,它就停止了两次

当我查看含有新中毒消息的表时,没有!!当我启用队列时,处理将成功恢复,“有毒消息”情况不会重现

关于队列的任务:每天接收大约2-3000条消息。它用于在事务外部运行存储过程。每一条消息都可以持续一段时间进行处理(进行大量的选择、插入和更新)

让我解释一下这一点:数据库具有在事务内部激发的触发器,触发器发送消息以在触发器外部运行一些代码。异步行为可防止数据库性能下降

我检测到,即使在处理消息时出现死锁,队列也会将消息视为已中毒。所以原则上这不应该是性能问题。但是,会吗?可能数据库正在增长,处理消息的时间太长了

但是如果没有检测到它的位置,我如何才能找到它呢?
为什么队列停止的其他原因?
如何保存禁用队列的时间和消息?
有人知道我怎么做法医分析吗?
有什么想法吗


更新公开伪解决方案:
根据Remus的帖子,我尝试使用事件通知来获取队列停止的确切时刻

CREATE EVENT NOTIFICATION [QueueDisabledEN]
  ON QUEUE [dbo].[ProcessQueue]
  FOR BROKER_QUEUE_DISABLED
  TO SERVICE 'Queue Watch Service', 'current database';
然后检查事件日志:

select * from sys.event_notificiation
但由于很难知道事件发生的环境(当时还有什么情况),法医分析就此结束。幸运的是,我的代理服务实现存储了带有装运日期、接收日期、处理日期等的消息。。。这有助于我检测到,在3秒钟内,队列中充斥着数百条消息,这些消息的处理时间太长

虽然我找到了一个真正的解决方案,但唯一的临时解决方案是每x分钟检查一次代理作业,检查队列的状态并启用它:

IF (EXISTS(SELECT * FROM sys.service_queues WHERE name like 'ProcessQueue' AND (is_receive_enabled = 0 OR is_enqueue_enabled = 0))) BEGIN
    PRINT convert(nvarchar, getdate(), 121)+ ': Activando la cola ProcessQueue'
    ALTER QUEUE ProcessQueue WITH STATUS = ON 
END

谢谢雷姆斯

当您发现队列处于禁用状态,并重新启用队列时,我假设处理将成功恢复,“有毒消息”的情况不会重现。这表明原因是暂时的或与时间有关的。它可能是一个正在运行的SQL代理作业,导致队列处理死锁,迫使队列处理回滚。在我的经验中,死锁是最典型的毒害信息原因。最好的取证工具是系统事件日志,因为激活的过程会将错误输出到错误日志中,从而输出到系统事件日志中

每当有毒消息触发器(5次连续回滚)禁用队列时,将触发类型为queue_disabled的队列。您可以在处理此事件的过程中捕获更多取证信息,因为它将在禁用队列后不久运行


顺便说一句,你永远不会有真正的“有毒消息处理”。每当您增强处理以处理某些错误情况时,“有害消息”的定义将更改为能够禁用新错误处理的消息。

当您发现队列处于禁用状态并启用回队列时,我假设处理成功恢复,并且“有毒消息”情况不会重现。这表明原因是暂时的或与时间有关的。它可能是一个正在运行的SQL代理作业,导致队列处理死锁,迫使队列处理回滚。在我的经验中,死锁是最典型的毒害信息原因。最好的取证工具是系统事件日志,因为激活的过程会将错误输出到错误日志中,从而输出到系统事件日志中

每当有毒消息触发器(5次连续回滚)禁用队列时,将触发类型为queue_disabled的队列。您可以在处理此事件的过程中捕获更多取证信息,因为它将在禁用队列后不久运行


顺便说一句,你永远不会有真正的“有毒消息处理”。每当您增强处理以处理某些错误情况时,“毒药消息”的定义将更改为能够禁用新错误处理的消息。

Hi@Remus Rusanu,关于毒药消息处理:当然不是真正的、确定的“毒药消息处理”,但我认为这是我能找到的最接近它的一个非常简单的解决方案:如果检测到3次回滚,在下一次“recibe操作”中,消息将被直接忽略,以便稍后进行分析。任何避免队列停止并达到连续5次回滚的方法。。。但是,当毒药消息保存以供以后分析时,它可能会生成错误(由死锁或暂时性问题引起),并到达第五次回滚。有点偏执,不是吗?嗨@Remus Rusanu,关于毒药消息处理:当然不是真正确定的“毒药消息处理”,但我认为这是我能找到的最接近它的方法,基于一个非常简单的解决方案:如果在下一个“recibe action”中检测到3次回滚该消息将被直接驳回,以便稍后进行分析。任何避免队列停止并达到连续5次回滚的方法。。。但是,当毒药消息保存以供以后分析时,它可能会生成错误(由死锁或暂时性问题引起),并到达第五次回滚。有点偏执,不是吗?