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


Как репликация слиянием отслеживает и перечисляет изменения

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

Отслеживание изменений

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

  • MSmerge_ins_<GUID>: триггер вставки (значение идентификатора GUID для этого и других триггеров извлекается из sysmergearticles)

  • MSmerge_upd_<GUID>: триггер обновления

  • MSmerge_del_<GUID>: триггер удаления

  • MSmerge_contents

  • MSmerge_tombstone

  • MSmerge_genhistory

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

  • MSmerge_partition_groups

  • MSmerge_current_partition_mappings

  • MSmerge_past_partition_mappings

ПримечаниеПримечание

Приведенные в списке системные таблицы используются всеми подписками и публикациями слиянием в базе данных; например если в базе данных публикации содержится несколько публикаций, то таблица MSmerge_contents содержит строки из статей во всех публикациях.

Отслеживание изменений для нефильтруемых таблиц

Системные таблицы

Системные таблицы, используемые для нефильтруемых и фильтруемых таблиц, содержат следующие метаданные:

  • MSmerge_contents содержит одну строку для каждой строки, вставленной или обновленной в опубликованной таблице в базе данных.

  • MSmerge_tombstone содержит одну строку для каждой строки, удаленной из опубликованной таблицы в базе данных.

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

Процесс отслеживания изменений

Для всех нефильтруемых таблиц используется следующий процесс отслеживания изменений:

  • При выполнении вставки или обновления в опубликованной таблице срабатывает триггер MSmerge_ins_<GUID> или MSmerge_upd_<GUID>, и в системную таблицу MSmerge_contents вставляется строка. Столбец rowguid в таблице MSmerge_contents содержит идентификатор GUID для вставленной или обновленной строки, указывающий на то, что при следующем выполнении синхронизации соответствующая вставленная или обновленная строка из пользовательской таблицы должна быть отправлена издателю или подписчикам. При внесении последующих обновлений строки в пользовательской таблице, для их отражения обновляется строка в таблице MSmerge_contents.

  • При осуществлении удаления в опубликованной таблице срабатывает триггер MSmerge_del_<GUID>, и в системную таблицу MSmerge_tombstone вставляется строка. Столбец rowguid таблицы MSmerge_tombstone содержит идентификатор GUID для удаленной строки, указывающий на то, что при следующем выполнении синхронизации издателю или подписчику должна быть отправлена команда удаления для соответствующей удаленной строки в пользовательской таблице. Если на удаленную строку содержится ссылка в таблице MSmerge_contents (поскольку она была вставлена или обновлена после выполнения последней синхронизации), то эта строка удаляется из MSmerge_contents.

Отслеживание изменений для фильтруемых таблиц

Системные таблицы

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

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

    • Определены явно с использованием процедуры sp_addmergepartition или страницы Секции данных диалогового окна «Свойства публикации».

    • Созданы автоматически, если подписчик синхронизируется и запрашивает секцию, которая еще не задана в MSmerge_partition_groups.

  • Таблица MSmerge_current_partition_mappings содержит по одной строке для каждого уникального сочетания строк в MSmerge_contents и MSmerge_partition_groups. Например, если строка в пользовательской таблице принадлежит двум секциям и эти строки обновлены, то одна строка вставляется в таблицу MSmerge_contents, сообщая об обновлении, а вторая строка — в таблицу MSmerge_current_partition_mappings, указывая на то, что обновление строк затронуло две секции.

  • Таблица MSmerge_past_partition_mappings содержит по одной строке для каждой строки, которая больше не принадлежит данной секции. Строка перемещается за пределы секции в следующих случаях:

    • Строка удалена. Если строка удалена из пользовательской таблицы, она вставляется в таблицу MSmerge_tombstone и одна или более строк вставляются в таблицу MSmerge_past_partition_mappings.

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

ПримечаниеПримечание

Если используются неперекрывающиеся секции с одной подпиской на секцию (значение 3 для параметра @partition_options хранимой процедуры sp_addmergearticle), то системные таблицы MSmerge_current_partition_mappings и MSmerge_past_partition_mappings не используются для отслеживания сопоставлений секций строк, поскольку каждая строка принадлежит только одной секции и может быть изменена только на одном подписчике.

Процесс отслеживания изменений

Процесс, описанный выше (в разделе «Отслеживание изменений для нефильтруемых таблиц») для нефильтруемых таблиц, также используется и для фильтруемых таблиц, со следующими дополнениями:

  • При осуществлении вставки в опубликованную таблицу помимо данных, обновляемых или вставляемых в таблицу MSmerge_contents, в таблицу MSmerge_current_partition_mappings добавляется сопоставление секций для каждой секции, которой принадлежит строка.

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

  • При осуществлении удаления из опубликованной таблицы, помимо вставки строки в таблицу MSmerge_tombstone, из таблицы MSmerge_current_partition_mappings удаляется строка, а в таблицу MSmerge_past_partition_mappings добавляется строка.

Перечисление изменений

Системные таблицы и процедуры

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

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

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

  • Таблица MSmerge_generation_partition_mappings используется только для фильтруемых таблиц и служит для записи факта наличия в заданном поколении изменений, относящихся к заданной секции. Эта таблица в базе данных публикации содержит по одной строке для каждого уникального сочетания строк в таблицах MSmerge_genhistory и MSmerge_partition_groups.

  • Процедура sp_MSmakegeneration закрывает все открытые поколения в начале процесса перечисления.

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

  • Процедура sp_MSgetmetadata определяет, необходимо ли применить изменение из одного узла к другому узлу в виде вставки, обновления или удаления.

Процесс перечисления изменений

Во время перечисления изменений выполняется следующий процесс:

  1. Вызывается системная процедура sp_MSmakegeneration:

    • Для нефильтруемых и фильтруемых таблиц эта процедура закрывает все открытые поколения, на которые имеются ссылки в таблице MSmerge_genhistory (закрытые поколения имеют значение 1 или 2 в столбце genstatus).

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

  2. Вызывается хранимая процедура sp_MSenumchanges и связанные с ней процедуры. Эти процедуры производят перечисление изменений, которые произошли после последней синхронизации:

    1. а. Вначале процедуры определяют поколение, с которого начнется перечисление, на основе столбцов sentgen (последнее отправленное поколение) и recgen (последнее полученное поколение) в таблице sysmergesubscriptions.

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

    2. b. После этого процедуры осуществляют перечисление изменений:

      Для нефильтруемых таблиц производится перечисление всех изменений, содержащихся в поколениях после поколения, указанного в столбце sentgen или recgen: таблица MSmerge_genhistory соединяется с таблицами MSmerge_contents и MSmerge_tombstone для определения изменений, которые необходимо отправить.

      Для фильтруемых таблиц таблица MSmerge_generation_partition_mappings соединяется с таблицами MSmerge_current_partition_mappings и MSmerge_contents, а также MSmerge_past_partition_mappings и MSmerge_tombstone для определения изменений, относящихся к секции, получаемой подписчиком.

  3. Вызывается хранимая процедура sp_MSgetmetadata, чтобы определить, следует ли применить изменение как вставку, обновление или удаление. На данном этапе производится обнаружение и разрешение конфликтов. Дополнительные сведения см. в разделе Способы обнаружения и разрешения конфликтов, используемые при репликации слиянием.