Service Broker queue message [duplicate] - sql-server

I am learning how to use the Service Broker of SQL Server 2008 R2. When following the tutorial Completing a Conversation in a Single Database. Following the Lesson 1, I have successfully created the message types, contract, the queues and services. Following the Lesson 2, I have probably sent the message. However, when trying to receive the message, I get the NULL for the ReceivedRequestMsg instead of the sent content.
When looking at the sys.transmission_queue, the transmission_status for the message says:
An exception occurred while enqueueing a message in the target queue. Error: 15517, State: 1. 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.
I have installed SQL Server using the Windows login like Mycomp\Petr. I am using that login also for the lessons.
Can you guess what is the problem? What should I check and or set to make it working?
Edited 2012/07/16: For helping to reproduce the problem, here is what I did. Can you reproduce the error if you follow the next steps?
Firstly, I am using Windows 7 Enterprise SP1, and Microsoft SQL Server 2008 R2, Developer Edition, 64-bit (ver. 10.50.2500.0, Root Directory located at C:\Program Files\Microsoft SQL Server\MSSQL10_50.SQL_PRIKRYL05\MSSQL).
Following the tutorial advice, I have downloaded the AdventureWorks2008R2_Data.mdf sample database, and copied it into C:\Program Files\Microsoft SQL Server\MSSQL10_50.SQL_PRIKRYL05\MSSQL\DATA\AdventureWorks2008R2_Data.mdf
The SQL Server Management Studio had to be launched "As Administrator" to be able to attach the data later. Then I connected the SQL Server.
Right click on Databases, context menu Attach..., button Add..., pointed to AdventureWorks2008R2_Data.mdf + OK. Then selected the AdventureWorks2008R2_Log.ldf from the grid below (reported as Not found) and pressed the Remove... button. After pressing OK, the database was attached and the AdventureWorks2008R2_log.LDF was created automatically.
The following queries were used for looking at "Service Broker enabled/disabled", and for enabling (the Service Broker was enabled successfully for the database):
USE master;
GO
SELECT name, is_broker_enabled FROM sys.databases;
GO
ALTER DATABASE AdventureWorks2008R2
SET ENABLE_BROKER
WITH ROLLBACK IMMEDIATE;
GO
SELECT name, is_broker_enabled FROM sys.databases;
GO
Then, following the tutorial, the queries below were executed to create the message types, the contract, the queues, and the services:
USE AdventureWorks2008R2;
GO
CREATE MESSAGE TYPE
[//AWDB/1DBSample/RequestMessage]
VALIDATION = WELL_FORMED_XML;
CREATE MESSAGE TYPE
[//AWDB/1DBSample/ReplyMessage]
VALIDATION = WELL_FORMED_XML;
GO
CREATE CONTRACT [//AWDB/1DBSample/SampleContract]
([//AWDB/1DBSample/RequestMessage]
SENT BY INITIATOR,
[//AWDB/1DBSample/ReplyMessage]
SENT BY TARGET
);
GO
CREATE QUEUE TargetQueue1DB;
CREATE SERVICE
[//AWDB/1DBSample/TargetService]
ON QUEUE TargetQueue1DB
([//AWDB/1DBSample/SampleContract]);
GO
CREATE QUEUE InitiatorQueue1DB;
CREATE SERVICE
[//AWDB/1DBSample/InitiatorService]
ON QUEUE InitiatorQueue1DB;
GO
So far, so good.
Then the following queries are used to look at the queues (now empty when used):
USE AdventureWorks2008R2;
GO
SELECT * FROM InitiatorQueue1DB WITH (NOLOCK);
SELECT * FROM TargetQueue1DB WITH (NOLOCK);
SELECT * FROM sys.transmission_queue;
GO
The problem manifests when the message is sent:
BEGIN TRANSACTION;
BEGIN DIALOG #InitDlgHandle
FROM SERVICE
[//AWDB/1DBSample/InitiatorService]
TO SERVICE
N'//AWDB/1DBSample/TargetService'
ON CONTRACT
[//AWDB/1DBSample/SampleContract]
WITH
ENCRYPTION = OFF;
SELECT #RequestMsg =
N'<RequestMsg>Message for Target service.</RequestMsg>';
SEND ON CONVERSATION #InitDlgHandle
MESSAGE TYPE
[//AWDB/1DBSample/RequestMessage]
(#RequestMsg);
SELECT #RequestMsg AS SentRequestMsg;
COMMIT TRANSACTION;
GO
When looking at the queues, the Initiator... and the Target... queues are empty, and the sent message can be found in sys.transmission_queue with the above mentioned error reported via the transmission_status.

alter authorization on database::[<your_SSB_DB>] to [sa];
The EXECUTE AS infrastructure requires dbo to map to a valid login. Service Broker uses the EXECUTE AS infrastructure to deliver the messages. A typical scenario that runs into this problem is a corporate laptop when working from home. You log in to the laptop using cached credentials, and you log in into the SQL using the same Windows cached credentials. You issue a CREATE DATABASE and the dbo gets mapped to your corporate domain account. However, the EXECUTE AS infrastructre cannot use the Windows cached accounts, it requires direct connectivity to the Active Directory. The maddening part is that things work fine the next day at office (your laptop is again in the corp network and can access to AD...). You go home in the evening, continue with Lesson 3... and all of the sudden it doesn't work anymore. Make the whole thing seem flimsy and unreliable. Is just the fact that AD conectivity is needed...
Another scenatio that leads to the same problem is caused by the fact that databases reteint the SID of their creator (the Windows login that issues the CREATE DATABASE) when restored or attached. If you used a local account PC1\Fred when you create the DB and then copy/attach the database to PC2, the account is invalid on PC2 (it is scoped to PC1, of course). Again, not much is affected but EXECUTE AS is, and this causes Service Broker to give the error you see.
And last example is when the DB is created by a user that later leaves the company and the AD account gets deleted. Seems like revenge from his part, but he's innocent. The production DB just stops working, simply because it's his SID that the dbo maps too. Fun...
By simply changing the dbo to sa login you fix this whole EXECUTE AS thing and all the moving parts that depend on it (and SSB is probably the biggest dependency) start working.

You would need to grant receive on your target queue to your login. And it should work!
USE [YourDatabase]
GRANT RECEIVE ON [dbo].[YourTargetQueue]
TO [Mycomp\Petr];
GO
And you also need to grant send for your user, permission on Target Service should be sufficient, but let's enable on both services for the future.
USE AdventureWorks2008R2 ;
GO
GRANT SEND ON SERVICE::[//AWDB/1DBSample/InitiatorService]
TO [Mycomp\Petr] ;
GO
GRANT SEND ON SERVICE::[//AWDB/1DBSample/TargetService]
TO [Mycomp\Petr] ;
GO

Related

Bulk Insert failed when executed from remote client but success on local

Please find the diagram as below for my issue:
I have 3 servers in the same domain, there is a SQL Server instance A (it's windows service run under domain\User1), In this instance, we have a Stored Procedure used for BULK INSERT a text file from a network shared folder in server C, the domain\User1 has full permissions on this folder.
My issue is: The Stored Procedure runs ok (green arrow) when connecting by SSMS in its (server A). But it failed when I change to SSMS in server B (log in by the same domain\User1 to the same Instance A). The error is "Access denied" to the text file (red arrow). Does the client have a role in this? I think the client does not matter, the file reading is done from the server (by the user that run Instance A service)
Note: If I connect Instance A from SSMS B with SQL Logon User (not windows account), the stored procedure works fine.
Could anyone give me some advice and sorry for my bad English
This is just a link answer but hopefully it helps.
BTW I commend you for taking the time to analyse the issue to the extent of drawing a diagram. This is far higher quality than most questions on here.
I believe you are running into a double hop issue. I searched everywhere for the BULK INSERT permission model and finally found this https://dba.stackexchange.com/questions/189676/why-is-bulk-insert-considered-dangerous
which says this about using BULK INSERT:
When accessing SQL Server via a Windows Login, that Windows account
will be impersonated (even if you switch the security context using
EXECUTE AS LOGIN='...') for doing the file system access
and this
when accessing SQL Server via a SQL Server Login, then the external
access is done in the context of the SQL Server service account
When you have issues with windows authentication and there is three servers and impersonation, it's often a double hop issue.
This may help you with that:
https://dba.stackexchange.com/questions/44524/bulk-insert-through-network
Which in turn references this:
https://thesqldude.com/2011/12/30/how-to-sql-server-bulk-insert-with-constrained-delegation-access-is-denied/

What SQL user is used by TFS to send alerts?

We are running into a few issues with our TFS installation (TFS 2013 Update 4, SQL 2014 Standard) as a result of email alerts. Most notably, Work Items cannot be created, because this triggers an email.
Any time a process or user attempts to create a Work Item, the error
TF30040: The database is not correctly configured. Contact your Team Foundation Server administrator.
is received. Further, when I check the Event Viewer on the server, I can see the error and it reports that the inner exception is:
Exception Message: The EXECUTE permission was denied on the object 'sp_send_dbmail', database 'msdb', schema 'dbo'. (type SqlException)
I have worked with the DBA and we have enabled Email Alerts on the server. We have verified that, in general, the alerts work by using the test button on the administration console. I can also set up a check-in alert through the web interface and receive said alerts without issue. This seems to be specifically affecting Work Item creation alerts (which apparently are just automatically and irrevocably enabled).
Presumably, we could correct this by giving appropriate permissions to use that stored procedure. To do so, we need to know what user to give permissions to. So far we have tried giving execute permissions to my AD user, the service account used by the build service, and the Network Service account (which appears to be the TFS Service Account).
There is no indication in any error message as to what user is being used to execute that procedure. So, my question: What SQL user is used to send alerts when creating Work Items?
Edit:
For the record, this started working of its own accord. We decided Monday to call Microsoft to get this fixed. Before that happened, failed builds magically created some work items (on Tuesday, a full day after we gave up), and we are now able to create work items. Everyone involved states not doing anything. We are baffled, but in a good way.
I'm going to advise you that a DBA should not be making changes to the TFS databases. I suggest opening a ticket with MSFT and getting assistance from the product support group.

Troubleshooting Service Broker: initiator database stuck CONVERSING/NOTIFIED

We are developing an application that will use service broker to transfer messages from one database to another. SourceDB is used by an existing application from which we are siphoning off some data. TargetDB is used only by this application and processes/distributes the data we need. We are only using one type of contract and both DBs are on the same server.
We have set up identical message types and contracts on both, and respective initiator and target queue/service. On both databases:
ENABLE_BROKER is set
TRUSTWORTHY is set
Have a unique service_broker_guid
Have sa as db owner, with all SSB authorization statements are dbo or OWNER, as appropriate.
However, when we send a message from SourceDB:
BEGIN DIALOG CONVERSATION #dialogHandle
FROM SERVICE [//Service/Initiator]
TO SERVICE N'//Service/Target'
ON CONTRACT [//Contract/Notification]
WITH ENCRYPTION = OFF;
SEND ON CONVERSATION #dialogHandle
MESSAGE TYPE [//Message/Notification] (#RequestMsg);
...messages do not find their way there. Further investigation reveals the following:
The initiator queue is empty
The target queue is empty (NB: not an issue of needing to RECEIVE)
The transmission queue is empty
No errors are recorded, either in the SQL Server logs or in our CATCH error handling in the stored procedure that creates the message
The initiator queue's entry in SourceDB's sys.dm_broker_queue_monitors is set to NOTIFIED if activation is enabled
SourceDB's sys.conversation_endpoints has a new entry in CONVERSING state
The target queue's entry in TargetDB's sys.dm_broker_queue_monitors remains INACTIVE if activation is enabled
TargetDB's sys.conversation_endpoints has a new entry in CONVERSING state with the same conversation_id and different conversation_handle from SourceDB's entry
Although the test database is SQL 2005 (application must support 2005), I ran the ssbdiagnose utility from my development machine's 2008 installation to dianose the issue:
ssbdiagnose -S testserver -d SourceDB CONFIGURATION FROM SERVICE //Service/Initiator TO SERVICE //Service/Target ON CONTRACT //Contract/Notification
That produced the following:
D 29912 dbtestsvr SourceDB Service //Service/Target was not found
D 29975 dbtestsvr SourceDB User dbo does not have SEND permission on service //Service/Target
This is confusing, since dbo should not be denied any permission, and //Service/Target certainly does exist, albeit in a different database. But my coworker ran a Profiler trace that showed a command being executed looking for //Service/Target on SourceDB. Service broker seems to be getting confused somehow. Adding an explicit route, in addition to being theoretically unnecessary, does not change the situation.
I ran a nearly-identical set of tutorial commands on our test server and everything worked fine, so it is likely something db-specific.
Our setup was working two days ago, so we're probably looking for some setting that might have gotten changed, but with no luck.

Problems with sending notification emails from SQL Server 2008

I have a problem setting up email notifications in SQL Server 2008.
I am using SQL Server 2008 to build a data cube. This process consists of several jobs, that are all scheduled to run each night at a specific time. To see whether a job was running without any failure, it is possible to set up email notification.
(source: smilinginthesun.de)
(source: smilinginthesun.de)
Unfortunately, no email is sent even though I think I have set up database mail correctly.
All guides I can found just explains, how to set up database mail (eg. http://blog.sqlauthority.com/2008/08/23/sql-server-2008-configure-database-mail-send-email-from-sql-database/), but thats it.
If I sent a mail to test functionality (via test email button or from T-SQL script) it works just fine and the email arrives. But when using the notification feature in a job, it doesn't even create a sysmail_mailitems or sysmail_log entry.
I have also send an email using sp_notify_operator, successfully. So the operator set up seems to work, too. (Thanks, Joe Stefanelli, for the hint.)
There is a great workaround written for SQL Server 2005, that works for me, too: http://www.howtogeek.com/howto/database/sending-automated-job-email-notifications-in-sql-server-with-smtp/, but why isn't it possible to just use that build-in functionality?
Does anyone knows if there is anything else to do, to make that email notification task work properly? Thanks in advise.
I am late but I saw your post having the same problem.
The solution is to enable a mail profile for alerts.
For this:
Right click on "SQL Server Agent"
Then "Properties".
Then go to "Alert System" section.
Tick the "Enable mail profile" box.
Then "OK".
Restart the SQL Server Agent service.
To send email notifications from agent jobs in SQL Server Agent, the alarm system must be activated. We did that. After restarting the agent, the Database Mail system should be used. Unfortunately, this does not work. The agent was still trying to reach a Mapi profile (as in SQL 2000).
The following registry value wasn't set: "UseDatabaseMail"=dword:00000001
After setting it to 1, the database mail system was used.
You can do that in SQL server, directly:
EXEC master.dbo.xp_instance_regwrite N'HKEY_LOCAL_MACHINE', N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent', N'UseDatabaseMail', N'REG_DWORD', 1
I've tried what ZeuG. indicated and still didn't have success... then I restarted the SQL Agent. That's what made the job email notification work for me.
For me, SQL email worked fine when I right-clicked Database Mail and said Send Test Email. However, after setting up alerts for all severities and running RAISERROR (N'Test alert!', 20, 1) WITH LOG;, no email came through. The issue is the service account that SQL Server Agent runs under. Apparently, the virtual account NT Service\SQLSERVERAGENT (or whatever your default may be) does not have permissions to access objects on the network and this includes e-mail.
To fix, change the service to use a local account under the Users group, restart SQL Server agent, and then try running a command that throws an error like the RAISERROR statement above. You should now receive the email.

How do I get dbmail to process items from the queue for SQL Server 2005?

When I use the sp_send_dbmail stored procedure, I get a message saying that my mail was queued. However, it never seems to get delivered. I can see them in the queue if I run this SQL:
SELECT * FROM msdb..sysmail_allitems WHERE sent_status = 'unsent'
This SQL returns a 1:
SELECT is_broker_enabled FROM sys.databases WHERE name = 'msdb'
This stored procedure returns STARTED:
msdb.dbo.sysmail_help_status_sp
The appropriate accounts and profiles have been set up and the mail was functioning at one point. There are no errors in msdb.dbo.sysmail_event_log.
Have you tried
sysmail_stop_sp
then
sysmail_start_sp
I had the same problem and this is how I was able to resolve it.
Go to Sql Agent >> Properties >> Alert System >> Check the Enable box for DBMail and add a profile.
Restart Agent and it works since then.
Hope this helps,
_Ub
Could be oodles of things. For example, I've seen (yes, actually seen) this happen after:
Domain controller reboot
Exchange server reboot
Router outage
Service account changes
SQL Server running out of disk space
So until it happens again, I wouldn't freak out over it.

Resources