How do I monitor the age of messages in SQL Service Broker? - sql

I have a SQL Server 2008 Service Broker queue that processes messages by calling a CLR stored procedure (which, in turn, transports the messages via HTTP to a third party's REST API). I need to get a handle on "how backed up?" or "how far behind?" this queue is. While I understand that the total number of messages in the queue is a good indicator of progress, what I'm interested in is "how long was the most recently handled message waiting in the queue to be processed?" As best I can tell, selecting from the queue gives you all of the messages in it, but does not give the age of the message. For example:
SELECT TOP 100 *, casted_message_body =
CASE message_type_name WHEN 'X'
THEN CAST(message_body AS NVARCHAR(MAX))
ELSE message_body
END
FROM [SyncReadTargetQueue] WITH(NOLOCK)
But, none of the columns indicate age.
Any ideas?

To get the time when message arrived you could use "security_timestamp" in sys.conversation_endpoints.
How to monitor Service Broker- maybe this helps.

Related

Extended Events connection_id vs client_connection_id

Hello guys I want to find a way to identify a query executed for Extended Events in Microsoft SQL Server (to filter the Extended Event with only that executed query)
If i query the system views in SQL Server like this:
SELECT session_id, connection_id
FROM sys.dm_exec_requests
WHERE session_id = ##SPID
I get the connection_id of the current query executing which is unique until SQL Server restarts.
But Extended Events have a different value called 'sqlserver.client_connection_id' which is not the same identifier as 'connection_id' from the table 'sys.dm_exec_requests'.
Do you know where can I find the 'sqlserver.client_connection_id' in system tables? or another solution to unquely identify a executed query?
The client_connection_idin Extended Events (according to SSMS)
Provides the optional identifier provided at connection time by a client
and is the SqlConnection.ClientConnectionId, which is intended to support troubleshooting client connectivity issues.
You can locate the connection ID in the extended events log to see if
the failure was on the server if the extended event for logging
connection ID is enabled. You can also locate the connection ID in the
connection ring buffer (Connectivity troubleshooting in SQL Server
2008 with the Connectivity Ring Buffer) for certain connection errors.
If the connection ID is not in the connection ring buffer, you can
assume a network error.
So this id correlates the client-side and server-side of the connection attempt. For successful connections a row in sys.dm_exec_connections and sys.dm_exec_sessions will be created with different id's.
I'm trying to create an Extended Event with error_reported of all queries. And then filter the results in .xel file using an identifier that tells me that this was from X query.
You can capture the query in the error_reported event, eg:
CREATE EVENT SESSION [errors] ON SERVER
ADD EVENT sqlserver.error_reported(
ACTION
(
sqlserver.client_app_name,
sqlserver.session_id,
sqlserver.sql_text
)
WHERE ([severity]>=(11)))
Extended Evets by default tracks all of the connections and activity on the instance. Your filters in the definition will limit that down.
The sqlserver.client_connection_id includes all of the values from all of the queries - so if you DID know the client connection id then you could identify those results.
I'm not clear what you are trying to filter for with the Extended Event? Are you looking to see where a specific query was executed from or track all the queries on a specific connection?
The other places you can look to get the same connection info are :
SELECT * FROM sys.dm_exec_connections
SELECT * FROM sys.dm_exec_sessions
SELECT * FROM sys.dm_exec_requests
Looking at these might help you link the make the connection.

How long does a sql mirror failover take to complete?

We are mirroring our database and I would like to know how long it would take to complete a failover from the time that I click "failover" in sql?
You need to understand .,how mirroring works before that..
Mirroring transfers log blocks over wire.once the log is hardened on secondary,Primary will commit the log only then(synchronous mode).They also keep track of the last LSN ,both recieved in case of failovers/unexpected shutdowns..
So when you failover,*minimum expected recovery time is the time that is need to REDO/UNDO the log on secondary*
This is a high level overview,it also depends on so many things like your mirroring mode,automatic failover/manual failover..
You can also use performance counters to check REDO queue size and log that needs to be sent to mirror yet..
select * from sys.dm_os_performance_counters where object_name like ‘%mirror%’
Which gives us..
here is good place to learn more....
https://technet.microsoft.com/en-us/library/ms189590(v=sql.105).aspx

SQL Server : Replication Error - the row was not found at the Subscriber when applying the replicated command

I got the following error in Activity Monitor,
The row was not found at the Subscriber when applying the replicated command. (Source: SQL Server, Error number: 20598)
After some research, I found out the error occurs because it's trying to delete records which are not exists in the subscriber(Also are not exists in publisher)
{CALL [dbo].[sp_MSdel_testtable] (241)}
I can manually insert something to the record and the replication will move on. The problem I have right now is I don't how many bad records are there. Is there any fast way to do this? I already spends hours and inserted about 20 records.
Thank you
Re-initialize the subscription via Replication Monitor in SSMS, and generate a new snapshot during re-initialization. This should clear up the missing record issues.
Dude, I [literally] just solved this a few minutes ago. It pushed me about a fifty cent cab ride short of crazy. The replicated database was part of a third party solution to offload their app's reporting. As it turns out, one of their app servers was pointed to our reporting database rather than the live database. Hence, "row not found at subscriber." because they were inserting and deleting records in the subscriber table.
Use distribution.dbo.sp_helpsubscriptionerrors to find the xact_seqno, then you can use distribution.dbo.browsereplcmds and this query
SELECT *
FROM distribution.dbo.MSarticles
WHERE article_id in (
SELECT article_id
FROM MSrepl_commands
WHERE xact_seqno = 0x xact_seqno)
to get more info. Use distribution.dbo.sp_setsubscriptionxactseqno if you want to get that single transaction "un-stuck" or just re-initialize.
I ended up running SQL Profiler on both the publisher and subscriber, then keyed off the tables I found with the queries above. That's when I spotted the DML on the replicated table.
Good luck.
This query will give you all the pending commands for that article, which needs to be sent from distributor to subscriber.
Here you will get multiple records with same xact_seqno_start and xact_seqno_end but with different command ids.
You can check if all are delete commands, you can take primary key column value for all and insert them manually to subscriber server.
EXEC Sp_browsereplcmds
#article_id = 813,
#command_id = 1,
#xact_seqno_start = '0x00099979000038D60001',
#xact_seqno_end = '0x00099979000038D60001',
#publisher_database_id = 1

Reading multiple lines from the queue in service broker in SQL server

I am using the following command to read from the queue. But it returns only one row. I noticed that conversation_handle is unique for all messages. How can I read top 100 or all the rows from the queue in sql server?
RECEIVE *-- #handle=conversation_handle, --#xml=CAST(message_body AS XML) FROM EventData_Destination_Queue
as documentation says:
WHERE
Specifies the conversation or conversation group for the received messages. If omitted, returns messages from the next available
conversation group.
That mean- if next conversation group contains 1 message, it returns just 1 message. So maybe what you want is to group messages in one conversation group at the time of sending them.

Executing SQL Query after particular point iof Time

In our project we have requirement that, after receiving sms message from third party
service provider exactly after 3 minutes i need to execute a sql query to update database.
how should i do this , any suggestions are accepted.
** is it possible using stored procedures...
Exactly the scenario is , we are having mediator service application consider it has webservice. from my application when i send a SMS to webservice application via to SMS service provider , this system will push to embedded device , this will make the system to ON. and after 2 min device will send SMS message to pur application thru SMS service provider to say that checking is going on... after receiving this message exactly i need to update database saying that chekcing done succefully. why 3 minutes because exactly after this time device will go Off.
regards,
Mahesh
How exactly are you receiving the SMS Messages. What service is picking them up.
Theres a couple of ways you could do it.
In your Application Code on the SMSReceived Event you could kick off a separate thread to sleep for 180 seconds, and then call your SQL Code.
If you want to do it in the database, you'll need some sort of polling thread.
Record the "TimeReceived" and have a bit flag "PostProcessed"
Then you could just have a job that runs every 60 seconds that goes
SELECT *
FROM ReceivedSMS
WHERE TimeRecieved < dateadd(second, -180, getdatE()) AND
PostProcessed = 0
FOREACH Record - Execute SPROC & Update PostProcessed = 1.
You can use "SQL jobs"
Look at these articles:
http://msdn.microsoft.com/en-us/library/ms187910.aspx
http://dacosta9.wordpress.com/2008/10/22/how-to-disable-or-enable-a-sql-server-job-programatically/
Hope this helps.
Run the stored proc immediately but the first T-SQL line is WAITFOR DELAY '00:03:00' ?