Поделиться через


Как слияние репликации обнаруживает и разрешает конфликты

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

Обнаружение и разрешение конфликтов

Агент слияния обнаруживает конфликты с помощью lineage столбца MSmerge_contents системной таблицы. Если для статьи включено отслеживание на уровне столбцов, COLV1 столбец также используется. Эти столбцы содержат метаданные о вставке или обновлении строки или столбца, а также о том, какие узлы в топологии репликации слиянием внесли изменения в строку или столбец. Для просмотра этих метаданных можно использовать системную хранимую процедуру sp_showrowreplicainfo .

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

Конфликты разрешаются автоматически и немедленно агентом слияния, если вы не выбрали интерактивное разрешение конфликтов для статьи. Дополнительные сведения см. в разделе «Интерактивный сопоставитель конфликтов репликации Майкрософт». Если вы вручную измените победную строку для конфликта с помощью средства просмотра конфликтов репликации слиянием, агент слияния применяет победившую версию строки к серверу, потерявшему конфликт, во время следующей синхронизации.

Запись разрешённых конфликтов

После того как агент синхронизации разрешит конфликт в соответствии с логикой в решателе конфликтов, он регистрирует данные конфликтов в соответствии с типом конфликта.

  • Для UPDATE и INSERT конфликтов он записывает проигрышную версию строки в таблицу конфликтов для статьи, которая называется в формате conflict_<PublicationName>_<ArticleName>. Общие сведения о конфликте, такие как тип конфликта, записываются в таблицу MSmerge_conflicts_info.

  • В DELETE случае конфликтов она записывает в таблицу проигрышную версию строки MSmerge_conflicts_info . Если удаление проигрывает обновлению, данных для удалённой строки нет (так как она была удалена), поэтому ничего не записывается в conflict_<PublicationName>_<ArticleName>.

Таблицы конфликтов для каждой статьи создаются в базе данных публикации, базе данных подписки или в обеих (по умолчанию), в зависимости от значения, указанного для параметра @conflict_loggingsp_addmergepublication. Каждая таблица конфликтов имеет ту же структуру, что и статья, на которой она основана, с добавлением столбца origin_datasource_id . Агент слияния удаляет данные из таблицы конфликтов, если они старше срока хранения для публикации, который указан параметром @conflict_retentionsp_addmergepublication (по умолчанию — 14 дней).

Репликация предоставляет средство просмотра конфликтов репликации и хранимые процедуры (sp_helpmergearticleconflicts, sp_helpmergeconflictrows и sp_helpmergedeleteconflictrows) для просмотра данных конфликтов. Дополнительные сведения см. в разделе "Разрешение конфликтов для репликации слиянием".

Факторы, влияющие на разрешение конфликтов

Существует два фактора, влияющие на разрешение конфликта, обнаруженного агентом слияния:

  • Тип подписки: клиент или сервер (является ли подписка подпиской по запросу или принудительной подпиской не влияет на разрешение конфликтов).

  • Тип отслеживания конфликтов, используемый: уровень строк, уровень столбцов или логический уровень записи.

Типы подписок

При создании подписки, в дополнение к указанию, является ли она Push или Pull подпиской, укажите, является ли подписка клиентской или серверной; после создания подписки тип нельзя изменить (в предыдущих версиях SQL Server, клиентские и серверные подписки назывались соответственно локальными и глобальными подписками).

Подписка с назначенным приоритетом (от 0,00 до 99.99) называется подпиской на сервер; подписка с использованием значения приоритета издателя называется клиентской подпиской. Кроме того, подписчики, имеющие серверные подписки, могут повторно публиковать данные другим подписчикам. В следующей таблице приведены основные различия и использование каждого типа подписчика.

Тип Значение приоритета Б/у
Сервер Назначено пользователем Если вы хотите, чтобы разные подписчики имели разные приоритеты.
Клиент 0.00, но изменения данных принимают значение приоритета издателя после синхронизации. Если вы хотите, чтобы все подписчики имели одинаковый приоритет, и первый подписчик должен объединиться с издателем, чтобы выиграть конфликт.

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

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

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

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

  • Если подписчик повторно не публикует данные (так как он находится на уровне листа дерева повторной публикации), подписка должна быть клиентской подпиской.

Дополнительные сведения о подписках и приоритетах сервера см. в примере разрешения конфликтов слиянием на основе типа подписки и назначенных приоритетов.

Уведомление о конфликте с задержкой

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

  1. Издатель и подписчик с низким приоритетом с именем LowPrioritySub обмениваются изменениями в ходе нескольких синхронизаций без конфликтов.

  2. Подписчик с более высоким приоритетом с именем HighPrioritySub не синхронизировался с издателем в течение некоторого времени и внес изменения в те же строки, что и подписчик LowPrioritySub.

  3. Подписчик HighPrioritySub синхронизируется с издателем и выигрывает конфликты между своими изменениями и подписчиком LowPrioritySub, поскольку он имеет более высокий приоритет, чем подписчик LowPrioritySub. Теперь издатель содержит изменения, внесенные подписчиком HighPrioritySub.

  4. Затем подписчик LowPrioritySub объединяется с издателем и загружает большое количество изменений из-за конфликтов с подписчиком HighPrioritySub.

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

Уровень отслеживания

Зависит ли изменение данных в качестве конфликта от типа отслеживания конфликтов, заданного для статьи: уровня строк, уровня столбцов или логического уровня записей. Дополнительные сведения об отслеживании на уровне логических записей см. в разделе "Расширенные конфликты репликации слияния" — разрешение в логических записях.

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

Для отслеживания на уровне строк и на уровне столбцов разрешение конфликта совпадает: вся строка данных перезаписывается данными из победителя конфликта (для отслеживания на уровне логических записей разрешение зависит от свойства logical_record_level_conflict_resolution статьи).

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

Замечание

Если приложению не требуется отслеживание на уровне столбцов, рекомендуется использовать отслеживание на уровне строк (по умолчанию), так как обычно это приводит к повышению производительности синхронизации. Если используется отслеживание строк, базовая таблица может содержать не более 1024 столбцов, но столбцы должны быть отфильтрованы из статьи, чтобы опубликовать не более 246 столбцов. Если используется отслеживание столбцов, базовая таблица может содержать не более 246 столбцов.

Типы конфликтов

Хотя большинство конфликтов связаны с обновлениями (обновление на одном узле конфликтует с обновлением или удалением на другом узле), существуют и другие типы конфликтов. Каждый тип конфликта, рассмотренный в этом разделе, может возникать во время фазы загрузки или фазы выгрузки процесса объединения. Обработка отправки — это первая сверка изменений, выполненных в определенном сеансе слияния, и это этап, в течение которого Агент слияния реплицирует изменения от Подписчика к Издателю. Конфликты, обнаруженные во время этой обработки, называются конфликтами загрузки. Процесс загрузки включает перемещение изменений с издателя на подписчика и происходит после процесса выгрузки. Конфликты на этом этапе обработки называются конфликтами загрузки.

Дополнительные сведения о типах конфликтов см. в MSmerge_conflicts_info, особенно в столбцах conflict_type и reason_code.

Конфликты между обновлениями

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

Конфликты при обновлении и удалении

Агент слияния обнаруживает конфликты между обновлением и удалением, когда обновление данных на одном узле конфликтует с удалением данных на другом. В этом случае агент слияния обновляет строку; Однако, когда агент слияния выполняет поиск этой строки в месте назначения, он не может найти строку, так как она была удалена. Если победителем является узел, который обновил строку, удаление на проигравшем узле отбрасывается, и агент синхронизации отправляет только что обновленную строку на узел, потерпевший конфликт. Агент слияния записывает информацию о проигравшей версии строки в таблицу MSmerge_conflicts_info.

Не удалось изменить конфликты

Агент слияния вызывает эти конфликты, если он не может применить определенное изменение. Обычно это происходит из-за различий в определениях ограничений между издателем и подписчиком и использованием NOT FOR REPLICATION свойства NFR в ограничении. Вот некоторые примеры.

  • Конфликт внешнего ключа на подписчике, который может возникать, когда ограничение на стороне подписчика не помечается как NFR.

  • Различия в ограничениях между издателем и подписчиками, а ограничения не помечены как NFR.

  • Недоступность зависимых объектов у подписчика. Например, если вы публикуете представление, но не таблицу, от которой зависит это представление, происходит сбой при попытке вставить через это представление на подписчике.

  • Присоедините логику фильтрации для публикации, которая не соответствует ограничениям первичного ключа и внешнего ключа. Конфликты могут возникать, когда реляционный модуль SQL Server пытается выполнить ограничение, но агент слияния учитывает определение фильтра соединения между статьями. Агент слияния не может применить изменение на целевом узле из-за ограничений на уровне таблицы, что приводит к конфликту.

  • Конфликты из-за нарушений уникального индекса, уникальных ограничений или нарушений первичного ключа могут возникать, если столбцы идентификаторов определены для элемента, а автоматическое управление идентификаторами не используется. Это может стать проблемой, если два подписчика будут использовать одно и то же значение идентификатора для только что вставленной строки. Дополнительные сведения об управлении диапазоном идентификаторов см. в разделе «Репликация столбцов идентификаторов».

  • Конфликты из-за логики триггера, не позволяющей агенту слияния вставить строку в целевую таблицу. Рассмотрим триггер обновления, определенный на подписчике; триггер не помечен как NFR и содержит в своей логике ROLLBACK. Если произошел сбой, триггер выполняет ROLLBACK для транзакции, что приводит к тому, что агент слияния обнаруживает конфликт изменения.