Cách sửa lỗi sao chép sai trên MS SQL Server


11

Tôi đã khôi phục cơ sở dữ liệu từ bản sao lưu. Cơ sở dữ liệu sử dụng bản sao để xuất bản lên một máy chủ khác. Giả sử khôi phục cơ sở dữ liệu sẽ phá vỡ bản sao, tôi đã cố gắng xóa bản sao và tạo lại nó (chúng tôi có một kịch bản để tạo lại từ đầu). Tôi không chắc chắn chính xác những gì tôi đã làm, nhưng bây giờ nó đang ở trong tình trạng hoàn toàn sai lầm và tôi không thể sửa nó.

Đầu tiên, tôi cố gắng thoát khỏi đăng ký (trên máy chủ của nhà xuất bản):

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

Điều này dường như làm việc. SELECT * FROM syssubscriptionscho thấy không có kết quả. Tìm kiếm trên máy chủ thuê bao, SSMS> {SubscackerServer}> Sao chép> Đăng ký cục bộ - đăng ký không có ở đó.

Vì vậy, sau đó tôi cố gắng để xóa các ấn phẩm. SSMS> {Máy chủ}> Sao chép> Ấn phẩm cục bộ> {PublicationName}> Xóa. Điều này đưa ra thông báo lỗi sau:

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, vì vậy tôi cố gắng bỏ các bài viết:

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

và nhận được lỗi này:

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, vì vậy tôi thử khởi động Snapshot Agent và tôi nhận được ngoại lệ SQL nội bộ này:

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

Vì vậy, tôi đã thử một phương pháp khác để xóa bài viết DELETE FROM sysarticles,. Điều này dường như đã hoạt động - Bây giờ tôi đã thoát khỏi các bài viết, nhưng tôi vẫn nhận được cùng một điều 'Không thể bỏ ấn phẩm vì ít nhất một đăng ký tồn tại cho ấn phẩm này' khi tôi cố gắng xóa ấn phẩm.

Tôi cũng đã khởi động lại SQL Server - không giúp được gì.

Tôi không biết chuyện gì đang xảy ra ở đây và làm cách nào để khắc phục nó?

BTW đây là những gì xảy ra khi bạn cung cấp cho một nhà phát triển phần mềm biết đủ nguy hiểm cho các khóa của cơ sở dữ liệu. May mắn thay, đây không phải là môi trường sản xuất ...

Câu trả lời:


10

TLDR:

Có vẻ như việc vô hiệu hóa và kích hoạt lại sao chép có thể đã khắc phục vấn đề:

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

Tôi đoán điều này tương đương với việc tắt nó đi và sau đó bật lại ...

Phiên bản dài hơn:

Một đồng nghiệp đã cố gắng sửa nó. Anh ấy đã thử một vài thứ nhưng không đi được xa. Một thay đổi anh ấy đã thực hiện trước khi từ bỏ là vô hiệu hóa bản sao.

Sau đó tôi đã thử đề nghị của Cody . Lệnh sp_dropsubcrip đã phàn nàn rằng không có đăng ký nào tồn tại. Vì vậy, tôi đã thử lệnh sp_droppublication. Điều này phàn nàn rằng sao chép không được kích hoạt trên cơ sở dữ liệu. Vì vậy, tôi kích hoạt nó và chạy lại lệnh. Lần này nó phàn nàn rằng ấn phẩm không tồn tại. Tôi đã làm mới nút Local Publications trong SSMS và chắc chắn nó đã biến mất. Tôi đã chạy tập lệnh thiết lập sao chép, tạo một ảnh chụp nhanh mới và mọi thứ hiện đang hoạt động bình thường. Vui sướng!

Tôi không chắc chắn 100% rằng việc vô hiệu hóa và kích hoạt sao chép là điều thực sự đã khắc phục vấn đề, nhưng nó chắc chắn đáng để thử nếu bản sao bị rối.


Tuyệt vời đọc cho người mới. Có an toàn không khi nói rằng bạn nên vô hiệu hóa sao chép trước khi khôi phục cơ sở dữ liệu?
Keith Rivera

Tôi chắc chắn sẽ thử điều đó vào lần tới - từ những gì tôi đã đọc bản sao không cần phải hoàn toàn bị thổi bay và tái tạo (như ban đầu tôi nghĩ nó sẽ như vậy). Vô hiệu hóa sao chép, khôi phục cơ sở dữ liệu, cho phép sao chép, đẩy một ảnh chụp nhanh mới. Miễn là các bài viết vẫn còn hiệu lực, nó sẽ là tốt để đi. Dù sao cũng đáng để thử ...
TallGuy

Tổng số người mới nhân rộng ở đây, nhưng theo TLDR; hướng dẫn đã dẫn đến sự biến mất của các ấn phẩm của tôi từ SSMS. Truy vấn MSPublicationstrong distributioncơ sở dữ liệu cho thấy rằng ấn phẩm thực sự đã biến mất. Đây có phải là mong đợi?
pimbrouwers

5

Tôi đã có một mớ hỗn độn với sao chép và giải quyết nó với điều này

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

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

Đó và:

exec sp_cleanupdbreplication

Là những vị cứu tinh khi dọn dẹp các bản sao lộn xộn.


1
Tôi tin rằng Bài đăng của bạn vừa cứu tôi khỏi việc thiết lập lại môi trường Kiểm tra của tôi. Không chắc lệnh nào ở trên đã làm điều đó, nhưng bây giờ tôi có thể Xóa Chỉ mục mà không có Lỗi về chúng được xuất bản để sao chép. Cảm ơn bạn nhiều.
MHSQLDBA

2

Khôi phục cơ sở dữ liệu sẽ phá vỡ bản sao, vì vậy đó là bình thường. Ngoài ra, hầu hết các thông báo lỗi khác chỉ là theo dõi vì bạn chưa thể xóa tất cả các đăng ký (hoặc ít nhất là SQL nghĩ vậy).

Bạn biết bạn có nhà xuất bản của mình (cơ sở dữ liệu nguồn) và ít nhất một người đăng ký (cơ sở dữ liệu đích) và đây là hai máy chủ khác nhau. Tôi chỉ muốn đề cập rằng còn có một nhà phân phối trên một trong hai máy chủ này hoặc máy chủ khác, và có khả năng trong một cơ sở dữ liệu có tên là phân phối. Đôi khi nó có một số thông tin hữu ích trong đó và đôi khi mọi thứ rơi xuống vì thông tin giữa ba không khớp.

Dù sao, khi bạn kiểm tra người đăng ký, bạn cũng đã kiểm tra phần đó trên máy chủ của nhà xuất bản để đảm bảo không có gì khác được liệt kê? Nếu bạn tìm thấy bất kỳ bạn có thể cố gắng loại bỏ nó bằng tay:

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

Nhưng giả sử họ thực sự đã biến mất, hãy thử điều này trên cơ sở dữ liệu của nhà xuất bản:

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

Hãy cho chúng tôi biết làm thế nào nó đi. Bản sao khi nó vào trạng thái này làm tôi bối rối và các DBA giỏi khác không liên quan gì đến việc trở thành một nhà phát triển cả :-)


Cám ơn vì sự gợi ý. Lệnh sp_dropsubcrip đã phàn nàn rằng không có đăng ký nào tồn tại. Lệnh sp_droppublication phàn nàn rằng sao chép không được kích hoạt - điều này dẫn tôi đến những gì dường như là giải pháp.
TallGuy

Đối với tôi, lệnh sp_remondenameplication hoạt động trong hầu hết thời gian bất cứ khi nào tôi phải loại bỏ mạnh mẽ bản sao.
SQLPRODDBA

0

Cách duy nhất tôi có thể thoát khỏi các tạo tác sao chép ảo là bỏ đăng ký, bài báo, ấn phẩm. Nếu vẫn còn đăng ký ảo, sau đó tạo lại ấn phẩm bao gồm cả thuê bao ảo. Điều này dường như làm việc với các phiên bản cũ đặc biệt.


0

đây là những gì tôi thường làm khi tôi có một ấn phẩm bị rối tung.

nó là một chút xấu xí nhưng nó đã làm việc cho tôi nhiều lần trên các môi trường khác nhau. Điều gì gây ra nó? đó là đôi khi rất khó để con nó ra, đôi khi tốt nhất là bắt đầu từ đầu, nhưng ngay cả đối với những gì bạn cần để làm sáng tỏ allcác residualstừ các ấn phẩm hiện nay đó là bị lỗi.

chỉ để đặt nó vào bối cảnh:

Đây là những gì tôi thấy từ màn hình nhân rộng:

nhập mô tả hình ảnh ở đây

và khi tôi sử dụng màn hình sao chép của riêng mình bằng T-SQL :

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 

bạn có thể thấy 2 dòng trên hộp cuối cùng bên dưới - và một dòng không nên ở đó:

nhập mô tả hình ảnh ở đây

tương tự khi tôi sử dụng tập lệnh này:

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

nhập mô tả hình ảnh ở đây

Trước tiên, bạn làm những gì được hiển thị trong các câu trả lời khác ở trên, nếu điều đó hoạt động tốt, đôi khi nó hoạt động, vấn đề được giải quyết.

đó sẽ là ít hơn nó:

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

Bây giờ để loại bỏ hoàn toàn ấn phẩm này, chúng tôi sẽ bắt đầu bằng cách kết nối với người đăng ký, sau đó là nhà xuất bản và sau đó là nhà phân phối theo kịch bản dưới đây:

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

tại thời điểm này tạo lại ấn phẩm như bạn thường làm

sau đó đặt ảnh chụp để chạy

chờ cho nó hoàn thành việc tạo ảnh chụp nhanh

MAYBE YOU DONT NEED TO RUN THE SNAP- hãy thử withoutchạy nó trước, hầu hết thời gian nó hoạt động, bạn cũng có thể thêm chỉ 1-2 smallbài viết vào ấn phẩm để snap nhanh chóng chạy

nhưng nếu bạn chạy ảnh chụp nhanh thì bạn cần đợi cho đến khi nó kết thúc trước khi bạn có thể chuyển sang bước tiếp theo - drop the publication

nhập mô tả hình ảnh ở đây

sau đó bạn tạo các tập lệnh drop that publicationtheo hình dưới đây: nhập mô tả hình ảnh ở đây

sau đó, hy vọng, khi bạn chạy các tập lệnh gốc của chúng tôi ở trên hoặc nhìn vào màn hình sao chép, bạn sẽ không thấy ấn phẩm bị lỗi, chỉ có những tập tốt, trong trường hợp của tôi chỉ là một:

nhập mô tả hình ảnh ở đây


-1

Tôi đã có cùng một vấn đề trên hộp tiền sản xuất của tôi, lệnh

exec sp_cleanupdbreplication

dường như đã làm việc để dọn dẹp các mục đăng ký không có thật ...

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.