MS-SQL Server

Peer To Peer 복제 및 운영중 알고 있으면 좋은 내용

안보갑 2009. 6. 25. 22:53

Peer To Peer 복제에 대한 내용을 확인하다가 오류 발생에 대한 처리를 어떻게 하고

어떤 식으로 동작하는지에 대한 의문이 들어서 나름대로 테스트를 해보고 이전의

쿼리를 조금 바꾸어 좀더 쉽게 찾을 수 있도록 수정 하였습니다.

 

select (      select cast(count(*) as varchar(100)) + ':' + sys.fn_sqlvarbasetostr(min(xact_seqno))

                    from MSrepl_commands with(nolock)

                    where publisher_database_id = c.publisher_database_id and xact_seqno > a.MaxTranNo

             ) as '남은명령어수:처리해야할명령어'

,            case b.runstatus when 1 then '시작' when 2 then '성공' when 3 then '진행중' when 4 then '유휴상태' when 5 then '다시시도' when 6 then '실패' end as 'Status'

,            b.error_id, c.publisher_database_id, c.publication, d.srvname as '게시서버', c.publisher_db, e.srvname as '구독서버', c.subscriber_db, c.name

from                (      select agent_id, max(xact_seqno) as 'MaxTranNo', max(time) as 'Lasted'

                                 from MSdistribution_history with(nolock)

                                 where xact_seqno > 0x0

                                 group by agent_id) a

       inner join   MSdistribution_history b with(nolock)   on     a.agent_id = b.agent_id and a.Lasted = b.time

       inner join   MSdistribution_agents c with(nolock)    on     a.agent_id = c.id

       inner join   master.dbo.sysservers d with(nolock)    on     c.publisher_id = d.srvid

       inner join   master.dbo.sysservers e with(nolock)    on     c.subscriber_id = e.srvid

 

위의 쿼리를 실행하면 제일 첫 번째 컬럼의 왼쪽 부분은 복제 걸린 놈이 처리 하지 못하고 남겨 놓은 명령어가 얼마나 되는지 보여 줍니다.

그리고 이어서 최근 처리한 명령어 다음으로 실행해야 할 명령어 xact_seqno를 붙여서 보여 줍니다.

xact_seqno는 문제가 발생한 복제에서 삭제해야 할 대상이 되는 명령어 셋입니다. (아래 로그를 통해서 확인한 값과 동일 합니다.)

해당 명령어 셋 하나당(하나의 트랜잭션) 여러 명령어가 존재하기 때문에 특정 명령어를 찾아서 지우기 위해서는

복제 모니터를 통해서 로그 정보 확인하면은 어떤 명령어를 지워야 하는지 알 수 있습니다.

 

if @@trancount > 0 rollback tran

(트랜잭션 시퀀스 번호: 0x000000860000036B001500000000, 명령 ID: 1)

위의 표에서 트랜잭션 시퀀스 번호가 xact_seqno이고 명령 ID command_id가 됩니다.

 

위와 같이 확인하면 해당 명령어 셋이 어떤 명령어들이 처리되고자 했는지 확인이 가능 합니다.

해당 정보는 아래와 같이 조회 합니다.

sp_browsereplcmds

       @xact_seqno_start = '0x0000170B00009C36002900000000' -- 시작xact_seqno

,      @xact_seqno_end = '0x0000170B00009C36002900000000'   -- 종로xact_seqno

,      @publisher_database_id = 94                          -- 게시데이터베이스ID

 

위에서 조회한 정보를 바탕으로 해당 내용을 삭제 하는 것이 맞는지 확인하고 삭제 해도 된다면 아래의 방법으로 삭제 합니다.

delete Msrepl_commands

where xact_seqno = 0x0000170B00009C4A002400000000    -- 지워야할명령어셋xact_seqno

and publisher_database_id = 94                       -- 지워야할게시데이터베이스ID

and command_id = 5                                   -- 명령어셋중지울명령어선택

 

위에서 삭제 처리할 때 command_id의 조건은 필요에 따라서 넣어도 되고 사용하지 않아도 됩니다.

하나의 트랜잭션에 묶인 여러 개의 쿼리의 트랜잭션을 보장하고자 한다면 command_id 조건을 주지 않고 지우면

해당 처리에 대한 전체 트랜잭션에 대한 데이터가 복제에서 스킵하게 됩니다.

그게 아니라 특정 명령어만 지우기 위해서는 command_id의 조건을 검색해서 넣으면 됩니다. (명령 ID)

 

[Peer To Peer 복제]

일반 트랜잭션 복제와 개념은 동일하지만 스냅샷을 통한 초기화 방법은 없습니다.

백업 복구를 통한 데이터 동기화를 시켜놓고 처리하던지 수동으로 동기화하고 데이터 싱크 맞춘 상태에서 사용 가능 합니다.

물리적으로 구성은 하나의 게시자에 의해서 전체의 토폴로지를 구성하지만 논리적으로는

모든 DB들이 게시자의 역할을 하는 구조 입니다.

 

그리고 이 복제도 기존 복제와 비슷하게 위의 명령어 지우는 방법으로 충돌에 대한 해결이 가능 합니다.

2005까지는 충돌 감지에 대한 기능 자체가 Peer To Peer 복제에서 존재하지 않기 때문에

구성상 충돌 가능 요소를 제거하는 설계가 필수 입니다.

단 충돌이 생기면 모든 DB에서 해당 충돌을 제거 해야 합니다.

3대의 장비가 연결이 되면 하나의 충돌이 발생하더라도 모든 장비에서 해당 명령어를 지우는 작업을 해야 합니다.