Синхронизация баз данных Oracle

 
0
 
Oracle
ava
guest | 27.10.2004, 11:57
Не подскажете ли, господа?

Где можно в Internet найти литературу по синхронизации баз данных.
Про синхронизацию двух баз Oracle.
Про осуществление гарантированной закачки в базу данных от удалённого клиента.

Спасибо.
Comments (34)
ava
Dimich | 27.10.2004, 12:03 #
Я понял так, что Вас интересуют репликации? Могу порекомендовать http://www.sql.ru
ava
LSD | 27.10.2004, 19:14 #
По поводу репликации данных в первую очередь надо почитать справку по Oracle, там все достаточно хорошо описанно. Можно запустить Enterprise Management Console, там все операции по настрйке репликации делаются достаточно легко, и при желании можно записать скрипты, а затем их модифицировать.
ava
Dimich | 28.10.2004, 08:26 #
Если по правде, то я никогда сам не пользовался Ораклевыми репликациями как таковыми по той причине, что когда я начинал это делать у меня небыло достаточных навыков в этом деле. Сейчас я немного разобрался, как это делается, но у меня прекрасно работает свой ранее сделанный механизм. Опишу его работу:
У нас имеется 12 серверов, причем один - центральный, он и есть ведущий. Полной синхронизации серверов не требуется. Нужно, чтобы одинаковыми были только таблицы справочников (адреса, услуги, тарифы и прочие таблицы с условно-постоянной информацией). Над этими табличками на центральном сервере висят триггеры на Insert, Update и Delete, которые и отслеживают изменения и делают запись в отдельную табличку "искусственных репликаций", куда попадают:
1. номер "репликации"
2. имя таблички, над которой происходили изменения;
3. Дата
4. имя пользователя
5. Тип изменений (Ins or Del or Upd)
6. имя колонки таблицы
7. Данные (Old / New)
Далее данные из этих табличек выгружаются в файлы, рассылаются на все участки (ведомые сервера), где они закачиваются на сервер и запускается хранимая процедура, которая:
1. Разворачивает данные табличек в понятные SQL команды
2. Выполняет эти SQL команды как DML операции
3. Записывается статус выполнения команды (успешно или ошибка)
Далее данные о статусе выполнения "репликации" (каждой отдельной ее SQL команды) выгружаются в файл, который отсылается на центральный участок (ведущий сервер) и закачивается в БД. Это нужно для того, чтобы следить, где и как что выполнилось. Если ошибка - надо разрулить ее вручную (но это было на начальном этапе, когда все только устаканивалось, сейчас это работает без сбоев с апреля месяца). Итак, если репликация на ведомом сервере выполнилась, то все Ok и ее больше не трогаем (для данного сервера), иначе отсылаем ее опять (мало ли что, вдруг письмо не дошло?) и так пока не узнаем Ok или Error

Буду благодарен за критику.
ava
LSD | 28.10.2004, 19:16 #
Dimich
Вообщем ты повторил систему репликации Oracle smile . Один master и несколько snapshoot-ов.
ava
Petro123 | 28.06.2007, 12:23 #
Цитата


выгружаются в файлы, рассылаются на все участки (ведомые сервера), где они закачиваются на сервер и запускается хранимая процедура,


Простите, а зачем выгружать даные в файл, разве нельзя непосредственно обратиться к нужным данным и залить их в новую базу? Кажется есть ведь гомогенные запросы?

added later:
Да кстати не подскажите, как создать файл и отослать его вдруг понадобится?
ava
Dimich | 29.06.2007, 11:30 #
Цитата (Petro123 @ 28.6.2007, 12:23 findReferencedText)
Простите, а зачем выгружать даные в файл, разве нельзя непосредственно обратиться к нужным данным и залить их в новую базу? Кажется есть ведь гомогенные запросы?

Да, можно и так. Так гораздо лучше, но у меня дело осложняется тем, что каналы связи просто никакие. В лучшем случае dialup, где модем висит параллельно общему телефону, в гудшем случае gprs, которое вообще может неделю не работать и тогда приходится файлы на флешке с попутным междугородним автобусом передавать, все-таки межгород.

Файл создаю не из pl/sql. Этим занимается специальная клиентская программа, которая к тому же обрабатывает входящие/исходящие письма с этими самыми файлами.
ava
Petro123 | 29.06.2007, 11:58 #
А что за файлы, типизированные или текстовые?
ava
Dimich | 02.07.2007, 15:19 #
Типизированные. Такого примерно формата:
Поле
Тип данных
Размер данных
Собственно данные

Потом эти файлы еще архиватором упаковываются и режутся на тома.

Очевидные недостатки: ограниченность поддерживаемых типов данных (NUMBER, VARCHAR, DATE), хотя можно прикрутить (при желании) и другие типы, я за ненадобностью это не делал.

Но, если есть желание повторять, то лучше разобраться с нативными ораклевыви репликациями. Я такой изврат делал от безысходности. Причины описывал.
ava
Petro123 | 02.07.2007, 16:22 #
Не по чему разбираться пока, может есть какие ссылочки хорошие, русские.
А твой способ мне по душе
Создаем тригеры, журналы изменений таблиц, только файлы мне лень создавать, наверное гомогенными запросами можно слить будет инфу из одной базы в другую (кстати как тоже вопрос),
Теоретически все вроде понятно, но блин практически, возникает много вопросиков, безобидных, но требующих время. Все таки придется наверное пойти по твоему пути, он хотя бы прозрачен для меня...



ava
LSD | 02.07.2007, 18:48 #
Petro123 написание собственного велосипеда, процесс гораздо более долгий и сопряженный с бОльшим количеством ошибок, чем разбирательство по английской документации.
ava
Dimich | 03.07.2007, 06:44 #
Petro123, ну, если так заинтересовался, могу запостить пример триггера над таблицей, пример процедуры, которая все это хозяйство разворачивает в DML операции и выполняет их, ну и собственно структуру таблиц.

Кстати, если связь между БД хорошая, то можно данные из одной БД в другую гонять через dblink и не мучаться с файлами. Тогда у тебя воодще может не быть клиентских частей как у мну.

Но и к совету LSD я бы советовал тебе прислушаться. Этот человек всегда дело говорит.
ava
Sqlninja | 03.07.2007, 10:02 #
Цитата (LSD @ 27.10.2004, 19:14 findReferencedText)
Enterprise Management Console


Только не это, шеф! Максимум, на что годится эта консоль - это мониторинг ошибочных транзакций, и их состав. Но никому не советую ее использовать для управления объектами репликации.

Визарды, это вообще отдельная тема. Кажется, один раз я попробовал запустить какой-то мастер по созданию репликационной группы, в нем оказалость 6 нудных шагов, в итоге приведшие меня в никуда, ни окея, ни кансела. И это только маленький пример.

Так что устанавливаем пакет DBMS_REPCAT и да здравствует PL/SQL.

P.S. С каждым новым релизом Oracle, я все больше ненавижу индусов.
ava
LSD | 03.07.2007, 12:04 #
Цитата (Sqlninja @ 3.7.2007, 11:02 findReferencedText)
Только не это, шеф! Максимум, на что годится эта консоль - это мониторинг ошибочных транзакций, и их состав. Но никому не советую ее использовать для управления объектами репликации.



Визарды, это вообще отдельная тема. Кажется, один раз я попробовал запустить какой-то мастер по созданию репликационной группы, в нем оказалость 6 нудных шагов, в итоге приведшие меня в никуда, ни окея, ни кансела. И это только маленький пример.

Я настраивал репликацию именно им и все работало.
ava
Petro123 | 04.07.2007, 06:25 #
Цитата


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


Да, да конечно, буду очень признателен
ava
Dimich | 04.07.2007, 08:30 #
rout.pdc - таблица, принимающая имена таблиц, над которыми произошли изменения
routd.pdc - таблица, принимающая детализацию изменений
routsrv.pdc - таблица серверов, для которых предназначена данная репликация.
routins.trg - триггер, делающий запись в routsrv, при добавлении в rout на основании servers.outflag=1
servers.pdc - список серверов, участвующих в репликации

rin.pdc - "входящие" репликации от ведущего сервера
rind.pdc - детализация входящих репликаций
rt.pdc - статус входящий репликации. Нужен для того, чтобы подтвердить выполнение репликации на ведущем сервере,
после чего она больше не будет выгружаться на ведомый. Иначе, она должна выгружаться снова и снова, пока
не придет это подтверждение.

repl.prc - процедура, разворачивающая входящие репликации из таблиц rin и rind в DML и записывающая статус в rt
usl.pdc - скрипт для создания рабочей таблицы (справочник услуг), которая подлежит репликации
usl_rout.trg - триггер над таблицей usl, который фиксирует все измения таблицы в служебные таблицы ROUT, ROUTD

Кроме того, выполнять процедуру REPL разрешено только одному юзеру, 'repl'
и всем пользователям, кроме 'repl' запрещено менять справочники на ведомых серверах
и рабочие таблицы с реплицируемыми данными на ведущих. Это в моем случае определяется по ID строк,
которые уникальны для каждого сервера.

Вроде, все указал. Если есть вопросы - пишите, а они точно будут. Исходников клиентской шняги, которая принимает таблицы rout/routd и загружает в rin/rind, запускает хранимую REPL, а потом выгружает rt для подтверждения выполнения репликации я героически потерял. Но, думаю воспроизвести ее труда не составит.
ava
Petro123 | 04.07.2007, 09:21 #
Здорово, только я ненашел routins.trg, и самое главное repl.prc,...

added later:
а и еще, что это за servers.outflag=1
ava
Dimich | 04.07.2007, 09:33 #

>rar l 2007_07_04_Repl.rar

Архив 2007_07_04_Repl.rar

Имя Размер В архиве Сжатие Дата Время Атрибуты CRC Мет Вер
-------------------------------------------------------------------------------
usl.pdc 303 198 65% 04-07-07 08:27 .....A. 6F79D444 m3b 2.9
rout.pdc 569 286 50% 04-07-07 08:26 .....A. 3A229FB7 m3b 2.9
routd.pdc 372 227 61% 04-07-07 08:26 .....A. 51EF9A07 m3b 2.9
routsrv.pdc 483 300 62% 04-07-07 08:25 .....A. 4D67EBEC m3b 2.9
rin.pdc 649 300 46% 04-07-07 08:25 .....A. 8AA61C20 m3b 2.9
rt.pdc 134 113 84% 04-07-07 08:24 .....A. C358B48B m3b 2.9
rind.pdc 366 226 61% 04-07-07 08:24 .....A. 7C2402E3 m3b 2.9
USL_ROUT.trg 2815 883 31% 04-07-07 08:18 .....A. 6D00703B m3b 2.9
Repl.prc 8186 1921 23% 04-07-07 08:15 .....A. 1990DB9E m3b 2.9
repl.txt 1377 769 55% 04-07-07 09:18 .....A. D43A1179 m3b 2.9
-------------------------------------------------------------------------------
10 15254 5223 34%


А routins.trg я действительно забыл. Вот он:

create or replace trigger RoutIns
after insert on Rout
for each row
BEGIN
insert into routsrv (
select servid, :new.r_id, 0
from servers
where outflag = 1);
END RoutIns;
ava
Sqlninja | 04.07.2007, 09:34 #
Цитата (LSD @ 3.7.2007, 12:04 findReferencedText)
Я настраивал репликацию именно им и все работало.

значит версия была лучше
ava
Dimich | 04.07.2007, 09:39 #
Цитата (Petro123 @ 4.7.2007, 09:21 findReferencedText)
а и еще, что это за servers.outflag=1

Имелось ввиду значение поля outflag = 1 в таблице servers. Т.е. смысл в том, что для сервера, помеченного этим флагом генерируются репликации. Просто у меня много серверов и соответственно кому-то нужно синхронизировать одну часть данных, кому-то она вообще не нужна, даже таблиц таких нет. И для постепенного включения репликаций хорошо. Или если сбой где-то произошел, то выключить и разруливать потихоньку.
ava
Petro123 | 04.07.2007, 09:53 #
Понятно, вкл/выкл.

Как происходит обработка входящих репликаций, по идее она должна обрабатываться в виде очереди, Т.е. пока успешно не обработали одну репликацию не переходим к следующей. Так ли это?

added later:
Вроде как получается что за раз обрабатывается весь журнал, и если есть хотя бы одна ошибка делаем откат на начало журнала, или нет?
ava
Dimich | 04.07.2007, 10:16 #
Цитата (Petro123 @ 4.7.2007, 09:53 findReferencedText)
Как происходит обработка входящих репликаций, по идее она должна обрабатываться в виде очереди, Т.е. пока успешно не обработали одну репликацию не переходим к следующей. Так ли это?

Да, верно.
Данные из таблиц ROUT и ROUTD загружаются в таблицы RIN и RIND соответственно. После чего за выполнение репликаций отвечает хранимая REPL. Она то и выполняет все операции в порядке очереди. Очередь устанавливается последовательностью R_ID. Т.е. когда фиксируются репликации в таблицы (см. пример триггера над таблицей USL), R_ID будет определено последовательностью SEQR_ID. В этой же последовательности их и обработает потом хранимая REPL.
Кстати, вот она сама:
create sequence SEQR_ID
minvalue 10000000000000000
maxvalue 19999999999999999
start with 10000000000097698
increment by 1
cache 20
cycle;

На других серверах, как я уже говорил, значения первичных ключей не пересекаются, т.к. там тоже будут существовать такие последовательности, но уже с другим интервалом. Например:
create sequence SEQR_ID
minvalue 30000000000000000
maxvalue 39999999999999999
start with 30000196788501240
increment by 1
cache 20
cycle;

При возникновении ошибки в процедуру REPL, обработка прекращается до вмешательства человека. На начальном этапе это неизбежно будет (стадия отладки и тестирования). Теперь у меня это уже больше года работает нормально. Я и забыл, когда туда лазил. Вот сейчас пришлось вспоминать, как это работает.
ava
Petro123 | 04.07.2007, 12:03 #
Цитата


Данные из таблиц ROUT и ROUTD загружаются в таблицы RIN и RIND соответственно


Как загружаются данные в таблицы Rin, Ring?
Просто очищаем RIN, затем все строки заливаем из ROUT?

added later:
При такой схеме возникает некая избыточность данных. В обеих базах данные дублируются. Если реплицировать нужно справочники - проблем нет. А если таблицы в которые ежедневно добавляются сотни тысяч записей, как все это будет работать, корректно ли, быстро ли?
ava
Dimich | 04.07.2007, 14:35 #
Можно не очищать, просто дописывать.
Из RIN данные можно удалять только тогда, когда выполнятся все условия:
1. Репликация выполнена, т.е. Rin.rf = 0 (или существует запись в Rt)
2. Удаленный сервер знает, что репликация уже выполнена, иначе он должен снова ее выгрузить. Если память не изменяет, то это у мну routsrv.flag

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

Скорость, да несколько хромает. Обычно такие задачи у меня работают ночью. Синхронизируется 14 серверов с 1-м сервером. Средний поток изменений от одного сервера к другому - примерно 200,000..1,500,000 репликаций. За ночь успевает. Но бывает и больше, тогда может и к обеду следующего дня завершиться.

Насчет корректности: все работает корректно. Пока рассогласований небыло.

Имхо, мне самому не очень сейчас это нравится в плане быстродействия. Иногда хочется быстрее. Если время найду, я давно порывался это переделать, правда мысли пока еще не оформились окончательно. Может твоя критика и поможет мне.
ava
Petro123 | 04.07.2007, 15:16 #
Цитата


Можно не очищать, просто дописывать.


Опять репликация?
Как ты дописываешь?
ava
Petro123 | 04.07.2007, 15:49 #
Цитата


rt.pdc - статус входящий репликации.


Может быть лучше в таблицу Rout, добавить поле Статус репликации, 0 - не завершена, 1 - завершена?
Как думаешь?

Или у тебя в таблицу RT добавляются только те записи, репликация по которым прошла успешно, а затем при очистке журнала репликации, удаляются только те которые есть в RT?

ava
Dimich | 05.07.2007, 06:54 #
Цитата (Petro123 @ 4.7.2007, 15:16 findReferencedText)
Опять репликация?

Как ты дописываешь?

Не понял вопроса. Какие записи получил от удаленного сервера, те и дописываю. В таблицах есть primary key по R_ID (ID репликации), поэтому уже существующие, если такие оказались, будут отвергнуты в любом случае.
Более подробный алгоритм такой: читаю файл, делаю insert строки.
Можно к примеру SQL Loader прикрутить, если надо.

Цитата (Petro123 @ 4.7.2007, 15:49 findReferencedText)
Может быть лучше в таблицу Rout, добавить поле Статус репликации, 0 - не завершена, 1 - завершена?

Как думаешь?



Или у тебя в таблицу RT добавляются только те записи, репликация по которым прошла успешно, а затем при очистке журнала репликации, удаляются только те которые есть в RT?


Можно наверное и так сделать. Почему бы и нет. Будет экономия. Я уже и вспомнить не могу, чем я руководствовался, когда делал так.

Да, кстати, вспомнил еще: когда будешь обрабатывать дробные числа и даты, имей в виду, что скорее всего дробное число будет иметь не десятичную точку, а запятую. Это я сперва по глупости решил как Replace (',', '.', value). Но гораздо лучше использовать nls_numeric_characters

Также нужно обратить внимание на формат дат. При неверной настройке они имеют свойство записываться некрасиво. Это я решил, используя в тригерах форматирование при выводе дат: to_char(date, 'dd/mm/yyyy hh:mi:ss')
ava
Sqlninja | 05.07.2007, 11:41 #
имхо, вы все гоните. если б мои кодеры начали переписывать стандартную функциональность оракла, уволил бы всех нах.
ava
Dimich | 05.07.2007, 14:48 #
Цитата (Sqlninja @ 5.7.2007, 11:41 findReferencedText)
имхо, вы все гоните. если б мои кодеры начали переписывать стандартную функциональность оракла, уволил бы всех нах.

Гоним, не спорю.

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


Sqlninja, а вообще реально сделать dblink с базой, с которой нет связи? Ну, чтобы, можно было данные, например на дискете туда-сюда носить? Или как тогда можно запустить репликации (сети нет т.е., интернет есть, но не стабильный, т.е. может прерываться или каждые 5 минут или же стабильно отсутствовать в течение нескольких суток. В этот период хотелось бы использовать запасной канал, например соседнюю фирму, если у них в этот момент все работает, или пригородный автобус). Какие модули и компоненты оракла за это отвечают? Может быть надо что-то доустановить или у сторонних разработчиков есть такой функционал? Мне все разжевывать не надо, просто вкратце идеи нужны, в какую сторону копать?

Заранее спасибо.
ava
Sqlninja | 05.07.2007, 16:04 #
Цитата (Dimich @ 5.7.2007, 14:48 findReferencedText)
Sqlninja, а вообще реально сделать dblink с базой, с которой нет связи? Ну, чтобы, можно было данные, например на дискете туда-сюда носить?


можно делать экспорт шаблона внедрения (deployment template) на внешний носитель, и если нет связи, передавать его. мне про нет связи рассказывать не надо, у меня сеть была по всей Украине, и есть пару офисов стоящих реально в поле.
ava
Dimich | 06.07.2007, 07:14 #
Интересно. Спасибо за идею (правда я еще не понял что да как, читаю доку http://www.stanford.edu/dept/itss/docs/ora...96567/repdt.htm, пытаюсь разобраться). Если кто заинтересовался/разобрался с deployment template, поделитесь опытом пожалуйста.
ava
Sqlninja | 06.07.2007, 10:39 #
Вот пару скриптов по созданию MV схемы и выгрузке depoyment template в файл 3мя разными способами (есть траблы с экспортом длинных пакетов > 32k).
ava
Petro123 | 07.07.2007, 09:58 #
Чего то я непонял:
как из таблицы ROUTD, мы узнаем какую именно запись скажем удалили или обновили?

ava
DENSAOPIN | 29.08.2007, 10:00 #
Поразбирался deployment template, оказалось все достаточно просто.

Реплицируемая таблица сбрасывается целиком в текстовый файл
содержащий DML команды и запуская полученный скрипт на сайте снепшота мы заполняем снепшот при
полном отсутствии связи. Тут возникли проблемы при реплицировании больших таблиц строки в выгружаемом
скрипте >2499 символов...

Однако, зачем эта канетель, если можно просто сделать экспорт таблицы.

Подскажите, пожалуйста, есть ли готовый алгоритм для репликации типа "мастер-мастер" ?


ava
DENSAOPIN | 31.08.2007, 15:04 #
Спасибо Dimich, его вариант из того, что мне удалось накопать самый лучший.
Делаю стандартную репликацию типа "мастер-мастер" страхую при обрыве связи методом предложенным Dimich.

Кстати, к нам сейчас в фирму много народа приезжает свои программы презентовать.
И все у кого ни спросишь оффлайн репликацию сами руками пишут.

Короче - все работает. Только минимально подправил для своих нужд. http://forum.vingrad.ru/html/emoticons/pack/smile.gif
Please register or login to write.
Firm of day
Вы также можете добавить свою фирму в каталог IT-фирм, и публиковать статьи, новости, вакансии и другую информацию от имени фирмы.
Подробнее
Contributors
advanced
Submit