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

Материал из GedeminWiki
(Различия между версиями)
Перейти к: навигация, поиск
(Состояния записи в логе ЦБД)
(Изменение объекта и регистрация изменения на одной транзакции)
 
(не показаны 46 промежуточных версий 1 участника)
Строка 1: Строка 1:
 
Рассмотрим вариант однонаправленной репликации между двумя базами A и B. Все изменения осуществляются на базе A. База B работает в режиме только для чтения. В дальнейшем, мы будем использовать термины "Удаленная база данных (УБД)" для базы А и "Центральная база данных (ЦБД)" для B.  
 
Рассмотрим вариант однонаправленной репликации между двумя базами A и B. Все изменения осуществляются на базе A. База B работает в режиме только для чтения. В дальнейшем, мы будем использовать термины "Удаленная база данных (УБД)" для базы А и "Центральная база данных (ЦБД)" для B.  
  
Базы обмениваются между собой сообщениями. Канал связи между базами может быть непостоянным. Т.е. база A может посылать сообщения в тот момент, когда база B недоступна и наоборот. Порядок выполнения действий над объектами на базе A должен сохраняться при переносе на базу B. Транспорт передачи сообщений не гарантирует нам ни сохранности и целости конкретного сообщения, ни сохранения порядка при передаче нескольких сообщений.
+
http://gsbelarus.com/gs/images/gs/2009/repl_ab_1.png
  
==== Состояния объекта в УБД ====
+
Базы обмениваются между собой сообщениями в асинхронном режиме, т.е. база A может посылать сообщения в тот момент, когда база B недоступна и наоборот. Порядок выполнения действий над объектами на базе A должен ''строго сохраняться'' при переносе на базу B. Транспорт передачи сообщений не гарантирует нам ни сохранности и целости конкретного сообщения, ни сохранения порядка при передаче нескольких сообщений.
  
Каждый объект в УБД находится в определенном состоянии. В таблице ниже перечислены возможные состояния, а также определены допустимые переходы из одного состояния в другое.
+
Ниже представлена концептуальная схема организации репликации. Нюансы конкретной реализации рассмотрены в главе "Особенности физической реализации" в конце статьи.
 +
 
 +
== Состояния объекта в УБД ==
 +
 
 +
Каждый объект в УБД находится в определенном состоянии. В таблице ниже перечислены возможные состояния, а также определены допустимые переходы из одного состояния в другое. Состояние объекта влияет на блокировку действий по его изменению или удалению.
  
 
{|border="1" cellpadding="2" cellspacing="0"
 
{|border="1" cellpadding="2" cellspacing="0"
Строка 32: Строка 36:
 
  |Объект был отослан на ЦБД.  
 
  |Объект был отослан на ЦБД.  
 
  |Аналогично состоянию L.
 
  |Аналогично состоянию L.
  |C, F
+
  |C
 
  |-
 
  |-
 
  |C  
 
  |C  
Строка 38: Строка 42:
 
  |Нет
 
  |Нет
 
  |L
 
  |L
 +
|}
 +
 +
== Состояния объекта в ЦБД ==
 +
 +
Поскольку данные передаются только в одном направлении, для объектов в ЦБД мы выделяем только три состояния.
 +
 +
{|border="1" cellpadding="2" cellspacing="0"
 +
|+
 +
!Состояние
 +
!Описание
 +
!Переход
 +
|-
 +
|I
 +
|Объект существовал до настройки схемы репликации.
 +
|R
 +
|-
 +
|R
 +
|Объект получен и записан в базу данных.
 +
|
 
  |-
 
  |-
  |F  
+
  |F
  |Изменение объекта не может быть записано в ЦБД. Необходимо срочное вмешательство системного администратораи ручная синхронизация данных УБД и ЦБД.  
+
  |Объект получен, но не может быть записан в базу данных. Необходимо срочное вмешательство системного администратора для ручного разрешения конфликта данных.
  |Объект остается в заблокированном состоянии.
+
  |R
|L, С
+
 
  |}
 
  |}
  
==== Лог изменений ====
+
== Лог изменений ==
  
Фиксирование изменений осуществляется в логе, который заполняется триггерами и содержит:  
+
Фиксирование изменений состояния объекта осуществляется в логе, который заполняется триггерами и содержит:  
  
 
* целочисленный порядковый номер изменения (начиная с единицы),
 
* целочисленный порядковый номер изменения (начиная с единицы),
Строка 53: Строка 75:
 
* тип объекта,
 
* тип объекта,
 
* вид операции (создание, изменение, удаление),  
 
* вид операции (создание, изменение, удаление),  
* состояние записи лога.
+
* состояние объекта,
 +
* дата и время изменения состояния.
  
В дальнейшем, числом М мы будем обозначать максимальный номер записи в логе. М принимается равным нулю, если лог пуст.
+
В дальнейшем, символом N мы будем обозначать номер изменения, а символом М -- максимальный номер изменения в логе. М принимается равным нулю, если лог пуст.
  
==== Состояние базы данных ====
+
== Состояние базы данных ==
  
Мы будем называть целое число S состоянием базы данных. Если S = М, значит все изменения переданы на ЦБД. Если S < M, -- необходимо осуществить передачу. Ситуация, когда S > M означает серьезный сбой в данных репликации, нарушение логической целостности.
+
Мы будем называть целое число S состоянием базы данных. Если S = М, значит все изменения переданы (для УБД) или все изменения приняты и успешно записаны в базу (для ЦБД). Если S < M, -- необходимо осуществить передачу. Ситуация, когда S > M означает серьезный сбой в данных репликации, нарушение логической целостности.
  
 
В начальный момент времени:  
 
В начальный момент времени:  
Строка 65: Строка 88:
 
   S = M = 0
 
   S = M = 0
  
Базы данных А и B находятся в идентичном состоянии, если S<sub>a</sub> = S<sub>b</sub> и очередь сообщений пуста. Поскольку просто физическое отсутствие сообщений в очереди не означает того, что их там не было. То, говорить об идентичности баз мы можем только после того, как ЦБД послала "Запрос состояния УБД" и получила на него ответ.
+
Базы данных А и B находятся в идентичном состоянии, если M<sub>a</sub> = S<sub>a</sub> = S<sub>b</sub>.
  
Состояние базы данных увеличивается на единицу каждый раз, когда подтверждается передача очередного объекта. Фактически, состояние базы данных равно максимальному номеру записи в логе в состоянии C (Confirmed).
+
Состояние УБД увеличивается на единицу каждый раз, когда подтверждается передача очередного объекта. S<sub>a</sub> равно максимальному номеру записи в логе в состоянии C.
  
В начальный момент времени базы данных находятся в идентичном состоянии, т.е. выполняется:  
+
Состояние ЦБД увеличивается на единицу каждый раз, когда успешно принимается и записывается в базу очередной объект. S<sub>b</sub> равно максимальному номеру записи в логе в состоянии R.
 +
 
 +
В начальный момент времени базы данных находятся в идентичном состоянии и выполняется равенство:  
 
    
 
    
 
   S<sub>a</sub> = S<sub>b</sub> = М<sub>a</sub> = М<sub>b</sub> = 0
 
   S<sub>a</sub> = S<sub>b</sub> = М<sub>a</sub> = М<sub>b</sub> = 0
  
==== Связь в асинхронном режиме ====
+
== Связь в асинхронном режиме ==
  
В том случае, если при обмене данными между УБД и ЦБД нет постоянного канала связи, мы будем следующие параметры:
+
В том случае, если при обмене данными между УБД и ЦБД нет постоянного канала связи, мы будем использовать следующие параметры:
 
   T<sub>r</sub> -- Допустимое время ожидания ответа на посланное сообщение.
 
   T<sub>r</sub> -- Допустимое время ожидания ответа на посланное сообщение.
   T<sub>s</sub> -- Время простоя системы с момента обработки последнего сообщения до отсылки запроса о состоянии УБД.
+
   T<sub>s</sub> -- Время простоя ЦБД с момента обработки последнего сообщения до отсылки запроса о состоянии УБД.
 +
  T<sub>i</sub> -- Период с которым УБД осуществляет проверку очереди сообщений и отсылку изменений на ЦБД.
 +
 
 +
== Критерий идентичности УБД и ЦБД в асинхронном режиме ==
 +
 
 +
УБД знает о том, что она идентична ЦБД, если S<sub>a</sub>=M<sub>a</sub>. Т.е. нет объектов в состоянии L, B или S.
 +
 
 +
ЦБД знает о том, что она идентичная УБД, если получено сообщение '''"Состояние УБД"''' (ответ на сообщение '''"Запрос состояния УБД"''') из которого следует что M<sub>a</sub>=S<sub>b</sub>.
 +
 
 +
=== Запрос состояния УБД ===
 +
 
 +
Когда база B хочет узнать текущее состояние синхронизации с базой А, она посылает специальное сообщение '''"Запрос состояния УБД"''' и фиксирует время его отправки. Получив данное сообщение, база А действует в соответствии со своим логом. Если он содержит записи, подлежащие отправке, то формируются и посылаются соответствующие сообщения. Непосредственного ответа на '''"Запрос состояния УБД"''' в этом случае не отсылается. Если лог не содержит записей для отправки, то формируется специальное сообщение '''"Состояние УБД"''', которым передается число M<sub>a</sub>. После отсылки запроса База B периодически проверяет свою очередь сообщений. Если в течение заданного тайм-аута в очередь не поступило ни одного ответа от базы А, то системный администратор оповещается о возможном нарушении канала связи или неполадках на УБД. Если поступил ответ '''"Состояние УБД"''', то M<sub>a</sub> сверяется с S<sub>b</sub>. При их равенстве базы данных считаются идентичными (синхронизированными). Если M<sub>a</sub> > S<sub>b</sub>, то база B отсылает сообщение '''"Запрос на передачу объекта"''' с указанием номера S<sub>b</sub> + 1. Состояние, когда M<sub>a</sub> < S<sub>b</sub>, свидетельствует о серьезной рассинхронизации двух баз данных и требует немедленного информирования системного администратора.
 +
 
 +
'''"Запрос состояния УБД"''' отсылается автоматически по истечении заданного интервала времени с момента обработки последнего сообщения от УБД или с момента отправки предыдущего запроса на состояние, на который не поступило ответа.
  
==== Журнал репликации ====
+
== Журнал репликации ==
  
Журнал используется системным администратором для выявления проблем в репликации данных. В журнал заносятся:
+
Журнал используется системным администратором для выявления проблем и/или профилирования репликации. В журнал заносятся:
 +
* Информативные сообщения
 
* Предупреждения
 
* Предупреждения
 
* Критические ошибки
 
* Критические ошибки
  
==== Последовательность обмена сообщениями ====
+
== Последовательность обмена сообщениями ==
  
 
Последовательность обмена сообщениями между исходной и конечной базами данных выглядит следующим образом:
 
Последовательность обмена сообщениями между исходной и конечной базами данных выглядит следующим образом:
  
===== База А =====
+
=== База А ===
  
 
Проверяется очередь сообщений:
 
Проверяется очередь сообщений:
 
# Очередь сообщений пуста:
 
# Очередь сообщений пуста:
## Если есть записи в состоянии S и с момента отправки самой первой из них прошло времени больше чем T<sub>r</sub>, то ставим в известность системного администратора, а на ЦБД отсылаем сообщение '''"Запрос подтверждения передачи объекта"'''. В сообщении указываем идентификатор объекта.
+
## Для объектов в состоянии S, с момента отправки которых прошло времени больше чем T<sub>r</sub>, на ЦБД отсылаем сообщение '''"Запрос подтверждения передачи объекта"''' с указанием идентификаторов объектов. Одновременно в журнале отражаем факт превышения времени ожидания ответа на сообщение '''"Передача объекта"'''.
## Проверяется лог на наличие записей в состоянии L. Для каждой такой записи формируется и посылается отдельное сообщение '''"Передача объекта"'''. После формирования и успешной отправки сообщения, запись в логе переводится в состояние S (Sent).
+
## Для каждого объекта в состоянии L формируется и посылается отдельное сообщение '''"Передача объекта"'''. После формирования и успешной отправки сообщения, запись в логе переводится в состояние S.
# Если в очереди присутствуют сообщения, группируем их по типу и сортируем внутри группы по порядковому номеру. Обрабатываем последовательно по типам сообщений:
+
# Если в очереди присутствуют только сообщения типа '''"Запрос состояния УБД"''', отвечаем сообщением '''"Состояние УБД"''' и очищаем очередь.
## "Подтверждение передачи объекта":
+
# Если в очереди присутствуют сообщения, сортируем их по порядковому номеру. В процессе сортировки удаляем сообщения типа '''"Запрос состояния УБД"'''. Обрабатываем последовательно:
### Если номер из сообщения '''соответствует''' номеру первого объекта со статусом S, то переводим объект в состояние C. Продолжаем обрабатывать список сообщений.
+
## '''"Подтверждение передачи объекта"''':
### Если номер из сообщения '''меньше''' номера первого объекта со статусом S, то игнорируем такое сообщение. Продолжаем обрабатывать список сообщений. Может информировать сисадмина?
+
### Если номер изменения из сообщения '''соответствует''' номеру первого объекта со статусом S (в порядке очередности записей в логе), то переводим объект в состояние C. Удаляем сообщение из очереди и продолжаем обрабатывать список.
### Если номер из сообщения больше номера первого объекта со статусом S, прекращаем дальнейшую обработку сообщений "Подтверждение передачи объекта". Отсылаем на сервер сообщение '''"Запрос подтверждения передачи объекта"'''. Может выждать время?
+
### Если номер из сообщения '''меньше''' номера первого объекта со статусом S, то игнорируем такое сообщение. Удаляем сообщение из очереди и продолжаем обрабатывать список. Заносим в журнал информацию о получении лишнего подтверждения.
## "Запрос на передачу объекта".
+
### Если номер из сообщения '''больше''' номера первого объекта со статусом S:
### Если запрашиваемый объкт находится в состоянии S, то передаем его на ЦБД.
+
#### Еще не истек допустимый интервал времени с момента отправки первого объекта в состоянии S. Сообщение из очереди не удаляем. Продолжаем обрабатывать список, пропуская все последующие сообщения типа '''"Подтверждение передачи объекта"'''.
### Если запрашиваемый объкт находится в состоянии L или C, или вообще отсутствует в списке, то игнорируем сообщение, а системного администратора информируем о ситуации.
+
#### Истекло время, отпущенное ЦБД на ответ. Отсылаем на сервер сообщение '''"Запрос подтверждения передачи объекта"''' с указанием идентификаторов всех объектов, для которых с момента отправки прошло времени больше чем T<sub>r</sub>. Сообщение из очереди не удаляем. Продолжаем обрабатывать список, пропуская все сообщения типа '''"Подтверждение передачи объекта"'''. Помещаем информацию о недошедшем подтверждении в журнал.
## "Запрос состояния УБД".
+
## '''"Запрос на передачу объекта"''':
 +
### Если запрашиваемый объект находится в состоянии S, то передаем его на ЦБД. Удаляем сообщение из очереди и продолжаем обрабатывать список. Помещаем в журнал информацию о повторной передаче объекта.
 +
### Если запрашиваемый объект находится в состоянии L или C, или вообще отсутствует в списке, то игнорируем сообщение и удаляем его из очереди, а в журнал помещаем запись с информацией о запросе на передачу ранее переданного и подтвержденного объекта.
  
===== База B =====
+
=== База B ===
 +
 
 +
Если в логе ЦБД присутствует запись в состоянии F, т.е. была ошибка при загрузке объекта, то репликация останавливается. Обработка очереди сообщений не производится.
  
 
Проверяется наличие сообщений в очереди.
 
Проверяется наличие сообщений в очереди.
Строка 113: Строка 156:
 
### Интервал времени истек. Информируем системного администратора. Повторяем '''"Запрос состояния УБД"'''.
 
### Интервал времени истек. Информируем системного администратора. Повторяем '''"Запрос состояния УБД"'''.
 
## Если истек интервал проверки связи и состояния УБД, то отсылаем '''"Запрос состояния УБД"'''.
 
## Если истек интервал проверки связи и состояния УБД, то отсылаем '''"Запрос состояния УБД"'''.
# Очередь не пуста:
+
# Очередь содержит только сообщения типа '''"Состояние УБД"'''. Берем последнее из них в хронологическом порядке:
## ...
+
## Если M<sub>a</sub> = S<sub>b</sub>, базы в идентичном состоянии. Очищаем очередь сообщений.
+
## Если M<sub>a</sub> > S<sub>b</sub>, есть объекты к передаче с УБД на ЦБД. Отсылаем запрос на передачу объекта. Очищаем очередь сообщений.
# Если он соответствует ожидаемому, то происходит считывание и обработка сообщения.
+
## Если M<sub>a</sub> < S<sub>b</sub>, серьезный сбой. Информируем системного администратора.
# Если номер первого сообщения в очереди меньше ожидаемого, то просто игнорируем его (удаляем).
+
# Очередь не пуста.
# Если номер первого сообщения в очереди больше ожидаемого, то посылаем запрос на пересылку сообщений с нужными номерами. Останавливаем дальнейшую обработку очереди. Ждем ответа от исходной базы.
+
## Сортируем сообщения в порядке номеров изменений. Выкидываем все сообщения '''"Состояние УБД"'''. Обрабатываем в порядке очередности.
# ...
+
### Если номер изменения первого сообщения в очереди равен S<sub>b</sub> + 1, то загружаем объект. Удаляем текущее сообщение и продолжаем обрабатывать очередь.
 +
### Если номер изменения первого сообщения в очереди меньше S<sub>b</sub> + 1, то игнорируем такое сообщение. Удаляем его и продолжаем обрабатывать очередь. В журнал помещаем запись о несанкционированной повторной передаче уже принятого объекта.
 +
### Если номер изменения первого сообщения в очереди больше S<sub>b</sub> + 1, то прекращаем обработку очереди. Текущее сообщение не удаляем. На УБД отсылаем сообщение '''"Запрос на передачу объекта"''', где указываем диапазон изменений, которые нас интересуют: с S<sub>b</sub> до номера изменения первого сообщения в очереди, не включая границы.
 +
## По окончании обработки очереди (не важно, полной или частичной), отсылаем на УБД сообщение '''"Подтверждение передачи объектов"''' с указанием номеров изменений, успешно записанных в ЦБД.
 +
## При возникновении конфликта записи объекта в ЦБД останавливаем обработку очереди. В лог ЦБД заносим пометку номера изменения и ставим ему статус F. Информируем системного администратор о серьезном сбое репликации.
  
===== Запрос состояния УБД =====
+
== Структура сообщения ==
  
Когда база B хочет узнать текущее состояние синхронизации с базой А, она посылает специальное сообщение '''"Запрос состояния УБД"''' и фиксирует время его отправки. Получив данное сообщение, база А действует в соответствии со своим логом. Если он содержит записи, подлежащие отправке, то формируются и посылаются соответствующие сообщения. Непосредственного ответа на '''"Запрос состояния УБД"''' в этом случае не отсылается. Если лог не содержит записей для отправки, то формируется специальное сообщение '''"Состояние УБД"''', которым передается число S<sub>a</sub>. После отсылки запроса База B периодически проверяет свою очередь сообщений. Если в течение заданного тайм-аута в очередь не поступило ни одного ответа от базы А, то системный администратор оповещается о возможном нарушении канала связи или неполадках на УБД. Если поступил ответ '''"Состояние УБД"''', то S<sub>a</sub> сверяется с S<sub>b</sub>. При их равенстве базы данных считаются идентичными (синхронизированными). Если S<sub>a</sub> > S<sub>b</sub>, то база B отсылает сообщение '''"Запрос на передачу объекта"''' с указанием номера S<sub>b</sub> + 1. Состояние, когда S<sub>a</sub> < S<sub>b</sub>, свидетельствует о серьезной рассинхронизации двух баз данных и требует немедленного информирования системного администратора.
+
Каждое сообщение содержит постоянную часть (заголовок) и данные, которые зависят от типа сообщения:
  
'''"Запрос состояния УБД"''' отсылается автоматически по истечении заданного интервала времени с момента обработки последнего сообщения от УБД или с момента отправки предыдущего запроса на состояние, на который не поступило ответа.
+
* Заголовок
 +
** Тип сообщения
 +
** Дата и время отправки
 +
** Отправитель
 +
** Получатель
 +
** Контрольная сумма
 +
* Данные, в зависимости от типа сообщения. Для сообщений некоторых типов данные могут отсутствовать:
 +
** '''"Передача объекта"'''
 +
*** Номер изменения в логе.
 +
*** Поток данных объекта.
 +
** '''"Запрос подтверждения передачи объекта"'''
 +
*** Диапазон номеров изменений в логе.
 +
** '''"Состояние УБД"'''
 +
*** Число M<sub>a</sub>.
 +
** '''"Запрос состояния УБД"'''
 +
*** Нет данных.
 +
** '''"Подтверждение передачи объекта"'''
 +
*** Диапазон номеров изменений в логе.
 +
** '''"Запрос на передачу объекта"'''
 +
*** Диапазон от S<sub>b</sub> + 1 до наименьшего номера изменения, переданного в сообщении "Передача объекта".
  
 +
Контрольная сумма используется для проверки корректности всех данных сообщения, включая и заголовок.
  
 +
== Особенности физической реализации ==
  
 +
=== Очередность сохранения объектов и формирование потока ===
  
 +
Механизм сохранения в поток платформы Гедымин рекурсивно обходит все ссылки, от которых зависит сохраняемый объект. Возможна ситуация, когда в логе будут находиться последовательно изменения объектов A, B, C. Объект А зависит от С. Тогда, при сохранении в поток объекта A, через ссылки, сохранится и объект C. Это приведет к нарушению строгой очередности передачи объектов в соответствии с порядком изменений в логе. В таком случае, в момент формирования потока при сохранении объекта А, необходимо остановить процесс и информировать системного администратора.
  
=== Структура сообщения ===
+
=== Регистрация несущественных изменений ===
  
{|border="1" cellpadding="2" cellspacing="0" width="780px"
+
Триггеры регистрации в логе изменений не должны реагировать на изменение только значений технических полей (например, LB и RB для интервальных деревьев).
|+
+
 
!Поле
+
=== Изменение объекта и регистрация изменения на одной транзакции ===
!Описание
+
 
|-
+
Во избежание рассинхронизации реального состояния объекта с информацией в логе, изменение объекта и регистрация в логе его нового состояния должны происходить на одной транзакции.
|Контрольная сумма
+
|Хэш код MD5, который позволяет контролировать целостность полученного сообщения. Рассчитывается по всему потоку данных, включая и заголовок.
+
|-
+
|Идентификатор УБД
+
|
+
|-
+
|Идентификатор ЦБД
+
|
+
|-
+
|Номер записи в логе
+
|
+
|-
+
|Данные
+
|
+
|}
+
  
 +
= Ссылки по теме =
  
 +
[http://delicious.com/goldensoftware/replication Ссылки по теме "Репликация баз данных".]
  
 
[[Category:Постановка]]
 
[[Category:Постановка]]

Текущая версия на 17:26, 20 сентября 2009

Рассмотрим вариант однонаправленной репликации между двумя базами A и B. Все изменения осуществляются на базе A. База B работает в режиме только для чтения. В дальнейшем, мы будем использовать термины "Удаленная база данных (УБД)" для базы А и "Центральная база данных (ЦБД)" для B.

repl_ab_1.png

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

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

[править] Состояния объекта в УБД

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

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

[править] Состояния объекта в ЦБД

Поскольку данные передаются только в одном направлении, для объектов в ЦБД мы выделяем только три состояния.

Состояние Описание Переход
I Объект существовал до настройки схемы репликации. R
R Объект получен и записан в базу данных.
F Объект получен, но не может быть записан в базу данных. Необходимо срочное вмешательство системного администратора для ручного разрешения конфликта данных. R

[править] Лог изменений

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

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

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

[править] Состояние базы данных

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

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

 S = M = 0

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

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

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

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

 Sa = Sb = Мa = Мb = 0

[править] Связь в асинхронном режиме

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

 Tr -- Допустимое время ожидания ответа на посланное сообщение.
 Ts -- Время простоя ЦБД с момента обработки последнего сообщения до отсылки запроса о состоянии УБД.
 Ti -- Период с которым УБД осуществляет проверку очереди сообщений и отсылку изменений на ЦБД.

[править] Критерий идентичности УБД и ЦБД в асинхронном режиме

УБД знает о том, что она идентична ЦБД, если Sa=Ma. Т.е. нет объектов в состоянии L, B или S.

ЦБД знает о том, что она идентичная УБД, если получено сообщение "Состояние УБД" (ответ на сообщение "Запрос состояния УБД") из которого следует что Ma=Sb.

[править] Запрос состояния УБД

Когда база B хочет узнать текущее состояние синхронизации с базой А, она посылает специальное сообщение "Запрос состояния УБД" и фиксирует время его отправки. Получив данное сообщение, база А действует в соответствии со своим логом. Если он содержит записи, подлежащие отправке, то формируются и посылаются соответствующие сообщения. Непосредственного ответа на "Запрос состояния УБД" в этом случае не отсылается. Если лог не содержит записей для отправки, то формируется специальное сообщение "Состояние УБД", которым передается число Ma. После отсылки запроса База B периодически проверяет свою очередь сообщений. Если в течение заданного тайм-аута в очередь не поступило ни одного ответа от базы А, то системный администратор оповещается о возможном нарушении канала связи или неполадках на УБД. Если поступил ответ "Состояние УБД", то Ma сверяется с Sb. При их равенстве базы данных считаются идентичными (синхронизированными). Если Ma > Sb, то база B отсылает сообщение "Запрос на передачу объекта" с указанием номера Sb + 1. Состояние, когда Ma < Sb, свидетельствует о серьезной рассинхронизации двух баз данных и требует немедленного информирования системного администратора.

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

[править] Журнал репликации

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

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

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

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

[править] База А

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

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

[править] База B

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

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

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

[править] Структура сообщения

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

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

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

[править] Особенности физической реализации

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

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

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

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

[править] Изменение объекта и регистрация изменения на одной транзакции

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

[править] Ссылки по теме

Ссылки по теме "Репликация баз данных".

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

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