Текст ниже - просто для того, что бы кто-нить когда-нить это нагугли, и ему было полезно. Собственно, ниже мой опыт возни с репликацией из мускуля в оракл с использованием tungsten replicator.
Итак, в начале несколько слов, а-ля предисловие. Данный мануал не претендует на истину в первой инстанции и на построчное руководство. Скрипты можно написать куда лучше. Команды - на момент прочтения могут звучать уже по другому (даже на момент написания документация на сайте разниться с реальными командами). Многое в скриптах сделано под рутом, что в целом тоже не правильно, но для «что бы заработало а потом поправить» - оставил пока что так. Ответы на базовые вопросы по настройке Вы найдете в документации на сайте tungsten-а (
http://code.google.com/p/tungsten-replicator/).
Задача:
Возникла необходимость в репликации с MySql (5.5) на Oracle (11.2) на сервере с CentOS 5.5. При чем не всего-всего, а только больших таблиц, очень-очень быстро наполняющихся и связанных со статистикой. Добавим к этому, что на сервере MySql наблюдаются проблемы с местом, и как вывод - фильтрация репликации должна происходить на нем. Ну, и при необходимости - сразу подчищаться все возможные временные файлы, опять же по причине места, на обоих серверах.
Итак, начнем.
Установка:
На MySql понадобиться проставить бинлоги в формате RAW. Это необходимо исключительно для скриптов фильтрации и было частью бизнес-логики. Если фильтровать Вам не обязательно, или пишите свой скрипт - вполне можно и не менять формат бинлогов.
Качаем сам tungsten replicator (
http://code.google.com/p/tungsten-replicator/), и устанавливаем на мастере (MySql сервер) и на слейве (Oracle). Он потребует ruby и java. Все ставил из дистрибутивов без каких-либо проблем.
Работать Tungsten у нас будет по следующей схеме:
http://img256.imageshack.us/img256/8151/28494283.pngСкрипт инсталляции для мастера:
./tools/tungsten-installer --master-slave -a --cluster-hosts=127.0.0.1 \
--master-host=127.0.0.1 \
--user=root \
--home-directory=/opt/repl \
--datasource-port=3306 \
--datasource-user= \
--datasource-password= \
--service-name=oracle \
--rmi-port=10000 \
--thl-port=2112 \
--mysql-enable-enumtostring=true \
--mysql-use-bytes-for-string=false \
--skip-validation-check=MySQLNoMySQLReplicationCheck
В целом - все думаю понятно, «service-name» - как будет сервис обозван, и в мускуле возникнет схема - tungsten_. Она нам еще пригодится.
Юзер под которым крутится только в примере root, потом или сразу переставьте, под кем Вам удобнее. В примерах будет использоваться root.
На слейве:
./tools/tungsten-installer --master-slave -a --cluster-hosts=localhost \
--user=root \
--master-host= \
--home-directory=/opt/repl \
--datasource-type=oracle \
--datasource-oracle-service= \
--datasource-user= \
--datasource-password= \
--service-name=frommysql \
--rmi-port=10000 \
--master-thl-port=2112
Пока что, все просто. После выполнения этих не хитрых операций - мы будем работать только с копией в папке куда проинсталлировали (/opt/repl/...).
Не торопимся запускать репликатор, так сходу все равно не запустится корректно - будет ругаться в логах на нехватку конфигов, т.к. имена конфигов будет желать в зависимости от имени схемы. Переименовываем replicator.properties в static-<имя схемы>.properties, в моем случае - static-oracle.properties.
В конфиге (/opt/repl/tungsten/tungsten-replicator/conf/...) на мастере указываем какие фильтры будут использоваться:
replicator.stage.binlog-to-q.filters=dropcomments,filtertables,dbupper
и сам путь до фильтра, и соответственно таблицы которые будут реплицироваться:
replicator.filter.filtertables=com.continuent.tungsten.replicator.filter.JavaScriptFilter
replicator.filter.filtertables.script=/opt/repl/tungsten/tungsten-replicator/filtertables.js
replicator.filter.filtertables.include=idp.abyrvalg,idp.transactions
В данном случае - схема idp и таблицы abyrvalg и transactions.
Убеждаемся, что мастер слушает порт, по которому к нему будет обращаться слейв для забирания thl логов
replicator.master.listen.uri=thl://0.0.0.0:2112/
В replicator.source_id= указываем любое уникальное имя. Проще всего - IP сервера. В моем случае - 192.168.40.3
В конце повествования будут приложены боевые конфиги и разумеется скрипт фильтрации.
Стартуем репликатор на мастере ./replicator start
Проверим его переход в онлайн - ./trepctl status, если офлайн - ./trepctl online
Если статус онлайн - значит все хорошо, он начал складировать у себя бинлоги MySql (по умолчанию, когда они превышают гигабайт - он их сам трет) и thl файлы - собственно что он будет слать слейву, об этом речь еще зайдет чуть ниже. Тут проблем быть не должно.
На слейве соответственно конфиг файл переименовываем в static-<имя схемы>.properties, в моем случае - static-frommysql.properties.
Убеждаемся, что в значении replicator.master.connect.uri=thl://:2112 точно установлен IP мастера, явки и пароли верны.
replicator.source_id= - опять же любое уникальное значение,
закомментируем replicator.store.thl.storageListenerUri.
Создаем в указанной в конфиге слейва оракла таблицу, соответствующую реплицируемой.
Запускаем слейв - ./replicator start
Если он перешел с состояние по статусу online - все хорошо. Если нет - будет ругаться в логах и статусах.
Можно зайти в созданные схемы на местере и слейве, и обратить внимание - в таблице trep_commit_seqno меняются значения seqno и epoch_number.
Если все ок - можно уменьшить уровень логирования подредактировав wrapper.conf
Немного ухода за пациентом.
На мастере thl логи хранятся сколько указано в конфиге, по умолчанию - день. (replicator.store.thl.log_file_retention=), меняем на нужное нам, на слейве тоже самое. Но если нам срочно потребовалось высвободить место, то придется делать это вручную. Главное - не затереть последний эвент.
На мастере по умолчанию хранятся bin логи в размере не более 1 гигабайта (/opt/repl/relay/...), но для чистки thl вручную на слейве и мастере надо смотреть верхнее и нижнее значение уже записанных эвентов.
Собственно - сей кривой скрипт на мастере и слейве и занимается у меня этим.
#!/bin/sh
cd /opt/repl/tungsten/tungsten-replicator/bin
MINVALUE=`./thl -service frommysql info | grep «min seq# = » | awk '{print $4;}'`
MAXVALUE=`./trepctl status | grep «appliedLastSeqno: » | awk '{print $3;}'`
MAXVALUENEW=`echo "$MAXVALUE-1000" | bc`
./trepctl -service frommysql offline
sleep 10
./thl purge -low $MINVALUE -high $MAXVAskyrimLUENEW -y
./trepctl -service frommysql online
Немного траблшутинга.
Если мы случайно стерли лишнее, либо сеть между серверами лежала длительное время, или случился еще ряд причин, но при коннекте слейв пишет что увы и ах - но он хочет позицию N, а у мастера ее нету, что-нибудь вроде:
INFO | jvm 1 | 2011/11/24 11:32:54 | 2011-11-24 11:32:54,432 [oracle - connector-handler-192.168.39.50] ERROR thl.ConnectorHandler Connector handler terminated by THL exception: Log seek failure: expected seqno=XXXXXXX found seqno=YYYYYYY
(более точно смотрим либо в статусе, либо в логах) - то придется немного подчистить.
Останавливаем репликацию на слейве. Вытираем скопированные thl логи. Обращаем внимание на таблицу trep_commit_seqno. Затираем значения seqno и epoch_number, либо ставим ожидаемые мастером значения, смотря чего он хочет. Запускаем. Дальше придется, конечно, утерянный фрагмент по старинке перегонять из MySql в Oracle (через csv).
Так же, возможно сделать считывание с определенной позиции, см. документацию на официальном сайте, пункты 4.3.x
Конфиг мастера, конфиг слейва и js-скрипт фильтрации:
http://zalil.ru/32217860 В целом - Tungsten replicator показал себя как очень гибкий и мощный, но не очень хорошо документированный продукт, позволяющий производить репликацию между различными БД под различные задачи.
ЗЫ я хз куда скрипт фильтрации бы залить, что бы на долго, если кому понадобиться - пишите, вышлю.
ЗЫЫ регнулся на хабре и отпостил это дело туда, но т.к. оно только там и доступно - решил дать миру тута =)