A disztributor halála :-) (hu)

Ma is kijutott a jóból, de hogy teljes egyen a nap egy finom kis replikációs hibába is belefutottam:

Replication-Replication Distribution Subsystem: agent %s failed. Procedure or function sp_MSupd_dboYourObjectNameComesHere has too many arguments specified.

Jujj de jó :-) a replikáció beépített update kódja megadta magát. Sem a publikáción sem a táblán nem történt változás, egyszer csak megadta magát. Időm nem volt sok keresgélni az okokat, így inkább újrageneráltam a replikációs eljárásokat az alábbiak szerint:

  • sp_scriptpublicationcustomprocs eljárással kigenerálam az összes kódot
  • kivettem a hibás kódhoz tartozó részt és lefutattam a subscriber-en.

Íme egy példa: futtassuk le az alábbi kódot azon az adatbázison, ami ki van publikálva.

EXEC sp_scriptpublicationcustomprocs 'publication_name'

Értelemszerűen a publication_name helyére a publikációnk nevét kell írni. A kigenerált kódból keressük ki az alábbi részeket:

  • a DROP PROCEDURE részt, ami az sp_MSupd_XXX eljárásra vonatkozik,
  • ahol a dbo.MSreplication_objects táblából kitörli a replikációs eljárást,
  • a CREATE PROCEDURE részt,
  • végül, ahol újra berakja a dbo.MSreplication_objects táblába az eljárást.

Az alábbi példa szerinti kódnak kellene meglenni:

if object_id(N'[sp_MSupd_dboMyTableObject]', 'P') > 0       
drop proc [sp_MSupd_dboMyTableObject]
go
if object_id(N'dbo.MSreplication_objects') is not null 
delete from dbo.MSreplication_objects 
where object_name = N'sp_MSupd_dboMyTableObject'
go
create procedure [sp_MSupd_dboMyTableObject] 
 @c1 uniqueidentifier = null,@c2 uniqueidentifier = null,@c3 uniqueidentifier = null,
 @pkc1 uniqueidentifier
,@bitmap binary(2)
as
begin
if ( substring(@bitmap,1,1) & 1 = 1 )
begin
update [dbo].[MyTableObject] set 
 [col1] = case substring(@bitmap,1,1) & 1 when 1 then @c1 else [col1] end
,[col2] = case substring(@bitmap,1,1) & 2 when 2 then @c2 else [col2] end
,[colN] = case substring(@bitmap,1,1) & 4 when 4 then @c3 else [colN] end
where [col1] = @pkc1
if @@rowcount = 0
    if @@microsoftversion>0x07320000
        exec sp_MSreplraiserror 20598
end
else
begin
update [dbo].[MyTableObject] set 
 [col2] = case substring(@bitmap,1,1) & 2 when 2 then @c2 else [col2] end
,[colN] = case substring(@bitmap,1,1) & 4 when 4 then @c3 else [colN] end
where [col1] = @pkc1
if @@rowcount = 0
    if @@microsoftversion>0x07320000
        exec sp_MSreplraiserror 20598
end
end
go
if columnproperty
(object_id(N'dbo.MSreplication_objects'), N'article', 'AllowsNull') is not null 
exec ('insert dbo.MSreplication_objects 
(object_name, publisher, publisher_db, publication, article, object_type) values 
( + N''sp_MSupd_dboMyTableObject'' , 
    N''publisherservername'' , 
    N''published_databasename'' , 
    N''publication_name'' , 
    N''MyTableObject'' ,''P'')')
go

 

Ha jól csináltunk mindent, a replikáció helyreáll, anélkül, hogy újra kellene inicializálni vagy publikálni. Fontos megjegyezni, hogy ez csak az update eljárást fogja frissíteni, illetve csak akkor megoldás ez, ha Error: 14151, Severity: 18, State: 1. hibaüzenettel együtt jár és az SQL Server által generált Statement Delivery kóddal dolgozunk. Ha saját kódot használunk, érdemes megnézni, hogy változott e a publikált tábla definiciója és/vagy az általunk írt kód minden oszlopra rendesen meg van írva.

Add comment