Требуется синхронизация 2-х баз данных

rubalex

Новичок
Требуется синхронизация 2-х баз данных

2 базы MYSQL на разных серверах.

вариант 1.
работа идет с базой 1 и потом нужно сделать так чтобы база 2 стала идентична базе 1.

вариант2
работа идет и с базой 1 и с базой 2 одновременно. и потом нужно полностью синхронизировать их

какой механиз нужно применять?
 

Апельсин

Оранжевое создание
> работа идет с базой 1 и потом нужно сделать так чтобы база 2 стала идентична базе 1.

репликация

> работа идет и с базой 1 и с базой 2 одновременно. и потом нужно полностью синхронизировать их

мм .. круговая репликация. правда не уверена что она подойдет, если включать ее раз в какой-то промежуток времени.
 

rubalex

Новичок
а какими средствами репликация? разве в MYSQL есть такой втроенный интрумент?
 

Yurik

/dev/null
работа идет и с базой 1 и с базой 2 одновременно. и потом нужно полностью синхронизировать их
Я не уверен что такое возможно даже теоретически, разве что у вас есть какие-то четкие правила работы с базой.

Пример
сервер 1: update t set a=b
сервер 1: update t set a=c

и какие данные после этого считать правильными?
 

Апельсин

Оранжевое создание
последнее изменение, имхо. Но все равно слишком много узких мест.
 

Yurik

/dev/null
А если изменения основываются на текущем состоянии базы. И изменения должны бы производиться с учетом предыдущих?
Может на втором сервере не делали бы
update t set a=c если бы знали что на первом уже сделали update t set a=b?

http://www.osp.ru/os/2001/12/045.htm - здесь есть интересное нестандартное решение это проблемы
Описанная методика в определенном смысле расширяет реляционную базу данных в новое измерение за счет внесения функциональной зависимости между кортежами эквивалентных отношений. Подобное изменение реляционной модели нельзя признать революционным, оно, тем не менее, вводит новое понятие, позволяющее расширить математическую базу теории реляционных баз данных (по крайней мере, ни в одном из известных нам источников такой метод не описан).
Кстати меня этот вопрос очень интересует сейчас.

Вопрос к Апельсинке:
возможно ли в мыскл сделать одно из следующего
а) задать диапазоны для первичных ключей с типом автоинкремент
б) создать первичные ключи другого типа, которые би идентифицировали из какой БД запись.

Нужно это для следующего:
есть N независимых баз идентичной структуры. Для анализа (readonly) нужно их периодически соединять воедино (реплицировать на центральный сервер который выступает в роли слейва). Очень желательно это сделать в одну БД (через чтение логов), но тогда возникает конфликт первичных ключей. Если бы можно было задать их так (к примеру)
1_1
1_2
....
1_6987
2_1
2_34

где X_* - код базы из какой взяты записи.
Или назначить автоинкременту диапазон из которого он начинается:
1....10000 - первая бд
10000....20000 - вторая бд и т.д.
(ну конечно тип полей и диапазон нужно подобрать)
 

Апельсин

Оранжевое создание
> А если изменения основываются на текущем состоянии базы. И изменения должны бы производиться с учетом предыдущих?

вот именно из-за этих "если" и много узких мест.
статью чуть позже прочту, спасибо.

a) нельзя
b) я так поняла тебе нужен составной первичный ключ, где вторым столбцом будет автоинкремент.
 

Yurik

/dev/null
b) я так поняла тебе нужен составной первичный ключ, где вторым столбцом будет автоинкремент.
угумс.. во все таблы добавить поле кода базы и
все запросы типа
INSERT INTO t (val) VALUES('sdasdad');
UPDATE t SET a='b' WHERE id=6
переписать на
INSERT INTO t (baza, val) VALUES(2, 'sdasdad');
UPDATE t SET a='b' WHERE baza=2 AND id=6

Тогда по идее при репликации из лога не должно быть конфликтов.
 

Yurik

/dev/null
Тогда вопрос такой:
это дополнительное поле нужно прописывать в программе. А можно в каждой БД прописать его default значение на код этой БД в системе и тогда не нужно заморачиваться насчет этого кода в самой программе.
В таком случае есть какая-то возможность реплицировать много баз в одну? Ведь по логу уже не пойдет? Только дампы таблиц по идее?
 

Апельсин

Оранжевое создание
стоп, так идентификатор базы это просто сделать NOT NULL столбец со значением по умолчанию равным этому самому идентификатору.
для всех данных в пределах одной базы данных он будет одинаковым, т.е. на запросы UPDATE он влиять не должен.
или я что-то не правильно поняла?
 

Yurik

/dev/null
Да! Именно. Работать база будет правильно. Но во всех логах числится просто
UPDATE t SET a='b' WHERE id=6
а не
UPDATE t SET a='b' WHERE baza=2 AND id=6
и когда центральный сервер обработает этот лог он применит запрос ко всем id=6 а не только к тем которые из базы номер 2.
Просто нужно в приложени во все запросы подописывать идентификатор текущей базы (для самого приложения они нафиг не нужны, а только для центрального сервера при разборе логов)
 

rubalex

Новичок
Originally posted by Апельсин
а какими средствами репликация? разве в MYSQL есть такой втроенный интрумент?

да.
Я что то не допонимаю. Вы обсуждаете как синхронизировать несколько баз данных c помощью определенных процедур. А апельсин говорила что есть внутренние средства MYSQL для синхронизации. ???
 

Yurik

/dev/null
2rubalex: внутренние средства репликации позволяют МНОГИМ слейвам автоматически реплицировать базу из ОДНОГО мастера. Это делают для:
1. распределения нагрузки в системах где большая нагрузка и много селектов
и/или
2. автоматического бекапа данных по слейвах

Организовывается это все через логи мастера. Слейв(ы) их читает и приводит свою базу в полное соотвествие главной.

Мне же нужно сделать синхронизацию из МНОГИХ МАСТЕРОВ на один слейв. Т.е. разные данные идентичной структуры свести воедино, а не просто скопировать. А здесь нужно менять структуру базы, чтобы данные не конфликтовали.
 

chira

Новичок
Установить условие, что все PRIMARY KEY начинаются с цифры из интервала к примеру 1-99. Далее сам организуешь auto_increment с шаном 100 (а не 1 как в MySQL).
Auto_increment начинающийся с 100 можно использовать для основных кодификаторов, которые редко меняются и должны быть одинаковы для всех.
 

confguru

ExAdmin
Команда форума
Yurik - твой подход чреват большими проблемами в будующем ,)

Делать надо так
2 WEB servera работают с 1 базой данный (Мастером) + 1 база данный стоит для репликации основной базы и для операций чтения этими 2 серверами если будет не доступен
мастер
 

Yurik

/dev/null
2admin:
это не для того делается.
Нету никакого веб сервера и репликация не нужна. Что делать для распределения нагрузки и бекапа я в курсе.
Ситуация такова:
Есть N организаций у которых есть установленное приложение которое работает с их базой. Т.е. есть N копий приложения.

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

Пока это смотрится так:
1. В каждой таблице добавил поле base - идентификатор копии приложения (код базы), он устанавливается при установке приложения. Он есть составной частью первичного ключа id (auto_increment)
2. Во все INSERT/UPDATE запросы в приложениия дописывается
INSERT INTO (base, ...) VALUES (N, ....)
UPDATE WHERE base=N AND...
(это не нужно для приложения, т.к. default значение и так стоит N, но это нужно будет для лого)
3. Все инсерт/апдейт запросы пишутся в логфайл.
4. По крону проверяется наличие соединения с центральным сервером, если оно есть - накопившийся лог перемещается на фтп центрального сервера.
5. Центральный сервер импортит логи в свою базу и так как в них везде фигурирует base=N нету конфликта данных и он знает откуда они пришли.
 

Yurik

/dev/null
Кстати о первых граблях: все запросы где упоминается
NOW() и другие временные функции-аналоги нужно в самом приложении переписать. В пхп например
PHP:
$sql="INSERT INTO t (d) VALUES(NOW())";
$sql="INSERT INTO t (d) VALUES(".date('Y-m-d G:i:s').")";
а также не использовать тип TIMESTAMP
 

confguru

ExAdmin
Команда форума
2Yurik: Чего ты нам мозги пудрил? Причем тут синхронизация?
 

Yurik

/dev/null
Ну я в терминах могу ошибаться? как это правильно называется? Апельсинка вот поняла о чем я говорил. Если эта тема не подходит к топику-стартеру - выделите новую тему.

Кстати ещё вопрос:
не будет ли камней если я при записи лога буду проверять
mysql_affected_rows()>0 чтобы не писать в лог те запросы которые не изменили ничего (например нажат апдейт записи без изменения данных)
это дало бы некоторое уменьшение размера лога, но если есть какие то предостережния, то откажусь от затеи.
 
Сверху