So beheben Sie eine fehlerhafte Replikation auf MS SQL Server


11

Ich habe eine Datenbank aus einem Backup wiederhergestellt. Die Datenbank verwendet die Replikation, um auf einem anderen Server zu veröffentlichen. Unter der Annahme, dass die Datenbankwiederherstellung die Replikation unterbrechen würde, habe ich versucht, die Replikation zu löschen und neu zu erstellen (wir haben ein Skript, um sie von Grund auf neu zu erstellen). Ich bin mir nicht sicher, was ich genau getan habe, aber jetzt ist es in einem völlig durcheinander geratenen Zustand und ich kann es nicht reparieren.

Zuerst versuche ich, das Abonnement (auf dem Publisher-Server) loszuwerden:

EXEC sp_dropsubscription @publication = 'PublicationName', @article = N'all', @subscriber = 'SubscriberServerName'

Das scheint zu funktionieren. SELECT * FROM syssubscriptionszeigt keine Ergebnisse. Auf dem Abonnentenserver SSMS> {SubscriberServer}> Replikation> Lokale Abonnements - das Abonnement ist nicht vorhanden.

Also versuche ich die Publikation zu löschen. SSMS> {Server}> Replikation> Lokale Veröffentlichungen> {Veröffentlichungsname}> Löschen. Dies gibt die folgende Fehlermeldung aus:

Could not delete publication 'PublicationName'.
Could not drop article. A subscription exists on it.
Changed database context to 'DatabaseName'. (Microsoft SQL Server, Error: 14046)

Ok, also versuche ich die Artikel fallen zu lassen:

EXEC sp_droparticle @publication = 'PublicationName', @article = N'all'

und erhalte diesen Fehler:

Invalidated the existing snapshot of the publication. Run the Snapshot Agent again to generate a new snapshot.
Msg 14046, Level 16, State 1, Procedure sp_MSdrop_article, Line 75
Could not drop article. A subscription exists on it.

Ok, ich versuche den Snapshot Agent zu starten und erhalte diese interne SQL-Ausnahme:

The SQL command 'sp_MSactivate_auto_sub' had returned fewer rows than expected by the replication agent.

Also habe ich eine alternative Methode zum Löschen des Artikels ausprobiert DELETE FROM sysarticles. Dies scheint funktioniert zu haben. Ich habe die Artikel jetzt entfernt, erhalte jedoch immer noch den Fehler "Die Veröffentlichung kann nicht gelöscht werden, da für diese Veröffentlichung mindestens ein Abonnement vorhanden ist", wenn ich versuche, die Veröffentlichung zu löschen.

Ich habe auch SQL Server neu gestartet - hat nicht geholfen.

Ich weiß nicht, was hier los ist und wie ich es behebe.

Übrigens passiert dies, wenn Sie einem Softwareentwickler, der gerade genug weiß, um die Schlüssel für die Datenbank gefährlich zu machen, geben. Zum Glück ist dies keine Produktionsumgebung ...

Antworten:


10

TLDR:

Es scheint, dass das Deaktivieren und erneute Aktivieren der Replikation wahrscheinlich das Problem behoben hat:

exec sp_replicationdboption @dbname = N'DatabaseName', @optname = N'publish', @value = N'false'
exec sp_replicationdboption @dbname = N'DatabaseName', @optname = N'publish', @value = N'true'

Ich denke, das entspricht dem Aus- und Wiedereinschalten ...

Längere Version:

Ein Arbeitskollege versuchte es zu beheben. Er versuchte ein paar Dinge, kam aber nicht weit. Die einzige Änderung, die er vor dem Aufgeben vorgenommen hat, war das Deaktivieren der Replikation.

Ich habe dann Codys Vorschlag ausprobiert . Der Befehl sp_dropsubscription hat beanstandet, dass keine Abonnements vorhanden sind. Also habe ich den Befehl sp_droppublication ausprobiert. Dies beschwerte sich darüber, dass die Replikation in der Datenbank nicht aktiviert war. Also habe ich es aktiviert und den Befehl erneut ausgeführt. Diesmal wurde beanstandet, dass die Veröffentlichung nicht existiere. Ich habe den Knoten "Lokale Veröffentlichungen" in SSMS aktualisiert und sicher war er verschwunden. Ich habe das Replikations-Setup-Skript ausgeführt, einen neuen Snapshot generiert und jetzt funktioniert alles ordnungsgemäß. Freude!

Ich bin nicht zu 100% sicher, dass das Deaktivieren und Aktivieren der Replikation das Problem tatsächlich behoben hat, aber es lohnt sich auf jeden Fall, es zu versuchen, wenn die Replikation durcheinander kommt.


Tolle Lektüre für Neulinge. Ist es sicher zu sagen, dass Sie die Replikation zuerst deaktivieren sollten, bevor Sie die Datenbank wiederherstellen?
Keith Rivera

Ich werde das auf jeden Fall das nächste Mal versuchen - nach dem, was ich gelesen habe, sollte die Replikation nicht komplett weggeblasen und neu erstellt werden müssen (wie ich ursprünglich gedacht hatte). Deaktivieren Sie die Replikation, stellen Sie die Datenbank wieder her, aktivieren Sie die Replikation und senden Sie einen neuen Snapshot. Solange die Artikel noch gültig sind, sollte es gut sein zu gehen.
Trotzdem

Total Replication Newbie hier, aber nach dem TLDR; Anweisungen haben zum Verschwinden meiner Veröffentlichungen aus SSMS geführt. Das Abfragen MSPublicationsin der distributionDatenbank zeigt, dass die Veröffentlichung tatsächlich weg ist. Wird das erwartet?
Pimbrouwers

5

Ich hatte ein Durcheinander mit der Replikation und löste es damit

DECLARE @subscriptionDB AS sysname
SET @subscriptionDB = N'DBName'

-- Remove replication objects from a subscription database (if necessary).
USE master
EXEC sp_removedbreplication @subscriptionDB
GO 

Das und:

exec sp_cleanupdbreplication

Sind die Retter beim Aufräumen durcheinandergebrachte Replikationen?


1
Ich glaube, Ihr Beitrag hat mich gerade davor bewahrt, meine Testumgebung neu einzurichten. Ich bin mir nicht sicher, welcher Befehl oben ausgeführt wurde, aber ich kann jetzt Indizes löschen, ohne dass der Fehler auftritt, dass sie zur Replikation veröffentlicht werden. Vielen Dank an dich.
MHSQLDBA

2

Durch das Wiederherstellen der Datenbank wird die Replikation unterbrochen. Das ist also normal. Außerdem handelt es sich bei den meisten anderen Fehlermeldungen nur um Folgemeldungen, da Sie nicht alle Abonnements entfernen konnten (oder zumindest SQL dies glaubt).

Sie wissen, dass Sie Ihren Herausgeber (die Quellendatenbank) und mindestens einen Abonnenten (die Zieldatenbank) haben und dass dies zwei verschiedene Server sind. Ich möchte nur erwähnen, dass es auch einen Distributor gibt, der sich auf einem dieser oder einem anderen Server befindet und wahrscheinlich in einer Datenbank namens Distribution. Manchmal enthält es einige nützliche Informationen, und manchmal fallen die Dinge um, weil die Informationen zwischen den drei nicht übereinstimmen.

Haben Sie bei der Überprüfung der Abonnenten auch diesen Abschnitt auf dem Publisher- Server überprüft, um sicherzustellen, dass nichts anderes aufgeführt ist? Wenn Sie welche finden, können Sie versuchen, sie manuell zu entfernen:

exec sp_dropsubscription @publication = N'xxx', @subscriber = N'xxx', @destination_db = N'xxx', @article = N'all'
-- And if that doesn't work
exec sp_dropsubscription @publication = N'xxx', @subscriber = N'xxx', @destination_db = N'xxx', @article = N'all', @Ignore_Distributor = 1

Angenommen, sie sind wirklich alle verschwunden, versuchen Sie dies in der Publisher-Datenbank:

exec sp_droppublication @publication = N'xxx'
-- And if that doesn't work
exec sp_droppublication @publication = N'xxx', @Ignore_Distributor = 1

Lassen Sie uns wissen, wie es geht. Die Replikation in diesem Zustand verwirrt mich und andere gute Datenbankadministratoren und hat überhaupt nichts damit zu tun, Entwickler zu sein :-)


Danke für den Vorschlag. Der Befehl sp_dropsubscription hat beanstandet, dass keine Abonnements vorhanden sind. Der Befehl sp_droppublication beschwerte sich darüber, dass die Replikation nicht aktiviert war - was mich zu der scheinbar Lösung führte.
TallGuy

Für mich funktionierte der Befehl sp_removedbreplication die meiste Zeit, wenn ich die Replikation zwangsweise entfernen musste.
SQLPRODDBA

0

Die einzige Möglichkeit, Phantomreplikationsartefakte zu entfernen, besteht darin, Abonnements, Artikel und Veröffentlichungen zu löschen. Wenn noch Phantomabonnements vorhanden sind, erstellen Sie die Publikation einschließlich des Phantomabonnements neu. Dies scheint besonders bei älteren Versionen zu funktionieren.


0

Dies ist, was ich normalerweise mache, wenn ich eine Publikation habe, die durcheinander ist.

Es ist ein bisschen hässlich, aber es hat bei vielen Gelegenheiten in verschiedenen Umgebungen für mich funktioniert. Was verursacht es? , Das ist manchmal schwierig , um es herauszufinden, am besten manchmal ist von Grund auf neu zu beginnen, aber auch für die Sie brauchen , um aufzuräumen alldie residualsvon der aktuellen Publikation , die fehlerhaft ist.

nur um es in einen Zusammenhang zu bringen:

Folgendes sehe ich auf dem Replikationsmonitor:

Geben Sie hier die Bildbeschreibung ein

und wenn ich meinen eigenen Replikationsmonitor mit T-SQL verwende :

DECLARE @cmd NVARCHAR(max)
DECLARE @publisher SYSNAME, @publisher_db SYSNAME, @publication SYSNAME, @pubtype INT
DECLARE @subscriber SYSNAME, @subscriber_db SYSNAME, @subtype INT
DECLARE @cmdcount INT, @processtime INT
DECLARE @ParmDefinition NVARCHAR(500)
DECLARE @JobName SYSNAME
DECLARE @minutes INT, @threshold INT, @maxCommands INT, @mail CHAR(1) = 'N'
SET @minutes = 60 --> Define how many minutes latency before you would like to be notified
SET @maxCommands = 80000  --->  change this to represent the max number of outstanding commands to be proceduresed before notification
SET @threshold = @minutes * 60

IF OBJECT_ID ('TEMPDB..#Replication_Qu_History')  IS NOT NULL
   DROP TABLE #Replication_Qu_History

IF OBJECT_ID ('TEMPDB..##PublicationInfo')  IS NOT NULL
   DROP TABLE  ##PublicationInfo

IF OBJECT_ID ('TEMPDB..#PublisherInfo')  IS NOT NULL
   DROP TABLE  #PublisherInfo

IF OBJECT_ID ('TEMPDB..##SubscriptionInfo')  IS NOT NULL
   DROP TABLE  ##SubscriptionInfo

SELECT * INTO #PublisherInfo
FROM OPENROWSET('SQLOLEDB', 'SERVER=(LOCAL);TRUSTED_CONNECTION=YES;'
, 'SET FMTONLY OFF EXEC distribution.dbo.sp_replmonitorhelppublisher')

SELECT @publisher = publisher FROM #PublisherInfo     

SET @cmd = 'SELECT * INTO ##PublicationInfo FROM OPENROWSET(''SQLOLEDB'',''SERVER=(LOCAL);TRUSTED_CONNECTION=YES''
,''SET FMTONLY OFF EXEC distribution.dbo.sp_replmonitorhelppublication @publisher='
+ @publisher + ''')'
--select @cmd
EXEC sp_executesql @cmd

SELECT @publisher_db=publisher_db, @publication=publication, @pubtype=publication_type  FROM ##PublicationInfo

SET @cmd = 'SELECT * INTO ##SubscriptionInfo FROM OPENROWSET(''SQLOLEDB'',''SERVER=(LOCAL);TRUSTED_CONNECTION=YES''
,''SET FMTONLY OFF EXEC distribution.dbo.sp_replmonitorhelpsubscription @publisher='
+ @publisher + ',@publication_type=' + CONVERT(CHAR(1),@pubtype) + ''')'
--select @cmd
EXEC sp_executesql @cmd


ALTER TABLE ##SubscriptionInfo
ADD  PendingCmdCount INT NULL,
EstimatedProcessTime INT NULL


SELECT *
FROM #PublisherInfo

SELECT *
FROM ##SubscriptionInfo 

SELECT *
FROM ##PublicationInfo 

Sie können 2 Zeilen im letzten Feld unten sehen - und eine sollte nicht vorhanden sein:

Geben Sie hier die Bildbeschreibung ein

das gleiche, wenn ich dieses Skript benutze:

EXEC distribution.dbo.sp_replmonitorhelppublication @publisher='my publisher'

Geben Sie hier die Bildbeschreibung ein

Zuerst machen Sie das, was in den anderen Antworten oben gezeigt wird. Wenn das funktioniert , ist das in Ordnung, es funktioniert manchmal, das Problem ist gelöst.

das wäre mehr oder weniger:

exec master.dbo.sp_replicationdboption @dbname = 'my_PUBLICATION', @optname = N'publish', @value = N'false'
exec master.dbo.sp_replicationdboption @dbname = 'my_PUBLICATION', @optname = N'publish', @value = N'true'

sp_droppublication @publication='my_PUBLICATION'

-- Remove replication objects from a subscription database (if necessary).
exec master.dbo.sp_removedbreplication 'my_PUBLICATION'

exec master.dbo.sp_removedbreplication 'my_PUBLICATION'

use my_PUBLICATION

sp_removedbreplication @type='both'


USE [master]
EXEC sp_replicationdboption 
  @dbname = N'my_PUBLICATION', 
  @optname = N'publish', 
  @value = N'false';
GO


EXEC distribution.dbo.sp_replmonitorhelppublication @publisher='PUBLISHER_SERVER'

sp_replmonitorhelppublisher @publisher='PUBLISHER_SERVER'

DECLARE @publicationDB AS sysname;
DECLARE @publication AS sysname;
SET @publicationDB = N'my_PUBLICATION'; 
SET @publication = N'my_PUBLICATION'; 

-- Remove a transactional publication.
USE my_PUBLICATION
EXEC sp_droppublication @publication = @publication;

-- Remove replication objects from the database.
USE [master]
EXEC sp_replicationdboption 
  @dbname = @publicationDB, 
  @optname = N'publish', 
  @value = N'false';
GO

Um diese Veröffentlichung vollständig zu entfernen, beginnen wir mit der Verbindung zum Buscriber und dann zum Publisher und dann zum Distributor gemäß dem folgenden Skript:

-- Connect Subscriber
:connect [SUBSCRIBER_SERVER]
use [master]
exec sp_helpreplicationdboption @dbname = N'SUBSCRIBER_DATABASE'
go
use [SUBSCRIBER_DATABASE]
exec sp_subscription_cleanup @publisher = N'PUBLISHER_SERVER', @publisher_db = N'my_PUBLICATION_DB', 
@publication = N'my_PUBLICATION'
go


-- Connect Publisher Server
:connect [PUBLISHER_SERVER]
-- Drop Subscription
use [my_PUBLICATION]
exec sp_dropsubscription @publication = N'my_PUBLICATION', @subscriber = N'all', 
@destination_db = N'SUBSCRIBER_DATABASE', @article = N'all'
go
-- Drop publication
exec sp_droppublication @publication = N'my_PUBLICATION'
-- Disable replication db option
exec sp_replicationdboption @dbname = N'my_PUBLICATION_db', @optname = N'publish', @value = N'false'
GO

-- Connect Distributor
:CONNECT [PUBLISHER_SERVER]
go

exec Distribution.dbo.sp_MSremove_published_jobs @server = 'PUBLISHER_SERVER', 
@database = N'my_PUBLICATION'
go

--===========================================================================================
--THAT DOES NOT GENERALLY GET RID OF THE JOBS FOR YOU
-- so you need to find them using these selects, and get rid of them manually yourself:

--select * from Distribution.dbo.MSpublications
--select * from Distribution.dbo.MSpublications
--===========================================================================================


select * from Distribution.[dbo].[MSlogreader_agents]
where publisher_db = N'my_PUBLICATION'

--found 1 job:
--PUBLISHER_SERVER-my_PUBLICATION-11

--script the job
--script the job delete script - and run that - keeping the job creation script just in case
exec msdb.dbo.sp_help_job @job_id=0x93C63D34E357704B818312B93FCA02FB
exec msdb.dbo.sp_delete_job @job_id=0x93C63D34E357704B818312B93FCA02FB



select * from Distribution.[dbo].[MSdistribution_agents]
where publisher_db = N'my_PUBLICATION'

--here found 2 jobs:

--PUBLISHER_SERVER-my_PUBLICATION-my_PUBLICATION--67
--PUBLISHER_SERVER-my_PUBLICATION-my_PUBLICATION--68


--here is the problem - it cannot find the jobs, the jobs are not even there anymore, one of those things
exec msdb.dbo.sp_delete_job @job_id=0x0F1564BAACD5464C988DE8957C25C411
exec msdb.dbo.sp_delete_job @job_id=0x6215C40F999CE248A30EE735E2C0E59D

--Msg 14262, Level 16, State 1, Procedure sp_verify_job_identifiers, Line 41 [Batch Start Line 52]
--The specified @job_id ('BA64150F-D5AC-4C46-988D-E8957C25C411') does not exist.


--Msg 14262, Level 16, State 1, Procedure sp_verify_job_identifiers, Line 41 [Batch Start Line 53]
--The specified @job_id ('0FC41562-9C99-48E2-A30E-E735E2C0E59D') does not exist.

exec msdb.dbo.sp_delete_job @job_name='PUBLISHER_SERVER-my_PUBLICATION-my_PUBLICATION'
PUBLISHER_SERVER-my_PUBLICATION-my_PUBLICATION--68

Erstellen Sie zu diesem Zeitpunkt die Publikation wie gewohnt neu

Setzen Sie dann den Schnappschuss zum Laufen

Warten Sie, bis der Snapshot erstellt ist

MAYBE YOU DONT NEED TO RUN THE SNAP- Versuchen Sie without, es zuerst auszuführen. Meistens funktioniert es. Außerdem können Sie smallder Publikation nur 1-2 Artikel hinzufügen , damit der Snap schnell ausgeführt wird

Wenn Sie den Snapshot jedoch ausführen, müssen Sie warten, bis er abgeschlossen ist, bevor Sie mit dem nächsten Schritt fortfahren können. drop the publication

Geben Sie hier die Bildbeschreibung ein

Danach generieren Sie die Skripte drop that publicationgemäß dem folgenden Bild: Geben Sie hier die Bildbeschreibung ein

Wenn Sie danach unsere obigen Originalskripte ausführen oder einen Blick auf den Replikationsmonitor werfen , sehen Sie hoffentlich nicht die fehlerhafte Veröffentlichung, sondern nur die guten, in meinem Fall nur eine:

Geben Sie hier die Bildbeschreibung ein


-1

Ich hatte das gleiche Problem mit meiner Vorproduktionsbox, dem Befehl

exec sp_cleanupdbreplication

scheinen an der Bereinigung gefälschter Abonnementeinträge gearbeitet zu haben ...

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.