Настройка и устранение неполадок параметра SubscriptionStreams агент распространения в SQL Server

Исходная версия продукта: SQL Server (все поддерживаемые версии)
Исходный номер базы знаний: 953199

В этой статье содержатся дополнительные сведения о параметре SubscriptionStreams, рекомендации по использованию этого параметра и связанные с ним способы устранения неполадок.

Введение

Параметр SubscriptionStreams можно использовать для управления количеством подключений. В репликации транзакций в Microsoft SQL Server параметр можно использовать для включения нескольких подключений, которые агент распространения использует для параллельного применения пакетов изменений к подписчику. Эта операция значительно повышает пропускную способность репликации. В то же время агент распространения по-прежнему может поддерживать те же транзакционные характеристики, что и при использовании агент распространения одного подключения для применения изменений. Если одно из подключений не выполняется или фиксируется, все подключения прервут текущий пакет, а агент будет использовать один поток для повторных попыток неудачных пакетов. Перед завершением этого этапа повтора на подписчике могут возникнуть временные несогласованности транзакций. После успешной фиксации неудачных пакетов подписчик возвращается в состояние согласованности транзакций.

Если для параметра SubscriptionStreamsзадано значение 2 или больше , порядок получения транзакций на подписчике может отличаться от порядка, в котором они были выполнены на издателе. Если это поведение вызывает нарушения ограничений во время синхронизации, следует использовать NOT FOR REPLICATION параметр для отключения принудительного применения ограничений во время синхронизации. Дополнительные сведения см. в разделе Управление поведением триггеров и ограничений в синхронизации.

Факторы, которые следует учитывать перед включением SubscriptionStreams

SubscriptionStreams в основном отвечает за задержку от распространителя к подписчику, поэтому, прежде чем вы решите перейти на SubscriptionStreams, убедитесь, что у вас действительно есть задержка от распространителя к подписчику. Маркеры трассировки можно использовать в мониторе репликации или Монитор производительности счетчиков, таких как SQLServer:Replication Dist.>Dist:Задержка доставки, чтобы иметь представление об уровне задержки.

Задержка от распространителя к подписчику может быть вызвана многими причинами, такими как, помимо прочего, следующие:

  • Блокировка на распространителе или подписчике
  • Любое узкое место на распространителе или подписчике, например медленные диски, низкая пропускная способность сети и устаревшая статистика
  • Массовые транзакции, поступающие от Publisher
  • Частота входящих транзакций от издателя слишком высока
  • Триггеры или ненужные индексы в базе данных с подпиской

Администратор базы данных (DBA) должен принять вызов и проверить, поможет ли SubscriptionStreams он ему или нет. Например, в случае блокировки на подписчике увеличение количества одновременных подключений не поможет, но может усугубить ситуацию. В то время как в таких ситуациях, как скорость входящих транзакций от издателя слишком высока, и вы чувствуете, что один поток для агент распространения не может справиться с входящей нагрузкой, можно увеличить значение параметра SubscriptionStreams до >=2. Это также может помочь в ситуациях с медленной сетью и медленным диском. В идеале максимальное значение для этого параметра равно 64, но рекомендуемое значение (или хорошее значение для начала) равно количеству физических процессоров в назначении (подписчике).

Настройка параметра SubscriptionStreams

SubscriptionStreams— это один из параметров, который не отображается в профиле агент распространения в мониторе репликации. Можно указать значение для этого параметра агента с помощью @subscriptionstreamssp_addsubscription (Transact-SQL) или добавить этот параметр в раздел команды задания агента распространения, выполнив следующую процедуру:

  1. Откройте монитор репликации, разверните узел Мой издатель и выберите публикацию в левом окне панели. В окне правой панели в разделе Все подписки вы увидите список всех подписчиков этой публикации.

  2. Щелкните правой кнопкой мыши подписчика, для которого нужно включить параметр SubscriptionStreams , и выберите пункт Просмотреть сведения. Откроется новое окно со сведениями о сеансе агент распространения.

  3. В этом новом окне выберите Действие в строке меню вверху и выберите агент распространения Свойства задания. Откроется окно Свойства задания для агент распространения.

  4. В левом окне панели выберите Шаги , а затем в окне справа выберите Запустить агент , а затем выберите Изменить. Откроется новое окно.

  5. Прокрутите страницу до конца раздела команды (в крайней правой части) и добавьте этот параметр -SubscriptionStreams 6.

  6. Сохраните параметры и перезапустите задание агент распространения. Для реализации изменений требуется перезапуск агент распространения.

Примечание.

В приведенном выше примере имеет значение 6. Это означает, SubscriptionStreams что мы ищем шесть параллельных подключений для агент распространения на подписчике. Это число можно задать в рамках среды и тестирования.

Определение количества потоков

Вы можете заметить повышение производительности с помощью параметра SubscriptionStreams. Если есть улучшение, улучшение может быть номинальным. Трудно определить, какое улучшение производительности будет обеспечивать каждая дисковая подсистема на рынке с помощью SubscriptionStreams. Поэтому рекомендуется подготовить тестовую среду, которая имитирует рабочую среду. Вы можете протестировать сценарии, использующие SubscriptionStreams различные значения конфигурации, и сценарий, который не использует SubscriptionStreams.

Мы рекомендуем выполнить нагрузочное тестирование публикации и подписки, чтобы определить, какие улучшения производительности можно получить с помощью SubscriptionStreams. Необходимо выполнить тестирование базовых показателей производительности, чтобы понять ожидаемую пропускную способность дисковой подсистемы. Перед выполнением каждого теста примените много изменений для создания нагрузки на издателе. При создании нагрузки убедитесь, что агент распространения не выполняется. Если репликация имеет достаточную задержку, запустите агент распространения, чтобы проверить производительность для следующих конфигураций:

  • Не используйте параметр SubscriptionStreams.
  • Задайте значение равным SubscriptionStreams количеству процессоров на сервере. Например, если сервер имеет восемь процессоров, задайте значение SubscriptionStreams 8.
  • Укажите разные значения для, SubscriptionStreams чтобы получить оптимальную конфигурацию.

При выполнении теста можно отслеживать следующие счетчики производительности агент распространения:

  • Dist: доставленные cmds/sec
  • Dist: задержка доставки

Поведение агент распространения после указания параметра SubscriptionStreams

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

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

Причины для агент распространения переключения на использование только одного сеанса

По многим причинам агент распространения может переключиться на использование только одного сеанса. Ниже приведены наиболее распространенные причины.

  • Когда агент распространения применяет изменения, один из сеансов выдает ошибку.

    Например, агент распространения вставляет строку в дочернюю таблицу с помощью одного сеанса. Если это происходит до того, как агент распространения вставляет соответствующую строку в родительскую таблицу с помощью другого сеанса, нарушение ограничения внешнего ключа выдает сообщение об ошибке.

  • Блокирующий поток монитора обнаруживает блокировку. Блокировка может происходить по одной из следующих причин:

    • Агент распространения выполняет INSERT операцию и с таблицей UPDATE на подписчике с помощью разных сеансов. Если таблица содержит уникальный некластеризованный индекс, блокировка между двумя сеансами может возникать, когда агент распространения обновляет ключи индекса таблицы.

    • На подписчике агент распространения выполняет инструкции языка обработки данных (DML) в нескольких таблицах. Если в этих таблицах определено индексированное представление, при обновлении ключей общего индекса между двумя сеансами может возникать блокировка между двумя сеансами.

    • Агент распространения выполняет инструкцию DML для таблицы на подписчике с помощью одного сеанса. Триггеры DML определены в этой таблице. Триггеры DML выполняют инструкции DML в другой таблице, которая обновляется с помощью другого сеанса. В этой ситуации может происходить блокировка между двумя сеансами.

Настоятельно рекомендуется не использовать следующие объекты базы данных в базе данных подписчика:

  • Ограничения внешнего ключа
  • Уникальные некластеризованные индексы
  • Индексированные представления
  • Триггеры DML, которые могут привести к блокировке между сеансами

Как определить, переключился ли агент распространения на использование только одного сеанса

Для этого используйте один из следующих методов:

Примечание.

Хотя вы можете подтвердить, что агент распространения не переключился на использование одного сеанса с помощью метода 1, необходимо использовать метод 2 или 3, чтобы убедиться, что агент распространения переключился на использование одного сеанса.

  • Способ 1

    Запросите sys.dm_exec_sessions динамического административного представления (DMV) для сеансов подключения к базе данных подписки. Если отображается только один сеанс подключения, агент распространения, возможно, переключился на использование одного сеанса. Если отображается несколько сеансов подключения, агент распространения по-прежнему использует указанное количество сеансов.

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

  • Способ 2

    Запрос столбца commentsтаблицы msdistribution_history в базе данных распространителя. Если результат запроса содержит следующую запись, агент распространения переключился на использование одного сеанса:

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

  • Способ 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 может быть вызвано любой ошибкой, которая может быть связана с проблемой. Например, ошибка может быть вызвана нарушением ограничения внешнего ключа.

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

  3. Если агент распространения переключился на использование одного сеанса, остановите трассировку.

  4. Из выходного файла агент распространения или из столбца start_timeтаблицы msdistribution_history получите метку времени следующей записи:

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

  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 IdProc имеет значение 2000986455. Объект Object Id в Proc сеансе блокировки имеет значение 1172459501.

  8. В базе данных подписки запросите представление sys.objects , указав столбец object_id , равный идентификаторам объектов, полученным на шаге 7. После этого можно определить имена объектов.

    Например, выполните следующий запрос в контексте базы данных подписки:

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

    Примечание.

    • Заполнитель <SubDBName> представляет имя базы данных подписки.
    • Обычно эти объекты являются хранимыми процедурами, которые используются в репликации.
  9. Определите индекс или индексированное представление, которое вызывает блокировку. Для этого выполните следующие действия:

    1. В сценарии блокировки найдите значение свойства waitresource.

      В примере сценария блокировки значение waitresource равно 72057594375700480.

    2. Запросите представление sys.partitions , чтобы получить идентификатор объекта и идентификатор индекса, указав столбец PARTITION_ID , равный значению объекта , полученному waitresource на шаге 9a.

      Например, выполните следующий запрос:

      SELECT object_id, index_id FROM SYS.PARTITIONS WHERE PARTITION_ID=72057594375700480
      
    3. В базе данных подписки запросите представление sys.indexes , чтобы определить индекс с помощью идентификатора объекта и идентификатора индекса, полученного на шаге 9b.

      Например, выполните следующий запрос:

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

      Примечание.

      • Заполнитель <objID> представляет идентификатор объекта, полученный на шаге 9b.
      • Заполнитель <idxID> представляет идентификатор индекса, полученный на шаге 9b.
  10. Если блокировка вызвана индексируемым представлением, рекомендуется удалить индексированное представление. Если блокировка вызвана уникальным некластеризованным индексом, рекомендуется удалить индекс, а затем повторно создать неуникальный индекс.

Описание потока блокирующего монитора

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

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

Как агент распространения возобновляет несколько сеансов

Прежде чем агент распространения сможет возобновить несколько сеансов, агент распространения должен выполнить хранимую процедуру sp_MSget_repl_commands для запроса базы данных распространителя для команд, которые не были применены на подписчике. Затем агент распространения должен применить все эти команды на подписчике, прежде чем агент распространения сможет возобновить несколько сеансов. В скрытой среде репликации агент распространения не может возобновить несколько сеансов, так как агент распространения должен применить много команд на подписчике, прежде чем агент распространения сможет возобновить несколько сеансов.

Чтобы отследить весь процесс, изучите выходной файл агент распространения.