Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Вопросы по репликации слиянием  [new]
DimmaN
Member

Откуда:
Сообщений: 71
Три вопроса

1. Не понимаю, каким образом работает механизм раздачи отрезков значений для identity поля в репликации:

В сгенерированном репликацией триггере на вставку в таблицу ttt написан код

	DBCC CHECKIDENT ('ttt', reseed, 2000) WITH NO_INFOMSGS


2000 - это для простоты написано мной, в триггере не так, конечно.

В таблице inserted триггера для автоинкрементного поля уже есть значение. Почему после выполнения вышеприведенного кода это поле при фиксации транзакции получает новое значение? При фиксации сервер рассчитывает автоикрементное поле заново?

2. Могу я сам спланировать диапазоны значений автоинкрементных полей? Скажем если в системе будет не больше 5 узлов, тогда разбить их так: increment = 10, а seed у каждой базы от 1 до 5. Я так изначально сделал, но стартовая синхронизация изменила таблицу и репликационный триггер стал сам раздавать диапазоны. Как заставить работать по-своему?

3. Можно ли (и как, если да) отказаться от начальной сихронизации таблиц снимком? Если ли какая-то галочка "Я уже синхронизировал вручную"? В книжке (Вьейра, про 2005 скл, правда) прочитал, что можно вручную синхронизировать, но не найду как.

MSSQL Server 2008 R2
29 окт 12, 22:10    [13393660]     Ответить | Цитировать Сообщить модератору
 Re: Вопросы по репликации слиянием  [new]
DimmaN
Member

Откуда:
Сообщений: 71
На второй вопрос нашел ответ. Похоже, надо из интерфейса мэнеджмент студии генерить скрипт и там уже в параметре @identityrangemanagementoption процедуры sp_addmergearticle ставить нужное значение.Ну или процедурой sp_changemergearticle менять уже существующие статьи.
30 окт 12, 08:47    [13394535]     Ответить | Цитировать Сообщить модератору
 Re: Вопросы по репликации слиянием  [new]
DimmaN
Member

Откуда:
Сообщений: 71
да, со вторым и третьим вопросами я разобрался, поторопился задать.

а вот с первым не пойму, что читать.
30 окт 12, 21:45    [13399742]     Ответить | Цитировать Сообщить модератору
 Re: Вопросы по репликации слиянием  [new]
SIMPLicity_
Member

Откуда: (((@)))
Сообщений: 8880
DimmaN
да, со вторым и третьим вопросами я разобрался, поторопился задать.

а вот с первым не пойму, что читать.

Про третий поясни где читать,- мне это уже не нужно, но в своё время волшебной галочки не нашёл (репликации в итоге писал самостоятельно)... Так что "свербит"....
Заранее спасибо....
30 окт 12, 21:58    [13399771]     Ответить | Цитировать Сообщить модератору
 Re: Вопросы по репликации слиянием  [new]
invm
Member

Откуда: Москва
Сообщений: 9845
SIMPLicity_
Про третий поясни где читать,- мне это уже не нужно, но в своё время волшебной галочки не нашёл (репликации в итоге писал самостоятельно)... Так что "свербит"....
Заранее спасибо....
Initializing a Merge Subscription Without a Snapshot
30 окт 12, 22:14    [13399817]     Ответить | Цитировать Сообщить модератору
 Re: Вопросы по репликации слиянием  [new]
invm
Member

Откуда: Москва
Сообщений: 9845
DimmaN
1. Не понимаю, каким образом работает механизм раздачи отрезков значений для identity поля в репликации

Replicating Identity Columns
30 окт 12, 23:16    [13400006]     Ответить | Цитировать Сообщить модератору
 Re: Вопросы по репликации слиянием  [new]
DimmaN
Member

Откуда:
Сообщений: 71
invm
DimmaN
1. Не понимаю, каким образом работает механизм раздачи отрезков значений для identity поля в репликации

Replicating Identity Columns


это я читал. я, видимо, плохо вопрос сформулировал.

я не понимаю почему работает триггер автоматической раздачи диапазона. вот репликация сгенерила мне триггер, в нем написан код
DBCC CHECKIDENT ('ttt', reseed, 2000) WITH NO_INFOMSGS


таблица ttt имеет текущее значение айдентити столбца, пусть 14. я вставляю в таблицу ttt новую строку. на момент исполнения кода триггера вставляемая строка в таблице inserted уже получила значение айденити столбца (15). почему после того как отрабатывает этот триггер и транзакция фиксируется строка получает новое значение айдентити поля (2001 к примеру)? при фиксации транзакции заново происходит пересчет айдентити столбца?
31 окт 12, 09:24    [13400520]     Ответить | Цитировать Сообщить модератору
 Re: Вопросы по репликации слиянием  [new]
DimmaN
Member

Откуда:
Сообщений: 71
SIMPLicity_
Про третий поясни где читать,- мне это уже не нужно, но в своё время волшебной галочки не нашёл (репликации в итоге писал самостоятельно)... Так что "свербит"....
Заранее спасибо....


если буквально, то из мэнеджмент студии вот так:

Clear the Initialize check box on the Initialize Subscriptions page of the New Subscription Wizard. Do this for each subscription that requires only replication objects and metadata to be copied.


отсюда.

How to: Initialize a Subscription Manually (SQL Server Management Studio)

ну и ссылку выше нужно прочитать, да.
31 окт 12, 09:28    [13400528]     Ответить | Цитировать Сообщить модератору
 Re: Вопросы по репликации слиянием  [new]
invm
Member

Откуда: Москва
Сообщений: 9845
DimmaN,

Текст триггера целиком покажите.
31 окт 12, 09:51    [13400587]     Ответить | Цитировать Сообщить модератору
 Re: Вопросы по репликации слиянием  [new]
DimmaN
Member

Откуда:
Сообщений: 71
invm, пожалуйста:

ALTER trigger [dbo].[MSmerge_ins_C565A70CE3414F91AB6C3B9C9C4CA61A] on [bbb].[dbo].[ttt] for insert   as 
    declare @is_mergeagent bit, @at_publisher bit, @retcode smallint 

    set rowcount 0
    set transaction isolation level read committed

        select @is_mergeagent = convert(bit, sessionproperty('replication_agent'))
        select @at_publisher = 0 
    if (select trigger_nestlevel()) = 1 and @is_mergeagent = 1
        return  
    if is_member('db_owner') = 1
    begin
        -- select the range values from the MSmerge_identity_range table
        -- this can be hardcoded if performance is a problem
        declare @range_begin numeric(38,0)
        declare @range_end numeric(38,0)
        declare @next_range_begin numeric(38,0)
        declare @next_range_end numeric(38,0)

        select @range_begin = range_begin,
               @range_end = range_end,
               @next_range_begin = next_range_begin,
               @next_range_end = next_range_end
            from dbo.MSmerge_identity_range where artid='C565A70C-E341-4F91-AB6C-3B9C9C4CA61A' and subid='E52F9C48-AC77-4EFB-B306-DC2E3F5F260D' and is_pub_range=0

        if @range_begin is not null and @range_end is not NULL and @next_range_begin is not null and @next_range_end is not NULL
        begin
            if IDENT_CURRENT('[dbo].[ttt]') = @range_end
            begin
                DBCC CHECKIDENT ('[dbo].[ttt]', RESEED, @next_range_begin) with no_infomsgs
            end
        end
    end 
    declare @article_rows_inserted int
    select @article_rows_inserted =  count(*) from inserted 
    if @article_rows_inserted = 0 
        return
    declare @tablenick int, @rowguid uniqueidentifier
    , @replnick binary(6), @lineage varbinary(311), @colv1 varbinary(1), @cv varbinary(1)
    , @ccols int, @newgen bigint, @version int, @curversion int
    , @oldmaxversion int, @child_newgen bigint, @child_oldmaxversion int, @child_metadatarows_updated int 
    , @logical_record_parent_rowguid uniqueidentifier 
    , @num_parent_rows int, @parent_row_inserted bit, @ts_rows_exist bit, @marker uniqueidentifier 
    declare @dt datetime
    declare @nickbin varbinary(8)
    declare @error int 
    set nocount on
    set @tablenick = 7505000    
    set @lineage = 0x0
    set @retcode = 0
    select @oldmaxversion= maxversion_at_cleanup from dbo.sysmergearticles where nickname = @tablenick
    select @dt = getdate()

    select @replnick = 0xac77e52f9c48 
    set @nickbin= @replnick + 0xFF

    select @newgen = NULL
        select top 1 @newgen = generation from [dbo].[MSmerge_genvw_C565A70CE3414F91AB6C3B9C9C4CA61A] with (rowlock, updlock, readpast) 
        where art_nick = 7505000     and genstatus = 0
    if @newgen is NULL
    begin
        insert into [dbo].[MSmerge_genvw_C565A70CE3414F91AB6C3B9C9C4CA61A] with (rowlock)
            (guidsrc, genstatus, art_nick, nicknames, coldate, changecount)
             values   (newid(), 0, @tablenick, @nickbin, @dt, @article_rows_inserted)
        select @error = @@error, @newgen = @@identity    
        if @error<>0 or @newgen is NULL
            goto FAILURE
    end
    set @lineage = { fn UPDATELINEAGE (0x0, @replnick, 1) }
            set @colv1 = NULL
    if (@@error <> 0)
    begin
        goto FAILURE
    end

    select @ts_rows_exist = 0 
        select @ts_rows_exist = 1 where exists (select ts.rowguid from inserted i, [dbo].[MSmerge_tsvw_C565A70CE3414F91AB6C3B9C9C4CA61A] ts with (rowlock) where ts.tablenick = @tablenick and ts.rowguid = i.rowguidcol)     
    if @ts_rows_exist = 1
    begin    
        select @version = max({fn GETMAXVERSION(lineage)}) from [dbo].[MSmerge_tsvw_C565A70CE3414F91AB6C3B9C9C4CA61A] where 
            tablenick = @tablenick and rowguid in (select rowguidcol from inserted) 

        if @version is not null
        begin
            -- reset lineage and colv to higher version...
            set @curversion = 0
            while (@curversion <= @version)
            begin
                set @lineage = { fn UPDATELINEAGE (@lineage, @replnick, @oldmaxversion+1) }
                set @curversion= { fn GETMAXVERSION(@lineage) }
            end

            if (@colv1 IS NOT NULL)
                set @colv1 = { fn UPDATECOLVBM(@colv1, @replnick, 0x01, 0x00, { fn GETMAXVERSION(@lineage) }) }    
                delete from [dbo].[MSmerge_tsvw_C565A70CE3414F91AB6C3B9C9C4CA61A] with (rowlock) where tablenick = @tablenick and rowguid in
                    (select rowguidcol from inserted) 
        end
    end 
    select @marker = newid()  
        insert into [dbo].[MSmerge_ctsv_C565A70CE3414F91AB6C3B9C9C4CA61A] with (rowlock) (tablenick, rowguid, lineage, colv1, generation, partchangegen, marker) 
        select @tablenick, rowguidcol, @lineage, @colv1, @newgen, (-@newgen), @marker
        from inserted i where not exists
        (select rowguid from [dbo].[MSmerge_ctsv_C565A70CE3414F91AB6C3B9C9C4CA61A] with (readcommitted, rowlock, readpast) where tablenick = @tablenick and rowguid = i.rowguidcol)  
    if @@error <> 0 
        goto FAILURE   

    return
FAILURE:
    if @@trancount > 0
        rollback tran
    raiserror (20041, 16, -1)
    return     
31 окт 12, 10:20    [13400711]     Ответить | Цитировать Сообщить модератору
 Re: Вопросы по репликации слиянием  [new]
invm
Member

Откуда: Москва
Сообщений: 9845
DimmaN,

Как и ожидалось, никаких чудес -- назначение нового диапазона происходит только после исчерпания текущего.
Так что вот тут:
DimmaN
таблица ttt имеет текущее значение айдентити столбца, пусть 14. я вставляю в таблицу ttt новую строку. на момент исполнения кода триггера вставляемая строка в таблице inserted уже получила значение айденити столбца (15). почему после того как отрабатывает этот триггер и транзакция фиксируется строка получает новое значение айдентити поля (2001 к примеру)? при фиксации транзакции заново происходит пересчет айдентити столбца?
Вы что-то путаете.
31 окт 12, 10:55    [13400860]     Ответить | Цитировать Сообщить модератору
 Re: Вопросы по репликации слиянием  [new]
DimmaN
Member

Откуда:
Сообщений: 71
invm, про назначение диапазона после исчерпания текущего - это понятно.

я сейчас попробовал - и дествительно не смог повторить ситуацию с переприсвоением нового значения айдентити, а которой писал.

видимо, я загнался и сделал не так, когда эксперементировал с рукописным триггером, присваивающем новое текущее значение айдентити. померещелось ночью, видимо.

спасибо, что помогли разобраться.
31 окт 12, 11:18    [13400999]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить