Одноранговая репликация. Обнаружение конфликтов в одноранговой репликации
Область применения: SQL Server
Одноранговая репликация транзакций дает возможность вставлять, обновлять и удалять данные в любом узле топологии и передавать изменения в данных на другие узлы. Данные можно изменять в любом узле, поэтому изменения, вносимые на различных узлах, могут конфликтовать друг с другом. Если строка изменяется на нескольких узлах, это может вызвать конфликт или даже потерю обновления, когда эта строка передается на другие узлы.
Одноранговая репликация позволяет включить обнаружение конфликтов во всей одноранговой топологии. Эта возможность помогает избежать проблем, вызванных необнаруженными конфликтами, включая недопустимое поведение приложения или потерю обновлений. При включенном режиме обнаружения конфликтов конфликтующее изменение по умолчанию рассматривается как критическая ошибка, вызывающая сбой агента распространителя. В случае конфликта топология остается в несогласованном состоянии, пока конфликт не будет разрешен, а данные согласованы во всей топологии.
Примечание.
Чтобы избежать возможной несогласованности данных, убедитесь, что в одноранговой топологии отсутствуют конфликты, даже при включенном обнаружении конфликтов. Чтобы операции записи выполнялись только на одном узле, приложения, получающие доступ к данным и изменяющие их, должны секционировать операции вставки, обновления и удаления. Такое секционирование обеспечивает тот факт, что изменения конкретной строки на одном узле синхронизируются с остальными узлами в топологии, прежде чем эта строка будет изменена другим узлом. Если приложению требуется усложненное обнаружение конфликтов, используйте репликацию слиянием. Дополнительные сведения см. в статьях Merge Replication (Репликация слиянием) и Detect and Resolve Merge Replication Conflicts (Обнаружение и разрешение конфликтов репликации слиянием).
Основные сведения о конфликтах и обнаружении конфликтов
В одной базе данных изменения, вносимые в одну строку различными приложениями, не создают конфликта. Это происходит благодаря тому, что транзакции сериализуются, а для обработки параллельных изменений используются блокировки. В асинхронной распределенной системе, какой является одноранговая репликация, транзакции воздействуют на каждый узел независимо друг от друга, при этом механизм сериализации транзакций по нескольким узлам отсутствует. Здесь можно использовать протокол, такой как двухфазная фиксация, но это приводит к существенному снижению производительности.
В таких системах, как одноранговая репликация, конфликты не обнаруживаются, если изменения фиксируются на отдельных узлах. Но они обнаруживаются в случаях, когда эти изменения реплицируются и применяются на других узлах. При выполнении одноранговой репликации конфликты обнаруживаются с помощью хранимых процедур, которые применяют изменения к каждому узлу с учетом содержимого одного или нескольких скрытых столбцов в каждой опубликованной таблице.
До SQL Server 2019 (15.x) CU 13 SQL Server добавляет один скрытый столбец в каждую опубликованную таблицу: $sys_p2p_cd_id
В этом скрытом столбце хранится идентификатор, сочетающий в себе идентификатор инициатора , указываемый пользователем для каждого узла, и версию строки.
В SQL Server 2019 (15.x) CU 13 и более поздних версий, если создать одноранговый узел для одноранговой публикации с @p2p_conflictdetection_policy = 'lastwriter'
помощью SQL Server добавляет дополнительный скрытый столбец в каждую опубликованную таблицу: $sys_md_cd_id
В этом скрытом столбце хранятся дата и время в виде типа данных datetime2
.
В ходе синхронизации агент распределителя выполняет процедуры для каждой таблицы. Эти процедуры выполняют операции вставки, обновления и удаления с других узлов. Если одна из этих процедур обнаруживает конфликт при считывании одного или нескольких значений скрытых столбцов, она фиксирует ошибку 22815 со степенью серьезности 16.
A conflict of type '%s' was detected at peer %d between peer %d (incoming), transaction id %s and peer %d (on disk), transaction id %s
По умолчанию при возникновении этой ошибки агент распространителя прекращает применение изменений к данному узлу. Сведения об обработке выявленных конфликтов см. в разделе Обработка конфликтов.
Примечание.
Работать со скрытым столбцом может только пользователь, вошедший в систему через выделенное административное соединение. Информацию о DAC вы найдете в статье Диагностическое соединение для администраторов баз данных.
При выполнении одноранговой репликации обнаруживаются следующие типы конфликтов.
Вставка-вставка
Все строки во всех таблицах, участвующих в одноранговой репликации, уникальным образом идентифицируются с помощью значений первичного ключа. Конфликт «вставка-вставка» имеет место тогда, когда вставка строки с одним и тем же значением ключа осуществляется более чем на одном узле.
Обновление-обновление
Происходит, когда одна и та же строка обновляется более чем на одном узле.
Вставка-обновление
Происходит, когда строка обновляется на одном узле, а на другом та же строка удаляется и затем вновь вставляется.
Вставка-удаление
Происходит, если строка удаляется на одном узле, а на другом та же строка удаляется и затем вновь вставляется.
Обновление-удаление
Происходит, когда строка обновляется на одном узле, а на другом та же строка удаляется.
Удаление-удаление
Происходит, когда строка удаляется более чем на одном узле.
Активизация функции обнаружения конфликтов
Чтобы использовать обнаружение конфликтов, включите обнаружение для всех узлов. По умолчанию обнаружение конфликтов включено при настройке одноранговой репликации в SQL Server Management Studio. Мы рекомендуем включать функцию обнаружения конфликтов — даже в тех случаях, когда возникновение конфликтов не ожидается. Обнаружение конфликтов можно включить и отключить с помощью хранимых процедур Management Studio или Transact-SQL:
Вы можете включить и отключить обнаружение в Management Studio с помощью страницы "Параметры подписки" диалогового окна "Свойства публикации" или страницы "Настройка топологии" мастера настройки одноранговой топологии .
Если вы настраиваете обнаружение конфликтов с помощью Management Studio, агент распространения настроено для прекращения применения изменений при обнаружении конфликта.
Вы также можете включить и отключить обнаружение с помощью следующих хранимых процедур:
sp_configure_peerconflictdetection.
В случае настройки режима обнаружения конфликтов с помощью хранимых процедур пользователь может указать, должен ли агент распространителя прекратить применение изменений при обнаружении конфликта. По умолчанию агент прекращает применение изменений. Рекомендуется использовать настройки по умолчанию.
Обработка конфликтов
Если в ходе одноранговой репликации возникает конфликт, создается предупреждение об обнаружении конфликтов в одноранговой репликации. Настройте это предупреждение так, чтобы при возникновении конфликта вам приходило оповещение. Дополнительные сведения об оповещениях см. в статье Использование предупреждений для событий агента репликации.
По прекращении действий агента распространителя и после направления предупреждения обрабатывайте происшедший конфликт в соответствии с одним из следующих подходов.
Выполните повторную инициализацию узла, на котором был обнаружен конфликт, с резервной копии узла, содержащей необходимые данные (рекомендуемый подход). Этот метод гарантирует сохранение данных в согласованном состоянии.
Попытайтесь вновь синхронизировать узел, дав возможность агенту распространителя продолжить применение изменений.
Выполните хранимую процедуру sp_changepublication, указав значение 'p2p_continue_onconflict' для параметра @property и значение true для параметра @value.
Перезапустите агент распространителя.
Проверьте обнаруженные конфликты с помощью средства просмотра конфликтов и определите вовлеченные в конфликты строки, тип конфликта, а также выигравшую сторону. Конфликт разрешается в соответствии со значением идентификатора инициатора, указанным пользователем во время настройки: победителем в конфликте становится строка, инициированная на узле с самым высоким значением идентификатора. Дополнительные сведения см. в разделе "Просмотр конфликтов данных" для публикаций транзакций (SQL Server Management Studio).
Выполните проверку и убедитесь в том, что конвергенция конфликтующих строк завершилась верно. Дополнительные сведения см. в статье Проверка реплицированных данных.
Примечание.
Если по выполнении этого шага несогласованность данных сохраняется, необходимо вручную обновить строки узла с самым высоким приоритетом, а затем разрешить распространение изменений с этого узла. Если в топологии более нет конфликтующих изменений, все узлы будут приведены в согласованное состояние.
Выполните хранимую процедуру sp_changepublication, указав значение 'p2p_continue_onconflict' для параметра @property и значение false для параметра @value.
Автоматическое разрешение конфликтов с приоритетом последней записи
Начиная с SQL Server 2019 (15.x) CU 13, можно настроить одноранговую репликацию для автоматического разрешения конфликтов, позволяя последней вставке или обновлению, чтобы выиграть конфликт. Если любая из двух операций записи удаляет строку, SQL Server при разрешении конфликта отдает приоритет операции удаления. Такой метод называют приоритетом последней записи.
Для настройки приоритета последней записи используйте хранимые процедуры. Дополнительные сведения см. в статье Настройка обнаружения и разрешения конфликтов путем определения приоритета последней записи. Настроить его с помощью SQL Server Management Studio невозможно.
Примечание.
Одноранговая репликация с приоритетом последней записи зависит от синхронизации часов участвующих узлов для получения надежных результатов. Если показания часов у участвующих серверов существенно расходятся, результат разрешения конфликта может оказаться неожиданным и (или) нежелательным. Например, если сервер A имеет точные часы, а часы сервера B отстают на одну неделю, сервер А будет получать приоритет при всех разрешениях конфликта, даже если он не последним обновлял данные в строке. Если вы не можете поддерживать допустимый диапазон отклонения для часов, вы можете выбрать другую стратегию разрешения конфликтов.