Несовпадение данных на издателе и подписчике
Данные на издателе и подписчике считаются расходящимися (другими словами, данные не совпадают) в следующих случаях:
- Разное количество строк на подписчике и издателе, публикация не фильтруется. Если публикация фильтруется, возможно, что количество строк будет разным.
- Данные в одной или нескольких строках отличаются по содержимому на издателе и подписчике.
Объяснение
Данные на издателе и подписчике могут расходиться по следующим причинам:
- Данные обновлены на подписчике, который должен быть доступен только для чтения. База данных подписки должна обрабатываться в режиме только для чтения, если не используется репликация слиянием, репликация транзакций с обновляемыми подписками или одноранговая репликация транзакций.
- На подписчике используются триггеры. Триггеры могут изменять данные на подписчике, а также предотвращать обновление данных, если триггер выполняет команду ROLLBACK.
- Сценарии выполняются репликацией на подписчике, но не на издателе.
- Репликация выполнения хранимой процедуры для публикации транзакций приводит к разным результатам на подписчике.
- Нарушение ограничений или другие проблемы препятствуют вставке, обновлению или удалению строк на подписчике.
Действия пользователя
Описываемые далее действия позволяют определить, имеется ли расхождение данных и как добиться их конвергенции:
- Определите наличие расхождения данных с помощью проверки или программы tablediff:
- Если агент распространителя или агент слияния может быть запущен, определите, отсутствуют ли данные, запустив проверку двоичной контрольной суммы. Также можно использовать проверку по количеству строк, но этот метод не позволяет обнаружить разницы в содержимом данных. Дополнительные сведения см. в разделе Проверка реплицированных данных.
- Если невозможно запустить агент распространителя или агент слияния, определите, расходятся ли данные, запустив программу tablediff. Дополнительные сведения об использовании этой служебной программы для реплицированных таблиц см. в разделе How to: Compare Replicated Tables for Differences (Replication Programming).
- Если данные расходятся, можно использовать программу tablediff, чтобы создать Transact-SQL-сценарий, который обеспечит конвергенцию данных. Дополнительные сведения см. в разделе Программа tablediff.
Определение причины расхождения
Следующие действия устраняют причины, перечисленные в разделе «Объяснение».
- Данные обновляются на подписчике вне репликации:
Если требуется разрешить пользователям вставлять, обновлять и удалять данные на подписчике, используйте репликацию слиянием, репликацию транзакций с обновляемыми подписками или одноранговую репликацию транзакций. Дополнительные сведения см. в разделах Обзор репликации слиянием и Типы публикации для репликации транзакций.
Если требуется запретить пользователям вставлять, обновлять и удалять данные на подписчике, создайте триггер для каждой таблицы, содержащий слово ROLLBACK, и используйте параметр NOT FOR REPLICATION (предотвращающий срабатывание триггера в случае, когда агент репликации выполняет операцию). Например:
USE AdventureWorks GO CREATE TRIGGER prevent_user_dml ON Person.Address FOR INSERT, UPDATE, DELETE NOT FOR REPLICATION AS ROLLBACK
Дополнительные сведения см. в разделах CREATE TRIGGER (Transact-SQL) и Управление ограничениями, идентификаторами и триггерами с помощью параметра «NOT FOR REPLICATION».
- Триггеры используются на подписчике. Следует правильно управлять триггерами на подписчике, чтобы они не вызвали расхождения данных или появления других проблем.
- Триггеры должны вызывать изменения данных на подписчике, если только используется репликация слиянием, репликация транзакций с обновляемыми подписками или одноранговая репликация транзакций. Дополнительные сведения см. в разделах Обзор репликации слиянием и Типы публикации для репликации транзакций.
- Во многих случаях в триггерах должен использоваться параметр NOT FOR REPLICATION. Рассмотрим триггер, который вставляет данные в таблицу отслеживания: при первоначальной вставке строки пользователем уместно, чтобы триггер включался и вводил строку в отслеживающую таблицу; однако триггер не должен включаться, когда данные реплицируются на подписчик, так как это привело бы к вставке ненужной строки в таблицу отслеживания.
Если триггер содержит инструкцию ROLLBACK и при этом в нем не используется параметр NOT FOR REPLICATION, строки, реплицированные на подписчик, могут быть не применены. - Для репликации транзакций существуют дополнительные вопросы, касающиеся параметра XACT_ABORT и использования инструкций COMMIT и ROLLBACK в триггере. Дополнительные сведения см. в подразделе «Триггеры» раздела Вопросы использования репликации транзакций.
- Сценарии выполняются репликацией на подписчике, но не на издателе.
Параметры @pre_snapshot_script и @post_snapshot_script хранимых процедур sp_addpublication и sp_addmergepublication позволяют указать сценарии, которые запускаются до и после применения моментального снимка. Дополнительные сведения см. в разделе Выполнение сценариев до и после применения моментального снимка. Хранимая процедура sp_addscriptexec позволяет выполнять сценарий во время процесса синхронизации. Дополнительные сведения см. в разделе How to: Execute Scripts During Synchronization (Replication Transact-SQL Programming).
Эти сценарии обычно используются для административных задач, таких как добавление имен входа на подписчике. Если сценарии используются для обновления данных на подписчике, который должен быть доступен только для чтения, администратору следует убедиться в том, что это не приводит к расхождению данных. - Репликация выполнения хранимой процедуры для публикации транзакций приводит к разным результатам на подписчике.
При репликации выполнения хранимой процедуры определение процедуры реплицируется на подписчик при инициализации подписки. Когда процедура выполняется на издателе, репликация выполняет соответствующую процедуру на подписчике. Дополнительные сведения см. в разделе Публикация выполнения хранимых процедур в репликации транзакций.
Расхождение данных может возникать, если действия, выполняемые хранимой процедурой, или данные, обрабатываемые ею, различаются на подписчике и издателе. Рассмотрим процедуру, которая выполняет вычисления и затем вставляет данные в зависимости от их результатов. Если подписчик фильтруется таким образом, что вычисления на подписчике основываются на других данных, результат, вставляемый на подписчике, может быть иным либо вообще может не происходить никакой вставки. - Нарушение ограничений или другие проблемы препятствуют вставке, обновлению или удалению строк на подписчике.
В репликации транзакций нарушения ограничений рассматриваются как ошибки; по умолчанию при возникновении этих ошибок агент распространителя прекращает синхронизацию (сведения о пропуске этих ошибок см. в разделе Пропуск ошибок в репликации транзакций). В репликации слиянием нарушения ограничений обрабатываются как конфликты. Они регистрируются, но не вызывают прекращения синхронизации агентом слияния. В обоих типах репликации нарушения ограничений могут повлечь расхождение данных, если вставка, обновление или удаление, успешно выполненные на одном узле, завершатся неудачей на другом узле.
При публикации таблицы параметры схемы по умолчанию указывают, что ограничения внешнего ключа и проверочные ограничения должны быть созданы в базе данных подписки с установленным параметром NOT FOR REPLICATION. Если для приложения необходимы другие установки ограничений, измените параметры схемы. Дополнительные сведения см. в разделах Как указать параметры схемы (среда SQL Server Management Studio) и How to: Specify Schema Options (Replication Transact-SQL Programming).