今天在对服务代理问题进行故障排除时,我发现数据库所有者是离开公司的员工的 Windows 登录名。他的登录名已被删除,因此查询通知失败。
据说处理这个问题的最佳实践是让“sa”成为数据库所有者。我们更改了它并清除了队列。
我的(非常基本的)问题:数据库所有者是什么,其目的是什么?
事件通知有问题。在消息发送到的机器/驱动器/数据库(接收器)上,驱动器在没有人查看时已满,因此它已经备份了一整天。
现在我们释放了驱动器上的空间,它正在接受消息进入队列,但它似乎没有处理它们 - 没有插入新记录,即使队列现在有 2200 万条消息并且还在增长(!)。队列已启用:
is_activation_enabled = 1
is_receive_enabled = 1
is_enqueue_enabled = 1
Run Code Online (Sandbox Code Playgroud)
我在 中看到激活的 SP activation_procedure,但是当我在 中查看时SP_WHOISACTIVE,我没有看到任何活跃的阅读器。
在我再次炸毁驱动器之前 - 我做错了什么?我怎样才能让它处理或刷新消息?提前致谢。
更新
一个想法 - 因为我有is_enqueue_enabled,也许它正在存储所有消息,直到它可以处理所有消息?如果是这样,我可以安全地关闭它吗?
CREATE PROCEDURE [dbo].[Parse_EN_Messages]
AS
--mdb 2012/09/05 version 1.2
-- With apologies and thanks to Remus Rusanu, Jonathon Kehayias, Mladen Prajdic, and Jasper Smith for writing
-- about EN, answering questions, and getting the word out about this awesome feature of SQL Server 2005+.
-- Also thanks to Mikael …Run Code Online (Sandbox Code Playgroud) 在我的应用程序的最后一个版本中,我添加了一个命令,告诉它在 Service Broker 队列中有东西到达时等待:
WAITFOR (RECEIVE CONVERT(int, message_body) AS Message FROM MyQueue)
Run Code Online (Sandbox Code Playgroud)
DBA 告诉我,自从添加以来,日志大小已经飙升。这可能是正确的吗?还是我应该去别处寻找?
是否有学习 Service Broker 的好资源?我正在寻找对新手友好的指南。
我们正在尝试让 Service Broker 在我们的环境中工作以解决业务案例。我不知道消息标题是否合适,但我的问题如下。但这可能不是一个好问题,所以在那之后是我们正在做的事情以及为什么我认为这是一个正确的问题。
在结束对话之前,应该在对话中发送多少条消息?
我们想使用 Service Broker 来异步更新结果表。结果表变平且快速。我们在基表上有触发器,它们发送带有表和主键的消息。我们有三个队列:
基本上,如果客户的信息更新,则会影响许多产品,因此会被发送到批量队列以进行较慢的处理。但是,如果产品更新,则会将其发送到低延迟队列。
我们重用类似于 Remus Rusanu 的博客http://rusanu.com/2007/04/25/reusing-conversations/ 的对话,除了我们根据主键的模数来做。这具有辅助主键重复数据删除的附带好处。
因此,我们正在重复使用对话并且符合我们的指导方针。使用两个线程,我能够每秒处理 125 条消息(人工丢弃数千条消息),这足以跟上生产速度(估计为 15 条消息/秒)。
但是,我们遇到的问题是,经过一段时间(约 4 小时或 120K 条消息)后,我们开始在 sysdesend 和队列表中看到阻塞和高争用。锁是 LCK_M_U 和 KEY 锁。有时,hobt 解析为 sysdesend,有时解析为特定的队列表 (queue_)。
我们有一个流程可以在 24 小时或 30 分钟不活动后结束对话,我们可以增加对话循环之前的时间。
我们使用的是 SQL 2016 Enterprise (13.0.4001.0)
清理过程每 10 分钟运行一次,以查看是否有任何空闲对话。ltd 它连续发现它们超过 3 次,它将其标记为不活动并结束对话。
如果有任何可能有益的其他细节,请告诉我。我对 Service Broker 没有太多经验,所以我不知道我们的消息/秒是低、高还是无动于衷。
更新
所以我们今天再次尝试,遇到了同样的问题。我们将对话生命周期更改为 2 小时,但没有任何影响。所以我们然后实现了 …
我们正忙于对我们在 .NET 4.0 中开发并在后台运行 SQL Server 2008 R2 的 OLTP 系统进行负载测试。系统使用 SQL Server Service Broker 队列,它们的性能非常好,但我们在处理时遇到了一个特殊的趋势。
SQL Server 以极快的速度处理请求 1 分钟,然后增加约 20 秒的磁盘写入活动。下图说明了这个问题。

Yellow = Transactions per second
Blue = Total CPU usage
Red = Sqlsrv Disk Write Bytes/s
Green = Sqlsrv Disk Read Bytes/s
Run Code Online (Sandbox Code Playgroud)
在故障排除期间,我们尝试了以下方法,但模式没有任何重大变化:
似乎 SQL Server 可能正在建立其缓存并以特定的时间间隔将其写入磁盘,但我无法在网上找到任何支持该理论的内容。
接下来,我计划将解决方案转移到我们的专用测试环境中,看看我是否可以复制该问题。在此期间的任何帮助将不胜感激。
更新 1 根据要求,附上一张图表,其中包括Checkpoint Pages/Sec、Page Life Expectancy和一些磁盘延迟计数器。

看起来好像检查点(浅蓝线)是我们观察到的性能下降(黄线)的原因。^
磁盘延迟在处理过程中保持相对一致,页面预期寿命似乎没有任何明显影响。我们还调整了 SQL Server 可用的 ram 量,这也没有太大影响。将恢复模型从 …
我们最近将生产实例从 SQL 2008 R2 迁移到全新的 SQL 2014 服务器。这是我们在使用 Service Broker 时发现的一个有趣场景。考虑一个Broker Enabled = true带有MyService和的数据库MyQueue。此队列上禁用了毒物消息处理。队列中至少有 2 个与消息的活动对话。
在一个进程 (SPID 100) 中执行:
BEGIN TRANSACTION;
DECLARE @conversation_group_id UNIQUEIDENTIFIER;
RECEIVE TOP (1) @conversation_group_id = conversation_handle FROM MyQueue;
Run Code Online (Sandbox Code Playgroud)
请注意,我们将事务保持打开状态。假设它是一个 .NET 程序,它在某些外部资源上等待了很长时间。通过sys.dm_tran_locks我们看到该 SPID 已被授予对队列的 IX 锁。
| type | resource_id | mode | status | spid |
| OBJECT | 277576027 | IX | GRANT | 100 |
Run Code Online (Sandbox Code Playgroud)
在单独的进程 (SPID 101) 中执行五次:
BEGIN TRANSACTION;
DECLARE @conversation_group_id …Run Code Online (Sandbox Code Playgroud) 我们有一个很好的 Python 代码,它可以发送一些电子邮件并与云系统进行交互。工作正常。但是我们必须每隔几分钟就启动它来轮询数据库。出于业务目的,我们确实需要实时启动 python 脚本,因此没有轮询延迟。(这服务于与客户通电话的销售人员。)
我们真的不想要 1 分钟的轮询循环。或 30 秒。我们希望记录显示在数据库中并立即发生。
实现此目的的快速方法是在将特定记录类型插入到表中时触发它。
我们可以从触发器触发 python 脚本吗?
根据下面 Aaron 的说明,我们知道这是一个非常糟糕的事情™,但是这张表很少使用(每天插入 0-12 次)。轮询表无法满足我们的业务需求(我们需要 .py 立即运行——它不仅仅是发送电子邮件)。
我们认为满足我们业务需求的一种方法是在 SQL Server 上设置 .net 版本的 python,然后让 T-SQL 以调用 C# 东西的方式调用 python 脚本......但我们不知道如何真的这样做!(因此这个问题)。
文档/细节?
我在 Stack Overflow 上问了一个后续问题:如何在 SQL Server 中创建 Python CLR 过程?
问题下的问题:你有一块python。您希望它从 SQL 触发器触发,但您知道这是一件非常糟糕的事情。那么,在 SQL 操作中间没有 python 代码的情况下,您如何实际实现相同的效果?
解决这种需求的非触发、非轮询方法是什么?
(同样的效果=“插入/更新/删除发生在表中,并且在db事件的2秒内触发python脚本,不轮询表”)
我每 15 分钟在 SQL Server 错误日志中收到此错误消息。我已经在这台服务器上设置了 AOAG。为该实例上的 Blackberry 相关数据库和 MSDB 数据库启用了数据库选项“Service Broker - Broker Enabled”。黑莓支持提到他们不需要启用此功能。我有其他 AOAG 实例,他们没有收到此错误。
请分享您在这方面的智慧。我还没有使用过服务代理,也没有在我的搜索中找到关于堆栈交换的类似帖子。
谢谢
sql-server service-broker sql-server-2012 availability-groups
在活动监视器中,以下查询导致高 CPU 和 281 毫秒的平均持续时间。
WAITFOR (
RECEIVE conversation_handle
, service_contract_name
, message_type_name
, message_body
FROM ExternalMailQueue
INTO @msgs
)
, TIMEOUT @rec_timeout
Run Code Online (Sandbox Code Playgroud)
任何想法或步骤如何解决这个问题?
service-broker ×10
sql-server ×10
locking ×1
performance ×1
permissions ×1
python ×1
trigger ×1