Репликация - разрешение конфликтов.

Padonak_Sem
Дата: 05.12.2007 20:08:44
Имеем несколько серверов Oracle 10g. Между ними - репликация, самодельная система.
Устроена так:

1. Стоят триггеры на всех таблицах, они пишут все изменения в таблицу очереди отправки
2. С помощью джобов очередь с каждого сервера пересылается на "центральный" сервер, который рассылает ее на все остальные сервера (щас - 4 штуки, дальше будет больше), в очередь приема
3. На каждом сервере обрабатывается очередь приема - строятся и выполняются запросы.

В принципе на таблицах, в которых происходит мало изменений - работает как надо. Но на таблицах, в которых проходит много изменений, и которые как раз самые важные - возникают конфликты такого рода:

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

2. При одновременной вставке одинаковых записей. По первичному ключу-то они не пересекаются, а вот по какому-то из уникальных - запросто. Тут более-менее понятно, что можно удалять старую запись и заменять ее новой. Но проблема в том, что на такую запись может быть несколько порожденных по foreign key записей, и что делать с ними уже непонятно.

Надеюсь, я понятно описал проблемы. Многоуважаемые гуру! Какие у вас могут быть рекомендации по устранению данных проблем? Полностью исключить возможность одновременной вставки или обновленя практически невозможно, но идентичность данных нужно обеспечивать.
softwarer
Дата: 05.12.2007 20:17:02
Padonak_Sem
Имеем несколько серверов Oracle 10g. Между ними - репликация, самодельная система.

Нет бы взять у меня готовую, точно описанного вида :)

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

Хреново. Когда едет изменение - ехать должно изменение (то есть только новое значение измененного поля). Соответственно, если на одном сервере поменяли одно поле записи, на сервере Б - другое, никакого конфликта не будет, спокойно пройдут оба изменения.

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

Padonak_Sem
2. При одновременной вставке одинаковых записей. По первичному ключу-то они не пересекаются, а вот по какому-то из уникальных - запросто.

В топку. Решалось очень просто: на удаленных серверах не вставлялась "одинаковая запись". Вместо этого на них создавалось "задание" вставить запись. Задание реплицировалось на центральный сервер и там исполнялось. Соответственно, одно из заданий падало с ошибкой, дублей в БД не возникало.
UDW
Дата: 05.12.2007 20:18:45
А чем не устроила Advanced Replication?
Там все это прописано и реализовано.
andrey_anonymous
Дата: 05.12.2007 20:34:32
UDW
А чем не устроила Advanced Replication?

В мануале многабукф, да и традиции шапкозакидательства никто не отменял...
UDW
Дата: 05.12.2007 20:39:09
Весь мануал читать не обязательно.
А дублирование встроенных решений - это даже не смешно.
В АР есть 3 вида репликации мультимастер, снапшот и комбинированный...
Все построено на отложенных транзакциях...
Юзаю уже лет 9 - все логично, все работает...
Padonak_Sem
Дата: 06.12.2007 12:22:01
Нет бы взять у меня готовую, точно описанного вида :)


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

Хреново. Когда едет изменение - ехать должно изменение (то есть только новое значение измененного поля). Соответственно, если на одном сервере поменяли одно поле записи, на сервере Б - другое, никакого конфликта не будет, спокойно пройдут оба изменения.

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


Как раз таки едут ТОЛЬКО изменения. Но есть такие поля, которые изменяются автоматически и всегда (дата редакции, юзер, который эту редакцию провел, и т.д.)


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


ПРоблемы в разруливании конфликта одиночной таблицы нет. ПРоблема, если он возникает в нескольких связанных по Foreign Key таблицах.


А чем не устроила Advanced Replication?
Там все это прописано и реализовано.


Хотя бы тем, что так и не удалось ее испытать. Все МАНы которые я видел описывают настройку через ГУИ Enterprise Managerа. У меня Ora10g, и чтоб настроить этот Advanced Replication скриптами я никакой доки не нашел.
Буду благодарен за какую либо помощь в этом деле. И еще - нормально ли оно работает в случае, если канал пролежит 2 дня? Вроде как говорили, что есть с этим проблемы





автор
В мануале многабукф, да и традиции шапкозакидательства никто не отменял...


Ваш ответ, сЭЭр, несомненно, очень ценный, и он здорово мне помог!
З.Ы. Нечего написать по теме - не пиши. Срать иди или на www.udaff.com или на http://lleo.aha.ru/na/

автор

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


Снапшот не устраивает 100%. А можно ли реализовать такую схему:

Сервер 1<----> Центральный сервер <-----> Сервер 2
|
Сервер 3

Т.е. сервер 1, 2, 3 не знают друг о друге и передают информацию только на центральный сервер, а уж центральный раздает всем.

Проблема в том, что серверов планируется много, и связь с некоторыми - по каналам с ограничением по трафику (ну нету другой возможности, кроме как оптику кидать). ПОэтому пересылать данные вместо 1 сервера на 5 - в 5 раз увеличение трафика. А данных ходит много.
softwarer
Дата: 06.12.2007 13:03:05
Padonak_Sem
Какую например? Streams пробовал, фигня редкая, на нестабильных каналах не работает вообще.

Ту, которую я писал именно для такого случая. Нижняя испытанная граница - работа через модемы 9600 (телефонная лапша и модемы с зажатой скоростью - иначе вообще никакого коннекта). Реально подававшаяся нагрузка - до миллиона реплик в сутки (разумеется, на модемные сервера ехало куда меньше...) Максимальная дистанция между серверами - четыре хопа (дополнительный сервер филиала - основной сервер филиала - центральный роутер - основной сервер другого филиала - дополнительный сервер другого филиала). Время путешествия записи по этой дистанции - понятно, зависит от настроек и состояния каналов; если все нормально, то при расписании заданий "раз в минуту" выходило 10-15 минут.

Padonak_Sem
Как раз таки едут ТОЛЬКО изменения. Но есть такие поля, которые изменяются автоматически и всегда (дата редакции, юзер, который эту редакцию провел, и т.д.)

Тогда в первую очередь стоит придумать бизнес-правило: что же, собственно, в этом случае должно происходить. Мне такую задачу решать не приходилось; сходу - я бы, наверное, во-первых, слал бы вместе с репликой какую-нибудь контрольную сумму "записи которая должна получиться", а во-вторых, обнаружив расхождение (то есть коллизию) запускал бы логику, которая формировала бы согласованную запись (для таких мест в настройках я делал гнезда для PL/SQL кода - чтобы настраивать по месту). Например, в этом случае логика могла бы опираться на дату последнего изменения - чья позже, тот и выиграл. Может быть, также, я сделал бы так, чтобы "согласованная" запись рассылалась с центрального сервера на прочие (гарантируя таким образом, что везде получится одинаково).

Padonak_Sem
ПРоблемы в разруливании конфликта одиночной таблицы нет. ПРоблема, если он возникает в нескольких связанных по Foreign Key таблицах.

В описанной схеме конфликта не может возникнуть, поскольку все изменения делаются на одном сервере.
UDW
Дата: 06.12.2007 13:10:27
Странно...
Обычно в оракловой доке все скриптами объясняется...
Ну ежели в 10-ке все через GUI, то можно доку и от 9-ки почитать, разницы не заметите...
Padonak_Sem
Дата: 06.12.2007 13:42:31
softwarer, насколько я слышал - вы свою систему продаете. Можете дать ее полное описание, и сколько вы за нее хотите?
softwarer
Дата: 06.12.2007 14:15:43
Не совсем так. Стучитесь ко мне в аську 165703937, расскажу ситуацию.