MS SQL Server'da dağınık bir çoğaltma nasıl düzeltilir


11

Bir veritabanını yedekten geri yükledim. Veritabanı, farklı bir sunucuya yayımlamak için çoğaltma kullanır. Veritabanı geri yüklemesinin çoğaltmayı bozacağını varsayarsak, çoğaltmayı silmeye ve yeniden oluşturmaya çalıştım (sıfırdan yeniden oluşturmak için bir komut dosyasına sahibiz). Tam olarak ne yaptığımdan emin değilim, ama şimdi tamamen dağınık durumda ve düzeltemiyorum.

İlk olarak, abonelikten kurtulmaya çalışıyorum (yayıncı sunucusunda):

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

Bu işe yarıyor gibi görünüyor. SELECT * FROM syssubscriptionssonuç göstermez. Abone sunucusuna bakarken, SSMS> {SubscriberServer}> Çoğaltma> Yerel Abonelikler - abonelik orada değildir.

Sonra yayını silmeye çalışıyorum. SSMS> {Sunucu}> Çoğaltma> Yerel Yayınlar> {YayınAdı}> Sil. Bu, aşağıdaki hata iletisini verir:

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

Tamam, bu yüzden makaleleri bırakmaya çalışıyorum:

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

ve şu hatayı alın:

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.

Tamam, bu yüzden Anlık Görüntü Aracısı'nı başlatmayı deneyin ve bu iç SQL istisnasını alıyorum:

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

Bu yüzden makaleyi silmek için alternatif bir yöntem denedim DELETE FROM sysarticles. Bu işe yaramış gibi görünüyor - şimdi makalelerden kurtuldum, ancak yine de aynı yayını alıyorum.

Ayrıca SQL Server'ı yeniden başlattım - yardımcı olmadı.

Burada neler olduğunu bilmiyorum ve nasıl düzeltebilirim?

BTW, veritabanının anahtarları için tehlikeli olabilecek kadar iyi bilen bir yazılım geliştiricisi verdiğinizde olan budur. Neyse ki, bu bir üretim ortamı değil ...

Yanıtlar:


10

TLDR:

Çoğaltmanın devre dışı bırakılması ve yeniden etkinleştirilmesinin muhtemelen sorunu çözdüğü anlaşılıyor:

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

Sanırım bu kapatıp tekrar açmanın eşdeğeridir ...

Daha uzun versiyon:

Bir iş arkadaşı bunu düzeltmeye çalıştı. Birkaç şey denedi ama çok uzağa gitmedi. Vazgeçmeden önce yaptığı tek değişiklik, çoğaltmayı devre dışı bırakmaktı.

Sonra Cody'nin önerisini denedim . Sp_dropsubscription komutu hiçbir abonelik olmadığından şikayet etti. Bu yüzden sp_droppublication komutunu denedim. Bu, çoğaltmanın veritabanında etkinleştirilmediğinden şikayet etti. Bu yüzden etkinleştirdim ve komutu yeniden çalıştırdım. Bu kez yayının mevcut olmadığından şikayet etti. SSMS'deki Yerel Yayınlar düğümünü yeniledim ve yeterince gitmişti. Ben çoğaltma kurulum komut dosyası koştu, yeni bir anlık görüntü oluşturdu ve her şey şimdi düzgün çalışıyor. Sevinç!

100% Çoğaltma devre dışı bırakma ve etkinleştirme sorunu gerçekten düzeltti ne olduğundan emin değilim, ama çoğaltma dağınık eğer kesinlikle denemeye değer.


Yeni başlayanlar için harika bir okuma. Veritabanını geri yüklemeden önce çoğaltmayı devre dışı bırakmanız gerektiğini söylemek güvenli mi?
Keith Rivera

Kesinlikle bir dahaki sefere deneyeceğim - okuduktan sonra çoğaltma tamamen uçurulmuş ve yeniden (başlangıçta olacağını düşündüm gibi) yeniden olması gerekir. Çoğaltmayı devre dışı bırakın, veritabanını geri yükleyin, çoğaltmayı etkinleştirin, yeni bir anlık görüntü itin. Makaleler hala geçerli olduğu sürece, gitmek iyi olmalıdır. Yine de değer bir deneyin ...
TallGuy

Toplam çoğaltma acemi burada, ama TLDR takip; talimatları yayınlarımın SSMS'den kaybolmasına neden oldu. Sorgulanıyor MSPublicationsiçinde distributionveritabanı yayın gerçekten gitmiş olduğunu ortaya koymaktadır. Bu bekleniyor mu?
pimbrouwers

5

Çoğaltma ile ilgili bir karışıklık yaşadım ve bununla çözdüm

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

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

Bu ve:

exec sp_cleanupdbreplication

Temizlik yaparken berbat kopyaları kurtarırlar.


1
Postunuzun beni Test ortamımı yeniden kurmamdan kurtardığına inanıyorum. Yukarıdaki komutun ne olduğundan emin değilim, ancak artık çoğaltma için yayınlanmalarıyla ilgili Hata olmadan Dizinleri Silebilirim. Çok teşekkürler.
MHSQLDBA

2

Veritabanını geri yüklemek çoğaltmayı keser, bu normaldir. Ayrıca tüm abonelikleri kaldıramadığınız için (veya en azından SQL öyle olduğunu düşünüyor) diğer hata mesajlarının çoğu sadece takip edilir.

Yayıncınızın (kaynak veritabanı) ve en az bir abonenizin (hedef veritabanı) olduğunu ve bunların iki farklı sunucu olduğunu biliyorsunuz. Sadece bu sunucularda ya da başka bir sunucuda ve muhtemelen dağıtım adlı bir veritabanında bulunan bir distribütör olduğunu belirtmek istiyorum. Bazen orada bazı yararlı bilgiler vardır ve bazen işler düşer, çünkü üçü arasındaki bilgiler eşleşmez.

Her neyse, aboneleri kontrol ettiğinizde , listelenen başka bir şey olmadığından emin olmak için yayıncı sunucusundaki o bölümü de kontrol ettiniz mi ? Herhangi birini bulursanız manuel olarak kaldırmayı deneyebilirsiniz:

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

Ancak bunların hepsinin gerçekten kaybolduğunu varsayarsak, bunu yayıncı veritabanında deneyin:

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

Nasıl gittiğini bize bildirin. Bu duruma girdiğinde çoğaltma beni ve diğer iyi DBA'ları geliştirici olmakla ilgisi olmayan şeyleri karıştırıyor :-)


Önerin için teşekkürler. Sp_dropsubscription komutu hiçbir abonelik olmadığından şikayet etti. Sp_droppublication komutu, çoğaltmanın etkinleştirilmediğinden şikayet etti - bu da beni çözüm gibi görünen şeye götürdü.
TallGuy

Benim için, sp_removedbreplication komutu çoğaltmayı zorla kaldırmak zorunda kaldığım zamanlarda çalıştı.
SQLPRODDBA

0

Fantom çoğaltma eserlerinden kurtulmanın tek yolu abonelikleri, makaleleri, yayınları bırakmaktır. Hala hayali abonelikler varsa, hayali abone de dahil olmak üzere yayını yeniden oluşturun. Bu özellikle eski sürümlerle çalışıyor gibi görünüyor.


0

normalde yayınladığım bir yayın olduğunda bunu yapıyorum.

biraz çirkin ama farklı ortamlarda birçok kez benim için çalıştı. ona ne sebep oluyor? o ama siz bile temizlemek gerekir bunun için en iyi bazen anlamaya bazen zordur sıfırdan başlamaktır arızalı akım yayından.allresiduals

sadece içeriğe koymak için:

Çoğaltma monitöründen gördüğüm şey bu:

resim açıklamasını buraya girin

ve T-SQL kullanarak kendi çoğaltma monitörümü kullandığımda :

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 

aşağıdaki son kutuda 2 satır görebilirsiniz - bunlardan biri orada olmamalıdır:

resim açıklamasını buraya girin

Bu komut dosyasını kullandığımda aynı:

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

resim açıklamasını buraya girin

İlk olarak yukarıdaki diğer cevaplarda gösterilenleri yaparsınız , eğer işe yararsa , bu iyi, bazen işe yarıyor, problem çözüldü.

bu daha az olacaktır:

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

Şimdi bu yayından tamamen kurtulmak için buscriber'a, ardından yayıncıya ve daha sonra aşağıdaki komut dosyasına göre dağıtarak bağlantı kuracağız:

-- 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

bu noktada yayını normalde yaptığınız gibi yeniden oluşturun

sonra anlık görüntüyü çalıştır

anlık görüntünün oluşturulmasını bitirmesini bekleyin

MAYBE YOU DONT NEED TO RUN THE SNAP- withoutönce çalıştırmayı deneyin , çoğu zaman işe yarar, ayrıca smallyayına sadece 1-2 makale ekleyebilir , böylece ek hızlı bir şekilde çalışır

ancak anlık görüntüyü çalıştırırsanız, bir sonraki adıma geçmeden önce bitmesini beklemeniz gerekir - drop the publication

resim açıklamasını buraya girin

bundan sonra drop that publicationaşağıdaki resme göre komut dosyaları oluşturursunuz : resim açıklamasını buraya girin

bundan sonra umarım, yukarıdaki orijinal scriptlerimizi çalıştırdığınızda veya çoğaltma monitörüne baktığınızda, hatalı yayını, sadece iyi olanları görmeyeceğim, benim durumumda sadece bir tane:

resim açıklamasını buraya girin


-1

Üretim öncesi kutumda da aynı problem vardı,

exec sp_cleanupdbreplication

sahte abonelik girişlerini temizlemek için çalışıyor gibi görünüyor ...

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.