首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >发送方数据库中的代理处于单用户模式

发送方数据库中的代理处于单用户模式
EN

Database Administration用户
提问于 2011-10-21 15:52:14
回答 4查看 2.6K关注 0票数 2

请帮助我从快照恢复后为什么要得到这条sys.transmission_queue.transmission_status消息?

发送方数据库中的代理处于单用户模式。在单用户模式下无法传递消息。

这就是我尝试过但没有成功的地方:

  • 下降到单用户模式
  • 使用NEW_BROKER选项从快照还原
  • 使用NO_WAIT返回多用户模式
  • 检查sys.databases.is_broker_enabled和sys.service_queues.is_receive_enabled
  • 发送一条消息,它将被卡在传输队列中,抱怨单用户模式。

是否有另一个要查询的DMV或目录来查找服务代理的状态?

谢谢。

EN

回答 4

Database Administration用户

发布于 2011-11-02 20:56:32

数据库恢复之后,激活的Service队列似乎没有正确地设置其队列监视器,即使在恢复期间指定了使用ENABLE_BROKER的队列。

显式重新启用service将使队列监视器被正确地重新创建。如果有人有更好的解决办法,我很想听听。

您可以通过查询dm_broker_queue_monitors来检查这个问题,查询处于无文档状态的“丢弃”状态的任何队列,这些队列也没有相应的队列处于不同的状态(例如:‘'INACTIVE')

如果这个查询有任何结果,那么就会有一个断开的队列:

代码语言:javascript
复制
select database_id,queue_id,[state] from sys.dm_broker_queue_monitors m
 WHERE state='DROPPED' 
   and not exists (select 1 from sys.dm_broker_queue_monitors m2 
                    where state <> 'DROPPED' 
                          and m.queue_id=m2.queue_id 
                          and m.database_id=m2.database_id)

您可以通过重新启用service来修复它(是的,即使它已经启用;重新启用它将使队列得到正确的重建)。您需要在单个用户中启用service:

代码语言:javascript
复制
ALTER DATABASE [dbname] SET SINGLE_USER WITH ROLLBACK IMMEDIATE
ALTER DATABASE [dbname] SET ENABLE_BROKER WITH NO_WAIT
ALTER DATABASE [dbname] SET MULTI_USER
票数 2
EN

Database Administration用户

发布于 2011-10-21 16:36:47

在单用户模式下无法传递消息。

这还不够清楚吗?

复制后编辑

您发布的repro是不完整的,它使用对象而不是定义din (数据库和快照)。我使用这个脚本来测试一些我认为类似于您的情况的东西:

代码语言:javascript
复制
USE master
GO

if db_id('Accounting') is not null
begin
    alter database Accounting set single_user with rollback immediate;
    drop database Accounting;
end
go

create database Accounting;
go

alter authorization on database::Accounting to sa;

use Accounting;
go

create queue q;
create service s on queue q ([DEFAULT]);
go

-- Drop to single user mode
ALTER DATABASE [Accounting] SET SINGLE_USER WITH ROLLBACK IMMEDIATE
GO


declare @h uniqueidentifier;
begin dialog conversation @h 
    from service [s]
    to service N's'
    with encryption = off;
send on conversation @h ('Hello, World');
go  

-- Give the queue a bit of time to process
WAITFOR DELAY '0:00:02';
GO
-- Take a look after sending a message
SELECT * FROM sys.transmission_queue; -- 1 row, transmission_status = "...single user ..."
GO

-- Retry same multiuser with ENABLE_BROKER
USE master
GO
ALTER DATABASE Accounting SET MULTI_USER, ENABLE_BROKER WITH NO_WAIT
GO

use Accounting;
go

-- wait for the message delivery
WAITFOR (receive cast(message_body as varchar(8000)), * from q), timeout 60;
GO

-- Look at xmit queue
USE Accounting;
SELECT * FROM sys.transmission_queue; -- 1 row, no error status.
GO

-- Look again at xmit queue, in 10 seconds
waitfor delay '00:00:10';
USE Accounting;
SELECT * FROM sys.transmission_queue; -- row is gone
GO

这个脚本显示:

  • 当数据库处于单用户模式时,消息不会被传递(延迟)。
  • 在将数据库置于多用户模式后立即传递消息。
  • 发送后,消息将在几秒钟后从传输队列中异步删除。
票数 1
EN

Database Administration用户

发布于 2011-10-22 01:08:52

尝尝这个,

代码语言:javascript
复制
ALTER DATABASE database_name 
SET MULTI_USER, ENABLE_BROKER; 

有一个目录视图sys.databases,使用列user_access。

票数 1
EN
页面原文内容由Database Administration提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://dba.stackexchange.com/questions/7153

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档