SQL Server 배포 에이전트 SubscriptionStreams 매개 변수를 구성하고 문제를 해결하는 방법

원래 제품 버전: SQL Server(지원되는 모든 버전)
원래 KB 번호: 953199

이 문서에서는 매개 변수, 이 매개 변수 SubscriptionStreams를 사용하는 경우 모범 사례 및 관련 문제 해결에 대한 자세한 정보를 제공합니다.

소개

매개 변수 SubscriptionStreams 를 사용하여 연결 수를 제어할 수 있습니다. Microsoft SQL Server 트랜잭션 복제에서 매개 변수를 사용하여 배포 에이전트 구독자에 병렬로 변경 내용 일괄 처리를 적용하는 데 사용하는 여러 연결을 사용하도록 설정할 수 있습니다. 이 작업은 복제 처리량을 크게 향상시킵니다. 동시에 배포 에이전트 배포 에이전트 단일 연결을 사용하여 변경 내용을 적용할 때와 동일한 트랜잭션 특성을 계속 유지할 수 있습니다. 연결 중 하나가 실행되거나 커밋되지 않으면 모든 연결이 현재 일괄 처리를 중단하고 에이전트는 단일 스트림을 사용하여 실패한 일괄 처리를 다시 시도합니다. 이 재시도 단계가 완료되기 전에 구독자에 임시 트랜잭션 불일치가 있을 수 있습니다. 실패한 일괄 처리가 성공적으로 커밋되면 구독자는 트랜잭션 일관성 상태로 돌아갑니다.

매개 변수 SubscriptionStreams에 대해 2 이상의 값을 지정하면 구독자에서 트랜잭션이 수신되는 순서가 게시자에서 수행한 순서와 다를 수 있습니다. 이 동작으로 인해 동기화 중에 제약 조건 위반이 NOT FOR REPLICATION 발생하는 경우 이 옵션을 사용하여 동기화 중에 제약 조건 적용을 사용하지 않도록 설정해야 합니다. 자세한 내용은 동기화에서 트리거 및 제약 조건의 제어 동작을 참조하세요.

SubscriptionStreams를 사용하도록 설정하기 전에 고려해야 할 요소

SubscriptionStreams 주로 배포자에서 구독자까지의 대기 시간을 처리하므로 로 전환 SubscriptionStreams하기 전에 배포자에서 구독자까지 대기 시간이 실제로 실행되고 있는지 확인합니다. 복제 모니터에서 추적기 토큰을 사용하거나 SQLServer:Replication Dist와 같은 카운터를 성능 모니터 수 있습니다.>Dist:Delivery Latency - 대기 시간 수준을 파악합니다.

배포자에서 구독자로의 대기 시간은 다음과 같은 여러 가지 이유로 인해 발생할 수 있지만 이에 국한되지는 않습니다.

  • 배포자 또는 구독자에서 차단
  • 느린 디스크 드라이브, 느린 네트워크 대역폭 및 부실 통계와 같은 배포자 또는 구독자의 병목 현상
  • 게시자에서 들어오는 대량 트랜잭션
  • 게시자에서 들어오는 트랜잭션의 비율이 너무 높습니다.
  • 구독된 데이터베이스의 트리거 또는 불필요한 인덱스

DBA(데이터베이스 관리자)는 전화를 걸어 도움을 줄지 여부를 SubscriptionStreams 테스트해야 합니다. 예를 들어 구독자에서 차단되는 경우 동시 연결 수를 늘리면 도움이 되지 않지만 상황이 악화될 수 있습니다. Publisher에서 들어오는 트랜잭션 속도가 너무 높고 배포 에이전트 단일 스레드가 들어오는 로드에 대처할 수 없다고 느끼는 경우 매개 변수 SubscriptionStreams 값을 =2로 늘리는 것이 >좋습니다. 또한 느린 네트워크 및 느린 디스크 상황에서도 도움이 될 수 있습니다. 이상적으로 이 매개 변수의 최대값은 64이지만 권장 값(또는 시작하기에 좋은 값)은 대상(구독자)의 실제 프로세서 수와 같습니다.

SubscriptionStreams 매개 변수를 구성하는 방법

SubscriptionStreams는 복제 모니터의 배포 에이전트 프로필에 표시되지 않는 매개 변수 중 하나입니다. sp_addsubscription(Transact-SQL)을 사용하여 @subscriptionstreams 이 에이전트 매개 변수의 값을 지정하거나 다음 절차를 사용하여 배포 에이전트 작업 명령 섹션에 이 매개 변수를 추가할 수 있습니다.

  1. 복제 모니터를 열고 내 게시자를 확장하고 왼쪽 창 창에서 게시를 선택합니다. 오른쪽 창의 모든 구독 섹션 아래에 이 게시에 대한 모든 구독자 목록이 표시됩니다.

  2. 매개 변수 SubscriptionStreams 를 사용하도록 설정할 구독자를 마우스 오른쪽 단추로 클릭하고 세부 정보 보기를 선택합니다. 배포 에이전트 세션 세부 정보가 포함된 새 창이 나타납니다.

  3. 이 새 창의 위쪽 메뉴 모음에서 작업을 선택하고 배포 에이전트 작업 속성을 선택합니다. 그러면 배포 에이전트 대한 작업 속성 창이 열립니다.

  4. 왼쪽 창 창에서 단계를 선택한 다음 오른쪽 창 창에서 에이전트 실행을 선택한 다음 편집을 선택합니다. 새 창이 나타납니다.

  5. 명령 섹션의 끝(맨 오른쪽)으로 스크롤하여 이 매개 변수 -SubscriptionStreams 6을 추가합니다.

  6. 설정을 저장하고 배포 에이전트 작업을 다시 시작합니다. 변경 내용을 구현하려면 배포 에이전트 다시 시작해야 합니다.

참고

위의 예제 SubscriptionStreams 에서 은 6으로 설정됩니다. 즉, 구독자에서 배포 에이전트 대한 6개의 병렬 연결을 찾고 있습니다. 환경 및 테스트에 따라 이 숫자를 설정할 수 있습니다.

스트림 수 확인

매개 변수 SubscriptionStreams를 사용하여 성능이 향상될 수 있습니다. 개선 사항이 있는 경우 개선은 명목상일 수 있습니다. 를 사용하여 SubscriptionStreams시장에서 각 디스크 하위 시스템이 어떤 종류의 성능 향상을 제공할지 결정하기가 어렵습니다. 따라서 프로덕션 환경을 시뮬레이션하는 테스트 환경을 준비하는 것이 좋습니다. 다양한 구성 값 및 를 사용하지 SubscriptionStreams않는 시나리오를 사용하여 사용하는 SubscriptionStreams 시나리오를 테스트할 수 있습니다.

게시 및 구독에 대해 부하 테스트를 수행하여 를 사용하여 SubscriptionStreams얻을 수 있는 성능 향상을 확인하는 것이 좋습니다. 디스크 하위 시스템의 예상 처리량을 이해하려면 성능 기준 테스트를 수행해야 합니다. 각 테스트를 수행하기 전에 많은 변경 내용을 적용하여 게시자에서 부하를 만듭니다. 부하를 만들 때 배포 에이전트 실행되지 않는지 확인합니다. 복제에 충분한 대기 시간이 있는 경우 배포 에이전트 실행하여 다음 구성에 대한 성능을 테스트합니다.

  • 매개 변수 SubscriptionStreams를 사용하지 마세요.
  • 값을 서버의 SubscriptionStreams 프로세서 수와 같도록 설정합니다. 예를 들어 서버에 8개의 프로세서가 있는 경우 값을 SubscriptionStreams 8로 설정합니다.
  • 에 대해 SubscriptionStreams 다른 값을 지정하여 최적의 구성을 얻습니다.

테스트를 수행할 때 배포 에이전트 다음 성능 카운터를 모니터링할 수 있습니다.

  • Dist: Delivered Cmds/sec
  • Dist: 배달 대기 시간

SubscriptionStreams 매개 변수를 지정한 후 배포 에이전트 동작

배포 에이전트 에서 SubscriptionStreams지정한 세션/연결 수를 유지 관리합니다. 배포 에이전트 이러한 세션을 사용하여 구독자에서 변경 내용을 적용합니다.

그러나 지정 SubscriptionStreams 하고 배포 에이전트 일정 시간 동안 실행한 후 배포 에이전트 하나의 세션만 사용하여 구독자에 변경 내용을 적용하도록 전환할 수 있습니다.

배포 에이전트 하나의 세션만 사용하도록 전환하는 이유

배포 에이전트 여러 가지 이유로 하나의 세션만 사용하도록 전환할 수 있습니다. 가장 일반적인 이유는 다음과 같습니다.

  • 배포 에이전트 변경 내용을 적용하면 세션 중 하나가 오류를 발생합니다.

    예를 들어 배포 에이전트 하나의 세션을 사용하여 자식 테이블에 행을 삽입합니다. 배포 에이전트 다른 세션을 사용하여 부모 테이블에 해당 행을 삽입하기 전에 이 문제가 발생하면 외래 키 제약 조건 위반으로 인해 오류 메시지가 발생합니다.

  • 차단 모니터 스레드가 차단을 검색합니다. 차단은 다음 이유 중 하나로 발생할 수 있습니다.

    • 배포 에이전트 다른 세션을 사용하여 구독자의 테이블에 대한 및 UPDATE 작업을 수행 INSERT 합니다. 테이블에 고유한 비클러스터형 인덱스가 포함된 경우 배포 에이전트 테이블의 인덱스 키를 업데이트할 때 두 세션 간의 차단이 발생할 수 있습니다.

    • 구독자에서 배포 에이전트 여러 테이블에서 DML(데이터 조작 언어) 문을 실행합니다. 이러한 테이블에 인덱싱된 뷰가 정의된 경우 인덱싱된 뷰가 공유 인덱스 키를 업데이트할 때 두 세션 간의 차단이 발생할 수 있습니다.

    • 배포 에이전트 한 세션을 사용하여 구독자의 테이블에 대해 DML 문을 실행합니다. DML 트리거는 이 테이블에 정의되어 있습니다. DML 트리거는 다른 세션을 사용하여 업데이트되는 다른 테이블에서 DML 문을 실행합니다. 이 경우 두 세션 간의 차단이 발생할 수 있습니다.

구독자 데이터베이스에서 다음 데이터베이스 개체를 사용하지 않는 것이 좋습니다.

  • 외래 키 제약 조건
  • 고유 비클러스터형 인덱스
  • 인덱싱된 뷰
  • 세션 간에 차단을 일으킬 수 있는 DML 트리거

배포 에이전트 하나의 세션만 사용하도록 전환했는지 여부를 확인하는 방법

이렇게 하려면 다음 방법 중 하나를 사용합니다.

참고

메서드 1을 사용하여 배포 에이전트 한 세션을 사용하도록 전환하지 않은 것을 확인할 수 있지만 메서드 2 또는 메서드 3을 사용하여 배포 에이전트 한 세션을 사용하도록 전환했는지 확인해야 합니다.

  • 방법 1

    구독 데이터베이스에 대한 연결 세션에 대한 DMV(동적 관리 뷰) sys.dm_exec_sessions 쿼리합니다. 연결 세션이 하나만 표시되는 경우 배포 에이전트 하나의 세션을 사용하여 전환되었을 수 있습니다. 둘 이상의 연결 세션이 표시되면 배포 에이전트 지정된 수의 세션을 계속 사용하고 있습니다.

    배포 에이전트 한 세션을 사용하도록 전환했는지 확인하려면 메서드 2 또는 메서드 3을 사용합니다.

  • 방법 2

    배포 데이터베이스에 msdistribution_history 테이블의 열을 comments 쿼리합니다. 쿼리 결과에 다음 항목이 포함된 경우 배포 에이전트 하나의 세션을 사용하도록 전환되었습니다.

    이 프로세스는 다중 스트리밍 모드에서 마지막 일괄 처리를 완료하지 못했고, 단일 연결 모드로 다시 설정되었으며 작업을 다시 시도합니다.

  • 방법 3

    배포 에이전트 출력 파일을 검사합니다. 출력 파일에 메서드 2와 동일한 오류 메시지가 포함된 경우 배포 에이전트 하나의 세션만 사용하도록 전환되었습니다.

    다음 출력 파일은 예제입니다.

    Date/Time 100 transaction(s) with 1181 command(s) were delivered. 
    Date/Time 100 transaction(s) with 2672 command(s) were delivered. 
    Date/Time Bucket 6 aborted the wait for Ready To Commit event, deadlock found between spid 117 and 114 
    Date/Time Bucket 1 aborted the wait for Ready To Commit event, deadlock found between spid 117 and 114 
    Date/Time Bucket 3 aborted the wait for Ready To Commit event, deadlock found between spid 117 and 114 
    Date/Time Bucket 0 aborted the wait for Ready To Commit event, deadlock found between spid 117 and 114 
    Date/Time Bucket 5 aborted the wait for Ready To Commit event, deadlock found between spid 117 and 114 
    Date/Time Bucket 2 aborted the wait for Ready To Commit event, deadlock found between spid 117 and 114 
    Date/Time Bucket 7 aborted the wait for Ready To Commit event, deadlock found between spid 117 and 114 
    Date/Time Bucket 4 aborted the wait for Ready To Commit event, due to thread shutdown event 
    ... 
    Date/Time Number of subscription streams has been reset from 8 to 1, state 4. 
    Date/Time Disconnecting from Subscriber 
    SQLInstance 
    Date/Time Disconnecting from Subscriber 
    SQLInstance 
    
    Date/Time Disconnecting from Subscriber 
    SQLInstance 
    
    Date/Time Disconnecting from Subscriber 
    SQLInstance 
    
    Date/Time Disconnecting from Subscriber 
    SQLInstance 
    
    Date/Time Disconnecting from Subscriber 
    SQLInstance 
    
    Date/Time Disconnecting from Subscriber 
    SQLInstance 
    
    Date/Time Disconnecting from Subscriber 
    SQLInstance 
    
    
    Date/Time Connecting to Subscriber 
    SQLInstance 
    
    Date/Time The process failed to complete last batch in multi-streaming mode, it has been reset to single connection mode and is retrying the operation. 
    Date/Time 21 transaction(s) with 390 command(s) were delivered.
    

하나의 세션만 사용하도록 전환하는 배포 에이전트 문제를 해결하는 방법

  1. 구독자에서 SQL Server Profiler 실행하여 차단된 프로세스 보고서 이벤트 및 Exception 이벤트를 캡처합니다. 이러한 이벤트는 배포 에이전트 변경 내용을 적용할 때 발생하는 차단 및 오류를 기록합니다.

    참고

    Exception 이벤트는 문제와 관련될 수 있는 모든 종류의 오류로 인해 발생할 수 있습니다. 예를 들어 외래 키 제약 조건 위반으로 인해 오류가 발생할 수 있습니다.

  2. 배포 에이전트 세션 하나만 사용하여 배포 에이전트 모니터링하도록 전환했는지 여부를 확인하는 방법 섹션의 메서드 중 하나를 사용합니다.

  3. 배포 에이전트 한 세션을 사용하도록 전환한 경우 추적을 중지합니다.

  4. 배포 에이전트 출력 파일 또는 테이블 msdistribution_historystart_time 에서 다음 항목의 타임스탬프를 가져옵니다.

    이 프로세스는 다중 스트리밍 모드에서 마지막 일괄 처리를 완료하지 못했고, 단일 연결 모드로 다시 설정되었으며 작업을 다시 시도합니다.

  5. 구독자에서 추적(.trc) 파일을 엽니다. 타임스탬프가 4단계에서 가져온 타임스탬프와 같거나 매우 가까운 차단 스크립트 또는 예외 이벤트를 찾습니다.

  6. 예외가 발견되면 예외의 세부 정보를 검사하여 원인을 확인합니다. 예를 들어 외래 키 제약 조건 위반으로 인해 예외가 발생할 수 있습니다. 그렇다면 구독자 데이터베이스에서 외래 키 제약 조건을 제거하는 것이 좋습니다.

    차단 스크립트가 발견되면 차단으로 인해 문제가 발생합니다. 다음은 샘플 차단 스크립트입니다.

    <blocked-process-report monitorLoop="41589"> 
        <blocked-process> 
            <process id="process3a6d438" taskpriority="0" logused="24592" waitresource="KEY: 6:72057594375700480 (0100e420fa5a)" waittime="9937" ownerId="568644832" transactionname="user_transaction" lasttranstarted="2008-05-05T04:55:04.430" XDES="0xa5619e370" lockMode="X" schedulerid="11" kpid="6104" status="suspended" spid="58" sbid="0" ecid="0" priority="0" transcount="2" lastbatchstarted="2008-05-05T04:55:04.553" lastbatchcompleted="2008-05-05T04:55:04.430" clientapp=<DistributionAgentProgram> hostname=<servername> hostpid="3980" loginname=<SQLAgentAcct>  isolationlevel="read committed (2)" xactid="568644832" currentdb="6" lockTimeout="4294967295" clientoption1="671090784" clientoption2="128056"> 
                <executionStack> 
                <frame line="5" stmtstart="642" stmtend="1600" sqlhandle="0x0300060057a14477a8c6dd00609a00000100000000000000"/> 
                </executionStack> 
                <inputbuf> 
                Proc [Database Id = 6 Object Id = 2000986455]
                </inputbuf> 
            </process> 
        </blocked-process> 
        <blocking-process> 
            <process status="sleeping" spid="68" sbid="0" ecid="0" priority="0" transcount="1" lastbatchstarted="2008-05-05T04:55:04.570" lastbatchcompleted="2008-05-05T04:55:05.103" clientapp=<DistributionAgentProgram> hostname=<servername> hostpid="3980" loginname=<SQLAgentAcct> isolationlevel="read committed (2)" xactid="568644998" currentdb="6" lockTimeout="4294967295" clientoption1="671090784" clientoption2="128056"> 
            <executionStack/> 
            <inputbuf> 
            Proc [Database Id = 6 Object Id = 1172459501]
            </inputbuf> 
            </process> 
        </blocking-process> 
    </blocked-process-report> 
    

    차단 스크립트는 차단된 세션 및 차단 세션을 기록합니다. 차단된 세션은 태그 <blocked-process>에서 시작됩니다. 차단 세션은 태그 <blocking-process>에서 시작됩니다.

  7. Object Id 차단된 세션 및 차단 세션에서 개체 Proc 의 를 찾습니다.

    샘플 차단 스크립트 Object Id 에서 차단된 세션의 Proc 의 는 입니다 2000986455. 차단 세션의 ProcObject Id 입니다1172459501.

  8. 구독 데이터베이스에서 7단계에서 가져온 개체 ID와 같도록 열을 object_id 지정하여 뷰 sys.objects를 쿼리합니다. 이렇게 하면 개체 이름을 확인할 수 있습니다.

    예를 들어 구독 데이터베이스의 컨텍스트에서 다음 쿼리를 실행합니다.

    USE <SubDBName> 
    GO 
    SELECT name FROM sys.objects 
    WHERE object_id = 1172459501 OR object_id = 2000986455 
    

    참고

    • 자리 표시자는 <SubDBName> 구독 데이터베이스의 이름을 나타냅니다.
    • 일반적으로 이러한 개체는 복제에 사용되는 저장 프로시저입니다.
  9. 차단을 일으키는 인덱스 또는 인덱싱된 뷰를 결정합니다. 이렇게 하려면 다음과 같이 하십시오.

    1. 차단 스크립트에서 속성 waitresource의 값을 찾습니다.

      샘플 차단 스크립트에서 값 waitresource 은 입니다 72057594375700480.

    2. 9a단계에서 가져온 값 waitresource 과 같도록 열을 PARTITION_ID 지정하여 뷰 sys.partitions를 쿼리하여 개체 ID 및 인덱스 ID를 가져옵니다.

      예를 들어 다음 쿼리를 실행합니다.

      SELECT object_id, index_id FROM SYS.PARTITIONS WHERE PARTITION_ID=72057594375700480
      
    3. 구독 데이터베이스에서 뷰 sys.indexes 를 쿼리하여 9b단계에서 가져온 개체 ID 및 인덱스 ID를 사용하여 인덱스를 확인합니다.

      예를 들어 다음 쿼리를 실행합니다.

      USE <SubDBName> 
      GO 
      SELECT name, type_desc, is_unique FROM sys.indexes 
      WHERE object_id = <objID> and index_id = <idxID>
      

      참고

      • 자리 표시자는 <objID> 9b단계에서 가져온 개체 ID를 나타냅니다.
      • 자리 표시자는 <idxID> 9b단계에서 얻은 인덱스 ID를 나타냅니다.
  10. 인덱싱된 보기로 인해 차단이 발생하는 경우 인덱싱된 뷰를 삭제하는 것이 좋습니다. 차단이 고유 비클러스터형 인덱스로 인해 발생하는 경우 인덱스는 삭제한 다음 고유하지 않은 인덱스로 다시 만드는 것이 좋습니다.

차단 모니터 스레드에 대한 설명

배포 에이전트 세션 간의 차단을 감지하는 차단 모니터 스레드를 유지 관리합니다. 차단 모니터 스레드가 세션 간의 차단을 감지하는 경우 배포 에이전트 한 세션을 사용하여 배포 에이전트 이전에 적용할 수 없었던 명령의 현재 일괄 처리를 다시 적용하도록 전환합니다.

차단 모니터 스레드에 대한 자세한 내용은 모니터 스레드 차단을 참조하세요.

배포 에이전트 여러 세션을 다시 시작하는 방법

배포 에이전트 여러 세션을 다시 시작하려면 먼저 배포 에이전트 저장 프로시저 sp_MSget_repl_commands 를 실행하여 구독자에서 적용되지 않은 명령에 대한 배포 데이터베이스를 다시 쿼리해야 합니다. 그런 다음 배포 에이전트 구독자에서 이러한 모든 명령을 적용해야 배포 에이전트 여러 세션을 다시 시작할 수 있습니다. 배포 에이전트 여러 세션을 다시 시작하기 전에 배포 에이전트 구독자에서 많은 명령을 적용해야 하므로 대기 중인 복제 환경에서 배포 에이전트 여러 세션을 다시 시작할 수 없습니다.

전체 프로세스를 추적하려면 배포 에이전트 출력 파일을 검사합니다.