Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > Oracle > Синхронизация баз данных Oracle |
Автор: Гость_SergE 27.10.2004, 10:57 |
Не подскажете ли, господа? Где можно в Internet найти литературу по синхронизации баз данных. Про синхронизацию двух баз Oracle. Про осуществление гарантированной закачки в базу данных от удалённого клиента. Спасибо. |
Автор: Dimich 27.10.2004, 12:03 |
Я понял так, что Вас интересуют репликации? Могу порекомендовать http://www.sql.ru |
Автор: LSD 27.10.2004, 19:14 |
По поводу репликации данных в первую очередь надо почитать справку по Oracle, там все достаточно хорошо описанно. Можно запустить Enterprise Management Console, там все операции по настрйке репликации делаются достаточно легко, и при желании можно записать скрипты, а затем их модифицировать. |
Автор: 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 Буду благодарен за критику. |
Автор: LSD 28.10.2004, 19:16 |
Dimich Вообщем ты повторил систему репликации Oracle ![]() |
Автор: Petro123 28.6.2007, 12:23 | ||
Простите, а зачем выгружать даные в файл, разве нельзя непосредственно обратиться к нужным данным и залить их в новую базу? Кажется есть ведь гомогенные запросы? Добавлено @ 12:24 Да кстати не подскажите, как создать файл и отослать его вдруг понадобится? |
Автор: Petro123 29.6.2007, 11:58 |
А что за файлы, типизированные или текстовые? |
Автор: Dimich 2.7.2007, 15:19 |
Типизированные. Такого примерно формата: Поле Тип данных Размер данных Собственно данные Потом эти файлы еще архиватором упаковываются и режутся на тома. Очевидные недостатки: ограниченность поддерживаемых типов данных (NUMBER, VARCHAR, DATE), хотя можно прикрутить (при желании) и другие типы, я за ненадобностью это не делал. Но, если есть желание повторять, то лучше разобраться с нативными ораклевыви репликациями. Я такой изврат делал от безысходности. Причины описывал. |
Автор: Petro123 2.7.2007, 16:22 |
Не по чему разбираться пока, может есть какие ссылочки хорошие, русские. А твой способ мне по душе Создаем тригеры, журналы изменений таблиц, только файлы мне лень создавать, наверное гомогенными запросами можно слить будет инфу из одной базы в другую (кстати как тоже вопрос), Теоретически все вроде понятно, но блин практически, возникает много вопросиков, безобидных, но требующих время. Все таки придется наверное пойти по твоему пути, он хотя бы прозрачен для меня... |
Автор: LSD 2.7.2007, 18:48 |
Petro123 написание собственного велосипеда, процесс гораздо более долгий и сопряженный с бОльшим количеством ошибок, чем разбирательство по английской документации. |
Автор: Dimich 3.7.2007, 06:44 |
Petro123, ну, если так заинтересовался, могу запостить пример триггера над таблицей, пример процедуры, которая все это хозяйство разворачивает в DML операции и выполняет их, ну и собственно структуру таблиц. Кстати, если связь между БД хорошая, то можно данные из одной БД в другую гонять через dblink и не мучаться с файлами. Тогда у тебя воодще может не быть клиентских частей как у мну. Но и к совету LSD я бы советовал тебе прислушаться. Этот человек всегда дело говорит. |
Автор: Sqlninja 3.7.2007, 10:02 |
Только не это, шеф! Максимум, на что годится эта консоль - это мониторинг ошибочных транзакций, и их состав. Но никому не советую ее использовать для управления объектами репликации. Визарды, это вообще отдельная тема. Кажется, один раз я попробовал запустить какой-то мастер по созданию репликационной группы, в нем оказалость 6 нудных шагов, в итоге приведшие меня в никуда, ни окея, ни кансела. И это только маленький пример. Так что устанавливаем пакет DBMS_REPCAT и да здравствует PL/SQL. P.S. С каждым новым релизом Oracle, я все больше ненавижу индусов. |
Автор: LSD 3.7.2007, 12:04 | ||
Я настраивал репликацию именно им и все работало. |
Автор: Petro123 4.7.2007, 06:25 | ||
Да, да конечно, буду очень признателен |
Автор: Dimich 4.7.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 для подтверждения выполнения репликации я героически потерял. Но, думаю воспроизвести ее труда не составит. |
Автор: Petro123 4.7.2007, 09:21 |
Здорово, только я ненашел routins.trg, и самое главное repl.prc,... Добавлено через 6 минут и 45 секунд а и еще, что это за servers.outflag=1 |
Автор: Dimich 4.7.2007, 09:33 | ||||
А routins.trg я действительно забыл. Вот он:
|
Автор: Sqlninja 4.7.2007, 09:34 |
значит версия была лучше |
Автор: Dimich 4.7.2007, 09:39 |
Имелось ввиду значение поля outflag = 1 в таблице servers. Т.е. смысл в том, что для сервера, помеченного этим флагом генерируются репликации. Просто у меня много серверов и соответственно кому-то нужно синхронизировать одну часть данных, кому-то она вообще не нужна, даже таблиц таких нет. И для постепенного включения репликаций хорошо. Или если сбой где-то произошел, то выключить и разруливать потихоньку. |
Автор: Petro123 4.7.2007, 09:53 |
Понятно, вкл/выкл. Как происходит обработка входящих репликаций, по идее она должна обрабатываться в виде очереди, Т.е. пока успешно не обработали одну репликацию не переходим к следующей. Так ли это? Добавлено через 5 минут и 31 секунду Вроде как получается что за раз обрабатывается весь журнал, и если есть хотя бы одна ошибка делаем откат на начало журнала, или нет? |
Автор: Dimich 4.7.2007, 10:16 | ||||||
Да, верно. Данные из таблиц ROUT и ROUTD загружаются в таблицы RIN и RIND соответственно. После чего за выполнение репликаций отвечает хранимая REPL. Она то и выполняет все операции в порядке очереди. Очередь устанавливается последовательностью R_ID. Т.е. когда фиксируются репликации в таблицы (см. пример триггера над таблицей USL), R_ID будет определено последовательностью SEQR_ID. В этой же последовательности их и обработает потом хранимая REPL. Кстати, вот она сама:
На других серверах, как я уже говорил, значения первичных ключей не пересекаются, т.к. там тоже будут существовать такие последовательности, но уже с другим интервалом. Например:
При возникновении ошибки в процедуру REPL, обработка прекращается до вмешательства человека. На начальном этапе это неизбежно будет (стадия отладки и тестирования). Теперь у меня это уже больше года работает нормально. Я и забыл, когда туда лазил. Вот сейчас пришлось вспоминать, как это работает. |
Автор: Petro123 4.7.2007, 12:03 | ||
Как загружаются данные в таблицы Rin, Ring? Просто очищаем RIN, затем все строки заливаем из ROUT? Добавлено через 7 минут и 22 секунды При такой схеме возникает некая избыточность данных. В обеих базах данные дублируются. Если реплицировать нужно справочники - проблем нет. А если таблицы в которые ежедневно добавляются сотни тысяч записей, как все это будет работать, корректно ли, быстро ли? |
Автор: Dimich 4.7.2007, 14:35 |
Можно не очищать, просто дописывать. Из RIN данные можно удалять только тогда, когда выполнятся все условия: 1. Репликация выполнена, т.е. Rin.rf = 0 (или существует запись в Rt) 2. Удаленный сервер знает, что репликация уже выполнена, иначе он должен снова ее выгрузить. Если память не изменяет, то это у мну routsrv.flag Избыточность конечно существует, но она необходима для того, чтобы репликация обязательно достигла адресата и выполнилась, а не потерялась по дороге. Таблицы получаются достаточно большие. И хотя они у меня регулярно чистятся (удаляются уже отработанные записи), тем не менее наличие нескольких миллионов записей в RIND - нормальное явление. Скорость, да несколько хромает. Обычно такие задачи у меня работают ночью. Синхронизируется 14 серверов с 1-м сервером. Средний поток изменений от одного сервера к другому - примерно 200,000..1,500,000 репликаций. За ночь успевает. Но бывает и больше, тогда может и к обеду следующего дня завершиться. Насчет корректности: все работает корректно. Пока рассогласований небыло. Имхо, мне самому не очень сейчас это нравится в плане быстродействия. Иногда хочется быстрее. Если время найду, я давно порывался это переделать, правда мысли пока еще не оформились окончательно. Может твоя критика и поможет мне. |
Автор: Petro123 4.7.2007, 15:16 | ||
Опять репликация? Как ты дописываешь? |
Автор: Petro123 4.7.2007, 15:49 | ||
Может быть лучше в таблицу Rout, добавить поле Статус репликации, 0 - не завершена, 1 - завершена? Как думаешь? Или у тебя в таблицу RT добавляются только те записи, репликация по которым прошла успешно, а затем при очистке журнала репликации, удаляются только те которые есть в RT? |
Автор: Dimich 5.7.2007, 06:54 | ||
Не понял вопроса. Какие записи получил от удаленного сервера, те и дописываю. В таблицах есть primary key по R_ID (ID репликации), поэтому уже существующие, если такие оказались, будут отвергнуты в любом случае. Более подробный алгоритм такой: читаю файл, делаю insert строки. Можно к примеру SQL Loader прикрутить, если надо.
Можно наверное и так сделать. Почему бы и нет. Будет экономия. Я уже и вспомнить не могу, чем я руководствовался, когда делал так. Да, кстати, вспомнил еще: когда будешь обрабатывать дробные числа и даты, имей в виду, что скорее всего дробное число будет иметь не десятичную точку, а запятую. Это я сперва по глупости решил как Replace (',', '.', value). Но гораздо лучше использовать nls_numeric_characters Также нужно обратить внимание на формат дат. При неверной настройке они имеют свойство записываться некрасиво. Это я решил, используя в тригерах форматирование при выводе дат: to_char(date, 'dd/mm/yyyy hh:mi:ss') |
Автор: Sqlninja 5.7.2007, 11:41 |
имхо, вы все гоните. если б мои кодеры начали переписывать стандартную функциональность оракла, уволил бы всех нах. |
Автор: Dimich 5.7.2007, 14:48 | ||
Гоним, не спорю. Конечно, ввиду отсутствия русской документации по репликациям и наличия больших запасов природной лени и невежества родилось сие поделие. Но что тут поделаешь. Надо ж было с чего-то начинать и на чем то учиться? Кто же знал, что оно такое живучее окажется? Sqlninja, а вообще реально сделать dblink с базой, с которой нет связи? Ну, чтобы, можно было данные, например на дискете туда-сюда носить? Или как тогда можно запустить репликации (сети нет т.е., интернет есть, но не стабильный, т.е. может прерываться или каждые 5 минут или же стабильно отсутствовать в течение нескольких суток. В этот период хотелось бы использовать запасной канал, например соседнюю фирму, если у них в этот момент все работает, или пригородный автобус). Какие модули и компоненты оракла за это отвечают? Может быть надо что-то доустановить или у сторонних разработчиков есть такой функционал? Мне все разжевывать не надо, просто вкратце идеи нужны, в какую сторону копать? Заранее спасибо. |
Автор: Sqlninja 5.7.2007, 16:04 | ||
можно делать экспорт шаблона внедрения (deployment template) на внешний носитель, и если нет связи, передавать его. мне про нет связи рассказывать не надо, у меня сеть была по всей Украине, и есть пару офисов стоящих реально в поле. |
Автор: Dimich 6.7.2007, 07:14 |
Интересно. Спасибо за идею (правда я еще не понял что да как, читаю доку http://www.stanford.edu/dept/itss/docs/oracle/9i/server.920/a96567/repdt.htm, пытаюсь разобраться). Если кто заинтересовался/разобрался с deployment template, поделитесь опытом пожалуйста. |
Автор: Sqlninja 6.7.2007, 10:39 |
Вот пару скриптов по созданию MV схемы и выгрузке depoyment template в файл 3мя разными способами (есть траблы с экспортом длинных пакетов > 32k). |
Автор: Petro123 7.7.2007, 09:58 |
Чего то я непонял: как из таблицы ROUTD, мы узнаем какую именно запись скажем удалили или обновили? |
Автор: DENSAOPIN 29.8.2007, 10:00 |
Поразбирался deployment template, оказалось все достаточно просто. Реплицируемая таблица сбрасывается целиком в текстовый файл содержащий DML команды и запуская полученный скрипт на сайте снепшота мы заполняем снепшот при полном отсутствии связи. Тут возникли проблемы при реплицировании больших таблиц строки в выгружаемом скрипте >2499 символов... Однако, зачем эта канетель, если можно просто сделать экспорт таблицы. Подскажите, пожалуйста, есть ли готовый алгоритм для репликации типа "мастер-мастер" ? |
Автор: DENSAOPIN 31.8.2007, 15:04 |
Спасибо Dimich, его вариант из того, что мне удалось накопать самый лучший. Делаю стандартную репликацию типа "мастер-мастер" страхую при обрыве связи методом предложенным Dimich. Кстати, к нам сейчас в фирму много народа приезжает свои программы презентовать. И все у кого ни спросишь оффлайн репликацию сами руками пишут. Короче - все работает. Только минимально подправил для своих нужд. http://forum.vingrad.ru/html/emoticons/pack/smile.gif |