Как повторно синхронизировать базу данных Mysql, если ведущее и ведомое устройства имеют разные базы данных в случае репликации Mysql?

140

Mysql Server1работает как МАСТЕР .
Mysql Server2работает как SLAVE .

Теперь репликация БД происходит с МАСТЕРА на ПОДЧИНЕННЫЙ .

Server2удаляется из сети и повторно подключается через 1 день. После этого есть несоответствие в базе данных на ведущем и ведомом устройствах.

Как повторно синхронизировать БД, так как после восстановления БД, взятой из Master в Slave, проблема не решается?

Инду Шарма
источник

Ответы:

288

Это полная пошаговая процедура повторной синхронизации репликации ведущий-ведомый с нуля:

У мастера:

RESET MASTER;
FLUSH TABLES WITH READ LOCK;
SHOW MASTER STATUS;

И скопируйте куда-нибудь значения результата последней команды.

Не закрывая соединение с клиентом (потому что это снимет блокировку чтения) выполните команду, чтобы получить дамп мастера:

mysqldump -u root -p --all-databases > /a/path/mysqldump.sql

Теперь вы можете снять блокировку, даже если дамп еще не закончился. Для этого выполните в клиенте MySQL следующую команду:

UNLOCK TABLES;

Теперь скопируйте файл дампа на подчиненное устройство с помощью scp или другого инструмента.

У раба:

Откройте соединение с mysql и введите:

STOP SLAVE;

Загрузите дамп данных мастера с помощью этой консольной команды:

mysql -uroot -p < mysqldump.sql

Синхронизировать ведомые и главные журналы:

RESET SLAVE;
CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=98;

Где значения вышеперечисленных полей - те, которые вы скопировали ранее.

Наконец, введите:

START SLAVE;

Чтобы убедиться, что все снова работает, после ввода:

SHOW SLAVE STATUS;

Тебе следует увидеть:

Slave_IO_Running: Yes
Slave_SQL_Running: Yes

Это оно!

Дэвид Эспарт
источник
8
С типизированной dabatase INNODB и определенными другими сложными типами столбцов, такими как BLOB и DATE, я рекомендую использовать следующие переключатели:--opt --single-transaction --comments --hex-blob --dump-date --no-autocommit --all-databases
Кен Пега,
4
Является ли RESET_SLAVEнеобходимым? Обратите внимание, что эти инструкции сбрасывают пользователя и пароль репликации, поэтому вам придется повторно ввести их сCHANGE MASTER TO...
Майк С.
25
Если вы используете флаг --master-data при вызове mysqldump на ведущем устройстве, команда CHANGE MASTER TO записывается в файл дампа и, таким образом, сохраняет шаг выполнения после импорта файла дампа в ведомое устройство.
udog
3
Отсутствие блокировки мастера (не требует Percona ) plusbryan.com/mysql-replication-without-downtime Еще одним преимуществом этого является то, что дамп SQL также поставляется с необходимой строкой «CHANGE MASTER» (закомментировано)
mahemoff
2
Есть ли способ это автоматизировать?
Метафаниэль 05
27

Документация по этому поводу на сайте MySQL ужасно устарела и изобилует недоработками (например, interactive_timeout). Выпуск FLUSH TABLES WITH READ LOCK как часть вашего экспорта мастера обычно имеет смысл только при согласовании с моментальным снимком хранилища / файловой системы, таким как LVM или zfs.

Если вы собираетесь использовать mysqldump, вам следует вместо этого полагаться на параметр --master-data, чтобы защититься от человеческой ошибки и как можно быстрее снять блокировки на главном сервере.

Предположим, что главный - 192.168.100.50, а подчиненный - 192.168.100.51, у каждого сервера настроен отдельный server-id, у главного есть двоичный вход в систему, а у подчиненного устройства только для чтения = 1 в my.cnf

Чтобы ведомое устройство могло начать репликацию сразу после импорта дампа, введите команду CHANGE MASTER, но опустите имя и позицию файла журнала:

slaveserver> CHANGE MASTER TO MASTER_HOST='192.168.100.50', MASTER_USER='replica', MASTER_PASSWORD='asdmk3qwdq1';

Выдать GRANT на ведущем устройстве для использования ведомым устройством:

masterserver> GRANT REPLICATION SLAVE ON *.* TO 'replica'@'192.168.100.51' IDENTIFIED BY 'asdmk3qwdq1';

Экспортируйте мастер (на экране), используя сжатие и автоматически записывая правильные координаты двоичного журнала:

mysqldump --master-data --all-databases --flush-privileges | gzip -1 > replication.sql.gz

Скопируйте файл replication.sql.gz на ведомое устройство, а затем импортируйте его с помощью zcat в экземпляр MySQL, работающий на ведомом устройстве:

zcat replication.sql.gz | mysql

Запустите репликацию, подав команду ведомому устройству:

slaveserver> START SLAVE;

При необходимости обновите /root/.my.cnf на ведомом устройстве, чтобы сохранить тот же пароль root, что и на главном устройстве.

Если вы используете 5.1+, лучше сначала установить binlog_format мастера на MIXED или ROW. Помните, что события, регистрируемые строками, являются медленными для таблиц, в которых отсутствует первичный ключ. Обычно это лучше, чем альтернативная (и по умолчанию) конфигурация инструкции binlog_format = (на ведущем устройстве), поскольку с меньшей вероятностью будут получены неверные данные на ведомом устройстве.

Если вы должны (но, вероятно, не должны) фильтровать репликацию, сделайте это с опциями ведомого устройства replicate-wild-do-table = dbname.% Или replicate-wild-ignore-table = badDB.% И используйте только binlog_format = row

Этот процесс будет удерживать глобальную блокировку мастера на время выполнения команды mysqldump, но в противном случае не повлияет на мастер.

Если у вас возникает соблазн использовать mysqldump --master-data --all-databases --single-transaction (потому что вы используете только таблицы InnoDB), возможно, вам лучше использовать MySQL Enterprise Backup или реализацию с открытым исходным кодом под названием xtrabackup (любезно предоставлено Перкона)

Устаревший
источник
3
Если вы хотите просто перестроить существующее ведомое устройство, вы можете выполнить описанный выше процесс, пропустив пару шагов: Команда GRANT и ручная команда CHANGE MASTER
устарело
Вопрос 1: Что бы в windows было эквивалентом zcat. Вопрос 2: Как mysqldumpобстоят дела с большими базами данных с точки зрения производительности? Есть ли способ использовать SELECT INTO OUTFILEи LOAD DATAплавно в предложенном вами процессе? (Так как они обычно работают быстрее)
Ифеди Оконкво
Не нужно STOP SLAVEгде-то в процессе?
Дэвид В.
16

Если вы не пишете напрямую на подчиненное устройство (Server2), единственная проблема должна заключаться в том, что на Server2 отсутствуют какие-либо обновления, которые произошли с момента его отключения. Просто перезапустите подчиненное устройство с помощью "START SLAVE;" должен вернуть все в норму.

Malonso
источник
2
Вы можете проверить журналы корзины и посмотреть, охватывают ли они период времени, в течение которого ваша система не была синхронизирована. Если вам не хватает дней, это может быть более серьезной проблемой и потребовать от вас полного дампа для восстановления недостающих данных.
nelaaro
7

Думаю, вам помогут утилиты Maatkit! Вы можете использовать mk-table-sync. См. Эту ссылку: http://www.maatkit.org/doc/mk-table-sync.html

Незначительный
источник
Думаю, ему нужно будет временно прекратить запись во время работы скрипта.
Ztyx
Это по-прежнему отлично работает. Однако инструменты были переименованы и теперь называются pt-table-sync. На самом деле, однако, я обнаружил, что их инструмент pt-slave-restart работает как по волшебству.
mlerley
7

Я очень поздно ответил на этот вопрос, однако я столкнулся с этой проблемой, и после долгих поисков я нашел эту информацию от Брайана Кеннеди: http://plusbryan.com/mysql-replication-without-downtime

На Master сделайте резервную копию следующим образом:
mysqldump --skip-lock-tables --single-transaction --flush-logs --hex-blob --master-data = 2 -A> ~ / dump.sql

Теперь проверьте заголовок файла и запишите значения для MASTER_LOG_FILE и MASTER_LOG_POS. Они вам понадобятся позже: head dump.sql -n80 | grep "MASTER_LOG"

Скопируйте файл "dump.sql" на Slave и восстановите его: mysql -u mysql-user -p <~ / dump.sql

Подключитесь к подчиненному серверу mysql и выполните команду, подобную этой: CHANGE MASTER TO MASTER_HOST = 'master-server-ip', MASTER_USER = 'replication-user', MASTER_PASSWORD = 'slave-server-password', MASTER_LOG_FILE = 'value from above', MASTER_LOG_POS = значение сверху; НАЧАТЬ РАБ;

Чтобы проверить прогресс Slave: SHOW SLAVE STATUS;

Если все в порядке, Last_Error будет пустым, а Slave_IO_State сообщит «Ожидание отправки события мастером». Ищите Seconds_Behind_Master, который указывает, насколько он отстает. YMMV. :)

Джеффри7
источник
3
Это работает, и если ведомое устройство уже настроено и только рассинхронизировалось, вам не нужно запускать CHANGE MASTER; просто укажите --master-data=1(или просто --master-data).
LSerni
5

Вот что я обычно делаю, когда подчиненное устройство mysql не синхронизируется. Я смотрел mk-table-sync, но подумал, что раздел Риски выглядит страшно.

На Мастере:

SHOW MASTER STATUS

Выводимые столбцы (Файл, Позиция) нам немного пригодятся.

На ведомом:

STOP SLAVE

Затем выгрузите главную базу данных и импортируйте ее в подчиненную базу данных.

Затем запустите следующее:

CHANGE MASTER TO
  MASTER_LOG_FILE='[File]',
  MASTER_LOG_POS=[Position];
START SLAVE;

Где [File] и [Position] - это значения, выведенные из "SHOW MASTER STATUS", запущенного выше.

Надеюсь это поможет!

Брайсон
источник
5
Это , кажется , сломана, так как вы , видимо , не FLUSH TABLES WITH READ LOCK;до вас SHOW MASTER STATUSи сбросить основную базу данных. Я думаю, это может привести, например, к дублированию ключевых ошибок на ведомом устройстве, поскольку вы фактически устанавливаете статус ведущего на момент времени до того, как был сделан дамп, поэтому вы будете воспроизводить историю, которая уже включена в дамп. (Если вы делаете что-то в описанном вами порядке.)
KajMagnus
5

Продолжая ответ Дэвида ...

Использование SHOW SLAVE STATUS\Gдаст удобочитаемый результат.

Грег Акерсон
источник
Любой способ страницы вывода?
Джозайя
'pager more', я думаю, подойдет
Ян
3

иногда вам просто нужно дать рабу тоже

пытаться

stop slave;    
reset slave;    
start slave;    
show slave status;

частенько, рабы, ребята просто застревают :)

Замаскированный кодер глупости
источник
... и контролировать Positionиспользование ведущего устройства show master status;против Exec_Master_Log_Pos:использования ведомого устройства show slave status \G. Раб должен догнать мастера. Работал для меня с использованием mysql 5.6 только сейчас после короткого отключения сети.
Mike S
10
Это вводит в заблуждение, как только вы перезапустите раб, мазь полностью потеряет информацию о том, где находится хозяин.
Цянь Чен
2

Вот полный ответ, который, надеюсь, поможет другим ...


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

Итак, вот результат теста после настройки главного и подчиненного устройства, как указано в: http://dev.mysql.com/doc/refman/5.0/en/replication-howto.html ...

При условии, что вы используете рекомендованную конфигурацию ведущий / ведомый и не записываете на ведомое устройство, он и я, где правы (что касается mysql-server 5.x). Мне даже не нужно было использовать «START SLAVE;», он просто догнал своего хозяина. Но по умолчанию 88000 что-то повторяется каждые 60 секунд, поэтому я думаю, что если вы исчерпаете, вам, возможно, придется запустить или перезапустить ведомое устройство. В любом случае, для тех, как я, кто хотел знать, требуется ли ручное вмешательство для отключения ведомого устройства и повторного резервного копирования… нет, не требуется.

Может быть, исходный плакат имел повреждение в лог-файлах? Но, скорее всего, не просто сервер отключился на день.


извлечен из /usr/share/doc/mysql-server-5.1/README.Debian.gz, что, вероятно, имеет смысл и для серверов, отличных от debian:

* ДОПОЛНИТЕЛЬНЫЕ ЗАМЕЧАНИЯ ПО РЕПЛИКАЦИИ
===============================
Если сервер MySQL действует как ведомое устройство репликации, вам не следует
установите --tmpdir, чтобы указать на каталог в файловой системе на основе памяти или на
каталог, который очищается при перезапуске хоста сервера. Репликация
ведомому нужны некоторые из его временных файлов, чтобы пережить перезагрузку машины, поэтому
что он может реплицировать временные таблицы или операции LOAD DATA INFILE. Если
файлы во временном каталоге файлов теряются при перезапуске сервера,
репликация не удалась.

вы можете использовать что-то вроде sql: показать переменные, такие как 'tmpdir'; выяснить.

bksunday
источник
Будут ли базы данных синхронизироваться автоматически между собой? Например, я пишу мастеру, будет ли ведомое устройство обновляться автоматически?
TransformBinary
2

Добавляем к популярному ответу эту ошибку:

"ERROR 1200 (HY000): The server is not configured as slave; fix in config file or with CHANGE MASTER TO",

Репликация с раба одним выстрелом:

В одном окне терминала:

mysql -h <Master_IP_Address> -uroot -p

После подключения

RESET MASTER;
FLUSH TABLES WITH READ LOCK;
SHOW MASTER STATUS;

Статус отображается, как показано ниже: Обратите внимание, что номер позиции может быть разным!

+------------------+----------+--------------+------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000001 |      98  | your_DB      |                  |
+------------------+----------+--------------+------------------+

Экспортируйте дамп аналогично тому, как он описал " через другой терминал "!

Выйдите и подключитесь к своей собственной БД (которая является подчиненной):

mysql -u root -p

Введите следующие команды:

STOP SLAVE;

Импортируйте дамп, как указано (в другом терминале, конечно!), И введите следующие команды:

RESET SLAVE;
CHANGE MASTER TO 
  MASTER_HOST = 'Master_IP_Address', 
  MASTER_USER = 'your_Master_user', // usually the "root" user
  MASTER_PASSWORD = 'Your_MasterDB_Password', 
  MASTER_PORT = 3306, 
  MASTER_LOG_FILE = 'mysql-bin.000001', 
  MASTER_LOG_POS = 98; // In this case

После регистрации установите параметр server_id (обычно для новых / не реплицируемых БД он не установлен по умолчанию),

set global server_id=4000;

Теперь запустим раб.

START SLAVE;
SHOW SLAVE STATUS\G;

Результат должен быть таким же, как он описал.

  Slave_IO_Running: Yes
  Slave_SQL_Running: Yes

Примечание: после репликации главный и подчиненный пароль используют один и тот же пароль!

кудрявый
источник
Будут ли базы данных синхронизироваться автоматически между собой? Например, я пишу мастеру, будет ли ведомое устройство обновляться автоматически?
TransformBinary
1

Восстановление ведомого устройства с использованием LVM

Вот метод, который мы используем для восстановления ведомых устройств MySQL с помощью Linux LVM. Это гарантирует стабильный снимок и требует минимального времени простоя вашего мастера.

Установите максимальный процент грязных страниц innodb равным нулю на главном сервере MySQL. Это заставит MySQL записать все страницы на диск, что значительно ускорит перезапуск.

set global innodb_max_dirty_pages_pct = 0;

Чтобы отслеживать количество грязных страниц, выполните команду

mysqladmin ext -i10 | grep dirty

Как только число перестанет уменьшаться, вы достигнете точки для продолжения. Затем сбросьте мастер, чтобы очистить старые журналы бункеров / журналы реле:

RESET MASTER;

Запустите lvdisplay, чтобы получить LV Path

lvdisplay

Результат будет выглядеть так

--- Logical volume ---
LV Path                /dev/vg_mysql/lv_data
LV Name                lv_data
VG Name                vg_mysql

Завершите работу основной базы данных с помощью команды

service mysql stop

Затем сделайте снимок, mysql_snapshot будет новым именем логического тома. Если двоичные журналы находятся на диске с ОС, они также должны быть сняты.

lvcreate --size 10G --snapshot --name mysql_snapshot /dev/vg_mysql/lv_data

Снова запустите мастер с помощью команды

service mysql start

Восстановить настройки грязных страниц по умолчанию

set global innodb_max_dirty_pages_pct = 75;

Снова запустите lvdisplay, чтобы убедиться, что снимок есть и виден

lvdisplay

Выход:

--- Logical volume ---
LV Path                /dev/vg_mysql/mysql_snapshot
LV Name                mysql_snapshot
VG Name                vg_mysql

Смонтировать снимок

mkdir /mnt/mysql_snapshot
mount /dev/vg_mysql/mysql_snapshot /mnt/mysql_snapshot

Если у вас уже запущено подчиненное устройство MySQL, его необходимо остановить.

service mysql stop

Далее вам нужно очистить папку данных MySQL

cd /var/lib/mysql
rm -fr *

Вернуться к мастеру. Теперь выполните синхронизацию снимка с ведомым устройством MySQL.

rsync --progress -harz /mnt/mysql_snapshot/ targethostname:/var/lib/mysql/

После завершения rsync вы можете размонтировать и удалить снимок

umount /mnt/mysql_snapshot
lvremove -f /dev/vg_mysql/mysql_snapshot

Создайте пользователя репликации на главном сервере, если старый пользователь репликации не существует или пароль неизвестен

GRANT REPLICATION SLAVE on *.* to 'replication'@'[SLAVE IP]' identified by 'YourPass';

Убедитесь, что файлы данных / var / lib / mysql принадлежат пользователю mysql, в таком случае вы можете пропустить следующую команду:

chown -R mysql:mysql /var/lib/mysql

Далее запишите позицию бинлога

ls -laF | grep mysql-bin

Вы увидите что-то вроде

..
-rw-rw----     1 mysql mysql  1073750329 Aug 28 03:33 mysql-bin.000017
-rw-rw----     1 mysql mysql  1073741932 Aug 28 08:32 mysql-bin.000018
-rw-rw----     1 mysql mysql   963333441 Aug 28 15:37 mysql-bin.000019
-rw-rw----     1 mysql mysql    65657162 Aug 28 16:44 mysql-bin.000020

Здесь главный файл журнала - это файл с наибольшим номером в последовательности, а позиция журнала - это размер файла. Запишите эти значения:

master_log_file=mysql-bin.000020
master_log_post=65657162

Затем запустите подчиненный MySQL

service mysql start

Выполните команду изменения главного устройства на подчиненном устройстве, выполнив следующие действия:

CHANGE MASTER TO 
master_host="10.0.0.12", 
master_user="replication", 
master_password="YourPass", 
master_log_file="mysql-bin.000020", 
master_log_pos=65657162; 

Наконец запустить раб

SLAVE START;

Проверить статус ведомого:

SHOW SLAVE STATUS;

Убедитесь, что Slave IO запущен и нет ошибок подключения. Удачи!

BR, Юха Вехния

Я недавно написал об этом в своем блоге, который находится здесь ... Там есть еще несколько подробностей, но история та же.

http://www.juhavehnia.com/2015/05/rebuilding-mysql-slave-using-linux-lvm.html

Юха Вехния
источник
1

Мастер :

mysqldump -u root -p --all-databases --master-data | gzip > /tmp/dump.sql.gz  

scp master:/tmp/dump.sql.gz slave:/tmp/ Переместить файл дампа на подчиненный сервер

Раб:

STOP SLAVE;

zcat /tmp/dump.sql.gz | mysql -u root -p

START SLAVE;
SHOW SLAVE STATUS;  

ПРИМЕЧАНИЕ :
На главном SET GLOBAL expire_logs_days = 3сервере вы можете запустить бинарные журналы в течение 3 дней в случае проблем с подчиненным устройством.

М Ростами
источник
0

Я создал репозиторий GitHub со сценарием, чтобы быстро решить эту проблему. Просто измените пару переменных и запустите ее (сначала сценарий создает резервную копию вашей базы данных).

Я надеюсь, что это поможет вам (и другим людям тоже).

Как сбросить (повторно синхронизировать) репликацию MySQL Master-Slave

MCurbelo
источник
Я вижу, что сценарий всегда устанавливает позицию главного журнала на 1 и имя главного файла журнала. Я не знаю достаточно, чтобы быть уверенным, стоит ли мне это волновать или нет. Могли бы вы объяснить? Сейчас у меня позиция более 1 000 000. Означает ли это, что он попытается воспроизвести 1 миллион запросов, прежде чем наберет скорость? Нет ли шансов на повреждение при воспроизведении этих запросов с существующими данными? Мне интересно, почему бы не в сценарии при выполнении дампа mysql использовать параметр --master-data = 2, а затем вытащить файл и поместить его из дампа, чтобы установить их?
Джозия
0

Мы используем метод репликации MySQL master-master, и если один сервер MySQL говорит, что 1 удален из сети, он повторно подключается после восстановления соединения, и все записи, которые были зафиксированы на сервере 2, который был в сети, передаются к серверу 1, который потерял соединение после восстановления. Подчиненный поток в MySQL по умолчанию пытается подключиться к своему ведущему через каждые 60 секунд. Это свойство можно изменить, поскольку MySQL имеет флаг «master_connect_retry = 5», где 5 находится в секундах. Это означает, что нам нужно повторять попытку каждые 5 секунд.

Но вам нужно убедиться, что сервер, который потерял соединение, не совершает никаких фиксаций в базе данных, так как вы получаете повторяющийся код ошибки ключа: 1062

параг гупта
источник