Двунаправленная репликация между двумя базами (постановка)

Материал из GedeminWiki
Перейти к: навигация, поиск

На основе подробно рассмотренной схемы однонаправленной репликации построим схему, в которой базы A и B равноправны в плане изменения данных.

repl_ab_2.png

Как и раньше, базы обмениваются между собой сообщениями в асинхронном режиме, т.е. база A может посылать сообщения в тот момент, когда база B недоступна и наоборот. Порядок выполнения действий над объектами на базе A должен строго сохраняться при переносе на базу B и наоборот. Транспорт передачи сообщений не гарантирует нам ни сохранности и целости конкретного сообщения, ни сохранения порядка при передаче нескольких сообщений.

В один момент времени изменение объектов возможно только на одной из баз, которая называется Активной базой данных (АБД). Активная база данных в начальный момент времени задается схемой репликации и называется Главной базой данных (ГБД). Статус активности передается по запросу от одной базы данных к другой. ГБД передает статус активности на ограниченный промежуток времени, по истечении которого ГБД снова становится активной, даже если она не посылала соответствующего запроса.

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

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

Состояния объекта в БД

Каждый объект в базе данных находится в определенном состоянии. В таблице ниже перечислены возможные состояния, а также определены допустимые переходы из одного состояния в другое. Состояние объекта влияет на блокировку действий по его изменению или удалению.

Состояние Описание Блокировка Переход
I Каждый объект, который существовал до настройки схемы репликации, имеет состояние I. В начальный момент времени такой объект присутствует как в базе A, так и в B. Нет L, R, F
L Изменение объекта занесено в лог. Используется для информирования системы о необходимости отсылки сообщения "Передача объекта". Объект в состоянии L может быть изменен только в том случае, если после него в логе нет никаких других записей. Последовательные изменения (в смысле порядка записей в логе) одного и того же объекта допускаются. S, B
B Используется для остановки процесса передачи данных. При обработке объекта в состоянии B, процесс формирования сообщений останавливается с уведомлением пользователя о том, какая именно запись вызвала остановку. Аналогично состоянию L. L
S Объект был отослан на другую базу данных. Аналогично состоянию L. C
C Успешная передача и запись объекта в противоположную БД подтверждена. Нет L, R, F
R Объект принят и успешно записан в БД. Нет L, R, F
F Объект принят, но не может быт записан в БД. Нужно срочное вмешательство системного администратора. R

Лог изменений

Фиксирование изменений состояния объекта осуществляется в логе, который заполняется триггерами и содержит:

  • целочисленный порядковый номер изменения (начиная с единицы),
  • идентификатор объекта (RUID),
  • тип объекта,
  • вид операции (создание, изменение, удаление),
  • состояние объекта,
  • дата и время изменения состояния.

В дальнейшем, символом N мы будем обозначать номер изменения, а символом М -- максимальный номер изменения в логе. М принимается равным нулю, если лог пуст.

Разрывность последовательности номеров изменений

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

 Ni + 1 - Ni >= 1

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

Соответствие номера изменения

Важно отметить, что в логах обоих баз фиксация изменения состояния одного и того же объекта проходит под одинаковым номером. Например, на АБД создан объект О.

  1. В лог АБД будет помещена запись с номером Х, состояние L.
  2. В процессе сеанса обмена сообщениями, объект О будет подготовлен для передачи на НБД. Запись с номером Х в логе АБД, перейдет в состояние S.
  3. НБД успешно примет объект. В логе НБД появится запись с таким же номером Х в состоянии R.
  4. На АБД уйдет подтверждение.
  5. По принятии подтверждения, запись с номером Х в логе АБД перейдет в состояние C.

Состояние базы данных

Мы будем называть целое число S состоянием базы данных. По соотношению М и S можно судить о текущем состоянии репликации. Для АБД:

  • S = М -- все изменения переданы и подтверждены.
  • S < M -- есть изменения для передачи.
  • S > M -- серьезный сбой в данных репликации, нарушение логической целостности.

Для НБД:

  • S = М -- все изменения приняты и успешно записаны.
  • S < M -- возникли ошибки при записи объекта в БД.
  • S > M -- серьезный сбой в данных репликации, нарушение логической целостности.

В начальный момент времени:

 S = M = 0

Базы данных А и B находятся в идентичном состоянии, если Ma = Sa = Mb = Sb.

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

S равно максимальному номеру записи в логе в состоянии C или R.

В начальный момент времени базы данных находятся в идентичном состоянии и выполняется равенство:

 Sa = Sb = Мa = Мb = 0

Журнал репликации

Журнал используется системным администратором для выявления проблем и/или профилирования репликации. В журнал заносятся:

  • Информативные сообщения
  • Предупреждения
  • Критические ошибки

Связь в асинхронном режиме

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

 Tr -- Допустимое время ожидания ответа на посланное сообщение.
 Ts -- Время простоя НБД с момента обработки последнего сообщения до отсылки запроса о состоянии АБД.
 Ti -- Период с которым БД осуществляет проверку очереди сообщений и отсылку изменений.
 Ta -- Максимальное время, на которое статус активности передается от ГБД.

Критерий идентичности баз в асинхронном режиме

АБД знает о том, что она идентична НБД, если ее статус активности не истек и S = M. Т.е. нет объектов в состоянии L, B или S.

НБД знает о том, что она идентичная АБД, если получено сообщение "Состояние БД" (ответ на сообщение "Запрос состояния БД") из которого следует что MАБД=SНБД.

Запрос состояния БД

Когда НБД хочет узнать текущее состояние синхронизации с АБД, она:

  1. Посылает специальное сообщение "Запрос состояния БД" и фиксирует время его отправки.
  2. Получив данное сообщение АБД проверяет свой лог:
    1. Если нет объектов к передаче, то высылается сообщение "Состояние БД".
    2. Если есть объекты к передаче, то они отсылаются и АБД запоминает, что после получения подтверждения о их пересылке следует отослать сообщение "Состояние БД".
  3. После отсылки запроса НБД периодически проверяет свою очередь сообщений.
    1. Если в течение Tr в очередь не поступило ни одного ответа от АБД, то системный администратор оповещается о возможном нарушении канала связи или неполадках на АБД.
    2. Если сообщения поступили, то они обрабатываются в определенном порядке (см. ниже). Если поступил ответ "Состояние БД", MАБД сверяется с SНБД
      1. При их равенстве базы данных считаются идентичными (синхронизированными).
      2. Если MАБД > SНБД, то НБД отсылает сообщение "Запрос на передачу объекта" с указанием номера SНБД + 1.
      3. Состояние, когда MАБД < SНБД, свидетельствует о серьезной рассинхронизации двух баз данных и требует немедленного информирования системного администратора.

"Запрос состояния БД" отсылается автоматически по истечении интервала времени Ts с момента обработки последнего сообщения от УБД или с момента отправки предыдущего запроса на состояние, на который не поступило ответа.

Передача статуса активной базы данных

Передача статуса АБД возможна только между полностью синхронизированными базами данных.

Когда НБД нуждается в активном статусе:

  1. Она сначала обрабатывает очередь сообщений.
  2. Затем посылает сообщение "Запрос статуса АБД" и запоминает время отсылки сообщения. Вместе с сообщением передается SНБД.
  3. АБД принимает сообщение и проверяет свой лог.
    1. Если MАБД > SАБД, то изменения передаются на НБД. В этом случае сообщение игнорируется. НБД должна:
      1. принять все изменения,
      2. выслать подтверждения,
      3. и только потом, повторно, выслать "Запрос статуса АБД".
    2. Если MАБД = SАБД, то проверяем равенство SАБД = MНБД:
      1. При его выполнении база переходит в состояние НБД, а на прежнюю НБД отсылается сообщение "Передача статуса АБД" (если база уже была в состоянии НБД, то отражаем этот факт в журнале, но все равно отсылаем сообщение "Передача статуса АБД").
      2. Если равенство не выполняется, то имеем серьезный сбой в репликации или на НБД присутствуют объекты в состоянии F. Незамедлительно информируем системного администратора.
  4. База, которая отослала "Запрос статуса АБД" периодически проверяет очередь сообщений.
    1. Если получено сообщение "Передача статуса АБД", то база переходит в состояние АБД.
    2. Если за время Tr ответ не получен, то в журнал заносится соответствующее событие и повторяется последовательность действий начиная с п.1.

Если АБД получила статус активности на ограниченное время

По истечении заданного промежутка времени:

  1. База переводится в неактивное состояние (только для чтения).
  2. Все изменения отсылаются на НБД.
  3. Ожидается подтверждение передачи всех изменений.
  4. После его получения отсылается сообщение "Передача статуса АБД".

Последовательность обмена сообщениями

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

АБД

Проверяется очередь сообщений:

  1. Очередь сообщений пуста:
    1. Для объектов в состоянии S, с момента отправки которых прошло времени больше чем Tr, на НБД отсылаем сообщение "Запрос подтверждения передачи объекта" с указанием идентификаторов объектов. Одновременно в журнале отражаем факт превышения времени ожидания ответа на сообщение "Передача объекта".
    2. Для каждого объекта в состоянии L формируется и посылается отдельное сообщение "Передача объекта". После формирования и успешной отправки сообщения, запись в логе переводится в состояние S.
  2. Если в очереди присутствуют только сообщения типа "Запрос состояния БД", отвечаем сообщением "Состояние БД" и очищаем очередь.
  3. Если в очереди присутствуют сообщения, сортируем их по порядковому номеру. В процессе сортировки удаляем сообщения типа "Запрос состояния БД". Обрабатываем последовательно:
    1. "Подтверждение передачи объекта":
      1. Если номер изменения из сообщения соответствует номеру первого объекта со статусом S (в порядке очередности записей в логе), то переводим объект в состояние C. Удаляем сообщение из очереди и продолжаем обрабатывать список.
      2. Если номер из сообщения меньше номера первого объекта со статусом S, то игнорируем такое сообщение. Удаляем сообщение из очереди и продолжаем обрабатывать список. Заносим в журнал информацию о получении лишнего подтверждения.
      3. Если номер из сообщения больше номера первого объекта со статусом S:
        1. Еще не истек допустимый интервал времени с момента отправки первого объекта в состоянии S. Сообщение из очереди не удаляем. Продолжаем обрабатывать список, пропуская все последующие сообщения типа "Подтверждение передачи объекта".
        2. Истекло время, отпущенное ЦБД на ответ. Отсылаем на сервер сообщение "Запрос подтверждения передачи объекта" с указанием идентификаторов всех объектов, для которых с момента отправки прошло времени больше чем Tr. Сообщение из очереди не удаляем. Продолжаем обрабатывать список, пропуская все сообщения типа "Подтверждение передачи объекта". Помещаем информацию о недошедшем подтверждении в журнал.
      4. Если принято подтверждение для последнего из ранее переданных объектов и ранее было получено сообщение "Запрос состояния БД", то отвечаем сообщением "Состояние БД".
    2. "Запрос на передачу объекта":
      1. Если запрашиваемый объект находится в состоянии S, то передаем его на ЦБД. Удаляем сообщение из очереди и продолжаем обрабатывать список. Помещаем в журнал информацию о повторной передаче объекта.
      2. Если запрашиваемый объект находится в состоянии L или C, или вообще отсутствует в списке, то игнорируем сообщение и удаляем его из очереди, а в журнал помещаем запись с информацией о запросе на передачу ранее переданного и подтвержденного объекта.
    3. "Передача объекта", "Запрос подтверждения передачи объекта":
      1. Налиие этих сообщений в очереди являетмя признаком серьезного сбоя в схеме репликации и нуждается в немедленном внимании системного администратора.

НБД

Если в логе НБД присутствует запись в состоянии F, т.е. была ошибка при загрузке объекта, то репликация останавливается. Обработка очереди сообщений не производится.

Проверяется наличие сообщений в очереди.

  1. Очередь пуста:
    1. Ранее было отправлено сообщение "Запрос состояния БД":
      1. Если интервал времени на ответ не истек, то продолжаем ожидать.
      2. Интервал времени истек. Информируем системного администратора. Повторяем "Запрос состояния БД".
    2. Если истек интервал проверки связи и состояния БД, то отсылаем "Запрос состояния БД".
  2. Очередь содержит только сообщения типа "Состояние БД". Берем последнее из них в хронологическом порядке, остальные игнорируем:
    1. Если MАБД = SНБД, базы в идентичном состоянии.
    2. Если MАБД > SНБД, есть объекты к передаче. Отсылаем запрос на передачу объекта.
    3. Если MАБД < SНБД, серьезный сбой. Информируем системного администратора.
  3. Очередь не пуста.
    1. Сортируем сообщения в порядке номеров. Выкидываем все сообщения "Состояние БД", которые идут в начале, в середине, но не в конце очереди. Обрабатываем в порядке очередности.
      1. Если номер предыдущего изменения из первого сообщения в очереди равен SНБД, то загружаем объект. Удаляем текущее сообщение и продолжаем обрабатывать очередь.
      2. Если номер предыдущего изменения из первого сообщения в очереди меньше SНБД, то игнорируем такое сообщение. Удаляем его и продолжаем обрабатывать очередь. В журнал помещаем запись о несанкционированной повторной передаче уже принятого объекта.
      3. Если номер предыдущего изменения из первого сообщения в очереди больше SНБД, то прекращаем обработку очереди. Текущее сообщение не удаляем. На АБД отсылаем сообщение "Запрос на передачу объекта", где указываем диапазон изменений, которые нас интересуют: с SНБД до номера изменения первого сообщения в очереди, не включая границы.
    2. По окончании обработки очереди (не важно, полной или частичной), отсылаем на АБД сообщение "Подтверждение передачи объектов" с указанием номеров изменений, успешно записанных в НБД.
    3. При возникновении конфликта записи объекта в НБД останавливаем обработку очереди. В лог НБД заносим пометку номера изменения и ставим ему статус F. Информируем системного администратор о серьезном сбое репликации.

Структура сообщения

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

  • Заголовок
    • Порядковый номер сообщения (формируется генератором)
    • Тип сообщения
    • Дата и время отправки
    • Отправитель
    • Получатель
    • Число M
    • Число S (S <= M)
    • Контрольная сумма
  • Данные, в зависимости от типа сообщения. Для сообщений некоторых типов данные могут отсутствовать:
    • "Передача объекта"
      • Номер изменения в логе.
      • Номер предыдущего изменения в логе.
      • Поток данных объекта.
    • "Запрос подтверждения передачи объекта"
      • Диапазон номеров изменений в логе.
    • "Состояние БД"
      • Нет данных.
    • "Запрос состояния БД"
      • Нет данных.
    • "Подтверждение передачи объекта"
      • Диапазон номеров изменений в логе.
    • "Запрос на передачу объекта"
      • Диапазон от Sb + 1 до наименьшего номера изменения, переданного в сообщении "Передача объекта".
    • "Запрос статуса АБД"
      • Нет данных.
    • "Передача статуса АБД"
      • Нет данных.

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

Если на момент формирования сообщения S > M, то останавливаем процесс и информируем системного администратора о серьезном сбое.

Контроль синхронизации часов

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

В код репликатора следует включить синхронизацию с внешним источником времени по протоколу NTP или SNTP.

Особенности физической реализации

Очередность сохранения объектов и формирование потока

Механизм сохранения в поток платформы Гедымин рекурсивно обходит все ссылки, от которых зависит сохраняемый объект. Возможна ситуация, когда в логе будут находиться последовательно изменения объектов A, B, C. Объект А зависит от С. Тогда, при сохранении в поток объекта A, через ссылки, сохранится и объект C. Это приведет к нарушению строгой очередности передачи объектов в соответствии с порядком изменений в логе. В таком случае, в момент формирования потока при сохранении объекта А, необходимо остановить процесс и информировать системного администратора.

Регистрация несущественных изменений

Триггеры регистрации в логе изменений не должны реагировать на изменение только значений технических полей (например, LB и RB для интервальных деревьев).

Изменение объекта и регистрация изменения на одной транзакции

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

Блокировка рекурсивных записей в логе

При переносе объекта с АБД необходимо предусмотреть механизм, чтобы в лог НБД не попадала запись о его изменении и не срабатывал механизм блокировки редактирования объектов на НБД.

Синхронизация генераторов при переносе изменений

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

Персональные инструменты
Пространства имён

Варианты
Действия
Навигация
Инструменты