We have multiple subscriptions (merge pull) at our subscriber for only 1 "real" subscription. I think we actually broke it like this by adding and removing the subscription from the subscriber side, and then trying to replicate it... multiple times.
Now the problem is not that the replication does not work, I'm pretty confident that I the answer for that. The problem is that I can't drop/delete the broken subscriptions at the subscriber anymore. It just does not work.
When trying to run sp_dropmergepullsubscription at the publisher, it tells me "No subscription is on this publication article".
When trying to run sp_dropsubscription at the publisher, it tells me "This database is not enabled for subscription"
Yes I've checked that I was running all these scripts on the correct database and all that.
Has anybody had a problem like this before ?
Do I need to re-do the publication and the subscription ?
Thanks guys and gals ! :)
Try the following on the publisher:
EXEC sp_dropmergesubscription
#publication = '<publicationName>',
#subscriber = '<subscriberName>',
#subscriber_db = '<dbName>;
GO
delete sysmergesubscriptions where subscriber_server = '<subscriberName>'
use distribution
go
delete msmerge_Agents where subscriber_name = '<subscriberName>'
delete msmerge_subscriptions where subscriber = '<subscriberName>'
...then try setting the pull subscription back up
Related
I’m wondering if someone with knowledge/experience of SQLWatch could help me out with something.
We have SQLWatch set up on 2 DEV servers and 1 Central monitoring server, its working fine and the data from the 2 DEV servers is coming over to the central server, I can see alerts are being recorded in the table - [dbo].[sqlwatch_logger_check].
However, our issue that we are not being notified by any means (email, Powershell script running).
What’s interesting is that if we drop a row into the table [dbo].[sqlwatch_meta_action_queue] then alert notification does happen.
So our issue seems to be for some reason alerts are being raised but the record is not being inserted into the queue table. I suspect some sort of mapping issue but as it stands now it all looks ok, I use the following to check
SELECT C.check_id,check_name,check_description,check_enabled,A.action_description,A.action_exec_type,A.action_exec
FROM [dbo].[sqlwatch_config_check] C
LEFT JOIN [dbo].[sqlwatch_config_check_action] CA ON C.check_id = CA.check_id
LEFT JOIN [dbo].[sqlwatch_config_action] A ON CA.action_id = A.action_id
WHERe C.check_id = -1
And it shows the failed job is set to run our PowerShell script, which it does when the row is manually inserted.
Any ideas on what the cause may be here?
Thanks,
Nic
I am the creator of SQLWATCH.
Firstly, just to clarify, default notifications that come with SQLWATCH only work in a local scope i.e. they will happen on each monitored instance where ##SERVERNAME = sql_instance. If you are expecting the default notifications to fire from the central server for a remote instance this will not happen. The default notifications on the central server will only fire for the central server itself and not for data imported from the remote instances. This is done to avoid a situation where pull into the central repository is rare and thus notifications could be well delayed.
However, there is nothing stopping you from creating Check Rules or Reports to fire on the back of the imported data.
Secondly, the checks are not alerts per se. Checks are just... well, checks... that run periodically and make sure everything is in order. Checks can trigger an action to send an email. For this, as you have worked out, there is an association table that links together checks and actions.
As for your problem, is the actual action enabled? All actions that are not associated with report are disabled by default as they need to be configured first:
Add a column to your query to bring action_enabled column:
SELECT C.check_id, check_name, check_description, check_enabled, A.action_description, A.action_exec_type, A.action_exec, [action_enabled]
FROM [dbo].[sqlwatch_config_check] C
LEFT JOIN [dbo].[sqlwatch_config_check_action] CA ON C.check_id = CA.check_id
LEFT JOIN [dbo].[sqlwatch_config_action] A ON CA.action_id = A.action_id
WHERE C.check_id = -1
Or, there is already a view that should provide you with the complete mapping:
SELECT *
FROM [dbo].[vw_sqlwatch_report_config_check_action]
WHERE check_id = -1
The application log table [dbo].[sqlwatch_app_log] should also contain valuable information. Did you look in there for anything out of ordinary?
Summarising
In order to enable alerts in a brand new install of SQLWATCH, all it's needed is setting up action_exec with your email details and action_enabled set to 1. If you have made some other changes it may be easier to reinstall back to default.
I have queues created in proper order like so:
CREATE MESSAGE TYPE MyMessageType AUTHORIZATION dbo VALIDATION = WELL_FORMED_XML
GO
CREATE CONTRACT MyMessageContract AUTHORIZATION [dbo] (MyMessageType SENT BY INITIATOR)
GO
CREATE QUEUE [dbo].[MyMessageQueue] WITH STATUS = ON , RETENTION = OFF
GO
CREATE SERVICE [MyMessageService] ON QUEUE [dbo].[MyMessageQueue] (MyMessageContract)
The issue I'm having is when I try delete them all. I start with dropping the service first or contract first or any other one at first, it doesn't matter, I cannot delete.
Any tips?
Please note that the the queue is EMPTY..
Thanks!
It turned out to be a patching issues. We applied all the latest patches and the issue disappeared.
Server Version: SQL Server 2008R2
Client Version: SQL Server Express 2008R2
I have been encountering what appears to be locking issues when I run my merge replication process. It appears to be when a change is made on the subscriber and sync'd with the publisher. I am positive is coming from the triggers because it is appearing that they are firing on the publisher again and probably trying to send data down to the subscribers again. I have added "NOT FOR REPLICATION" to the triggers, but that doesn't seem to be helping. I also researched and tried adding the below clause as well.
DECLARE #is_mergeagent BIT
SELECT #is_mergeagent = convert(BIT, sessionproperty('replication_agent'))
IF #is_mergeagent = 0 --IF NOT FROM REPLICATION
That didn't seem to help either. How do you handle Merge Replication with Insert / Update triggers? Can I prevent them from "Double" firing?
Always appreciate the info.
--S
Not sure about triggers firing but SESSIONPROPERTY will give NULL here. So the subsequent test always fails.
<Any other string> [gives] NULL = Input is not valid.
You probably mean APP_NAME
This should at least assist troubleshooting...
i'd add a bit field to the table that's causing the issue and call it "processed" or something like that. have it default to false and then set to true when the trigger updates that record, and have the trigger check for a false value before it does anything, otherwise have it do nothing.
I have updated my database with this query:
UPDATE suppliers SET contactname = 'Dirk Lucky'
So all the rows in the suppliers table have the contact name: "Dirk Lucky."
How can I rollback this transaction? I want to restore my the contactname column in the suppliers table.
Thanks,
Programmer
Sounds like your transaction has already been committed. You can't roll it back anymore.
Your only option is restoring a backup. You might be able to restore a backup as a new database, so you can copy only the contactnames and not lose any other changes.
If you have the full log in FULL mode, you can do a restore from the log. There's an excellent blog post about it here.
If you don't, I seriously hope that you have a backup.
For future reference: When I do updates, I use the following syntax:
SELECT *
--UPDATE a SET col = 'val'
FROM myTable a
WHERE id = 1234
That way, you can see what you're selecting to update first. Then, when you're finally ready to update, you just select from UPDATE down and run the query. I've caught myself many times with this trick. It also works with deletes, so that's a bonus.
Hopefully your database is using the Full Recovery Model. If so:
First you need to take a transaction log backup now.
You can then look to perform a database restore from your FULL backup + Differntials.
Once done, you can then restore the transaction log to a specific point in time prior to your update statement.
See "How to Restore to a point in time"
As other posters have suggested, you could restore to another database, and apply an update back to the live database should you wish to minimise downtime.
Hope this makes sense but let me know if you need assistance.
I have transactional replication running between two databases. I fear they have fallen slightly out of sync, but I don't know which records are affected. If I knew, I could fix it manually on the subscriber side.
SQL Server is giving me this message:
The row was not found at the Subscriber when applying the replicated command. (Source: MSSQLServer, Error number: 20598)
I've looked around to try to find out what table, or even better what record is causing the issue, but I can't find that information anywhere.
The most detailed data I've found so far is:
Transaction sequence number: 0x0003BB0E000001DF000600000000, Command ID: 1
But how do I find the table and row from that? Any ideas?
This gives you the table the error is against
use distribution
go
select * from dbo.MSarticles
where article_id in (
select article_id from MSrepl_commands
where xact_seqno = 0x0003BB0E000001DF000600000000)
And this will give you the command (and the primary key (ie the row) the command was executing against)
exec sp_browsereplcmds
#xact_seqno_start = '0x0003BB0E000001DF000600000000',
#xact_seqno_end = '0x0003BB0E000001DF000600000000'
I'll answer my own question with a workaround I ended up using.
Unfortunately, I could not figure out which table was causing the issue through the SQL Server replication interface (or the Event Log for that matter). It just didn't say.
So the next thing I thought of was, "What if I could get replication to continue even though there is an error?" And lo and behold, there is a way. In fact, it's easy. There is a special Distribution Agent profile called "Continue on data consistency errors." If you enable that, then these types of errors will just be logged and passed on by. Once it is through applying the transactions and potentially logging the errors (I only encountered two), then you can go back and use RedGate SQL Data Compare (or some other tool) to compare your two databases, make any corrections to the subscriber and then start replication running again.
Keep in mind, for this to work, your publication database will need to be "quiet" during the part of the process where you diff and fix the subscriber database. Luckily, I had that luxury in this case.
If your database is not prohibitively large, I would stop replication, re-snapshot and then re-start replication. This technet article describes the steps.
If it got out of sync due to a user accidently changing data on the replica, I would set the necessary permissions to prevent this.
This replication article is worth reading.
Use this query to find out the article that is out of sync:
USE [distribution]
select * from dbo . MSarticles
where article_id IN ( SELECT Article_id from MSrepl_commands
where xact_seqno = 0x0003BB0E000001DF000600000000)
of course if you check the error when the replication fails it also tells you which record is at fault and you could extract that data from the core system and just insert it on the subscriber.
This is better than skipping errors as with the SQL Data Compare it will lock the table for the comparison and if you have millions of rows this can take a long time to run.
Tris
Changing the profile to "Continue on data consistency errors" won't always work. Obviously it reduces or nullifies an error, but you won't get the whole proper data. It will skip the rows by which an error occurs, and hence you fail to get accurate data.
the following checks resolve my problem
check that all the replication SQL Agents jobs are working fine and if not start them.
in my case it was stopped because of some killed session occurred a few hours before by Some DBA because of blocking issue
after a very short time all data in subscription were updated and no
other error in replication monitor
in my case all above queries did not returned nothing
This error usually comes when particular record does not exists on subscriber and a update or delete command executed for same record on primary server and which got replicated on subscriber as well.
As this records does not exists on subscriber, replication throws an error " Row Not Found"
Solution of this error to make replication work back to the normal running state:
We can check with following query, whether request at publisher was of update or delete statement:
USE [distribution]
SELECT *
FROM msrepl_commands
WHERE publisher_database_id = 1
AND command_id = 1
AND xact_seqno = 0x00099979000038D6000100000000
We can get artical id information from above query, which can be passed to below proc:
EXEC Sp_browsereplcmds
#article_id = 813,
#command_id = 1,
#xact_seqno_start = '0x00099979000038D60001',
#xact_seqno_end = '0x00099979000038D60001',
#publisher_database_id = 1
Above query will give information about, whether it was a update statement or delete statement.
In Case of Delete Statement
That record can be directly deleted from msrepl_commands objects so that replication wont make retry attempts for the record
DELETE FROM msrepl_commands
WHERE publisher_database_id = 1
AND command_id =1
AND xact_seqno = 0x00099979000038D6000100000000
In case of update statement:
You need to insert that record manually from publisher DB to subscriber DB: