Як повторно синхронізувати БД Mysql, якщо Master і slave мають різні бази даних у випадку реплікації Mysql?


139

Mysql Server1працює як MASTER .
Mysql Server2працює як SLAVE .

Тепер реплікація БД відбувається від MASTER до SLAVE .

Server2вилучається з мережі та повторно підключається назад через 1 день. Після цього виникає невідповідність бази даних в master і slave.

Як знову синхронізувати БД, оскільки після відновлення БД, взятого з Master в Slave, також не вирішується проблема?

Відповіді:


287

Це повна покрокова процедура для повторної синхронізації реплікації головного ведомого з нуля:

У майстра:

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
Якщо визначена INNODB дабатаза та інші складні типи стовпців, такі як BLOB та DATE, я рекомендую використовувати такі перемикачі:--opt --single-transaction --comments --hex-blob --dump-date --no-autocommit --all-databases
Ken Pega

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
Чи є спосіб це автоматизувати?
Метафаніель

26

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

Якщо ви збираєтесь використовувати mysqldump, вам слід покластися на параметр --master-data, щоб захистити від помилок людини і якнайшвидше звільнити блоки майстра.

Припустимо, що майстер - 192.168.100.50, а підлеглий - 192.168.100.51, на кожному сервері налаштований окремий ідентифікатор сервера, майстер увімкнено бінарний вхід і підлеглий має лише читання = 1 у my.cnf

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

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

Випустіть ГРАНТ на майстра, щоб раб використовував:

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 на підлеглому, щоб зберігати той самий кореневий пароль, що і головний.

Якщо ви перебуваєте у версії 5.1+, найкраще спочатку встановити binlog_format мастера на MIXED або ROW. Слідкуйте за тим, щоб події, записані в рядки, повільні для таблиць, у яких відсутні первинний ключ. Зазвичай це краще, ніж альтернативна (і за замовчуванням) конфігурація binlog_format = заява (на головний), оскільки це менше шансів видавати неправильні дані на підлеглому.

Якщо потрібно (але, мабуть, не слід) фільтрувати реплікацію, зробіть це за допомогою параметрів підлеглих repplic-wild-do-table = dbname.% Або replicate-wild-ignore-table = badDB.% Та використовуйте лише binlog_format = рядок

Цей процес буде утримувати глобальний замок на ведучому протягом тривалості команди mysqldump, але інакше не вплине на майстер.

Якщо ви спокушаєтеся використовувати mysqldump --master-data --all-databases --single-транзакції (тому що ви використовуєте лише таблиці InnoDB), вам, можливо, краще послужити, використовуючи MySQL Enterprise Backup або відкриту реалізацію під назвою xtrabackup (люб’язно надано Перкона)


3
Якщо ви хочете просто відновити існуючий підлеглий, ви можете виконати вищезазначений процес, пропустивши кілька кроків: команда ГРАНТ і вручну ЗМІНІ МАЙСТЕР
Застаріла

Питання 1: Що стосується Windows, що було б еквівалентом zcat. Питання 2: Яким чином цей mysqldumpтариф має великі бази даних з точки зору продуктивності? Будь-який спосіб використовувати SELECT INTO OUTFILEта LOAD DATAплавно використовувати запропонований процес? (Оскільки вони, як правило, працюють швидше)
Ifedi Okonkwo

Не потрібно STOP SLAVEдесь у процесі?
Девід В.

16

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


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

7

Думаю, утиліти Maatkit допомагають вам! Ви можете використовувати mk-table-sync. Перейдіть за цим посиланням: http://www.maatkit.org/doc/mk-table-sync.html


Я думаю, йому буде потрібно тимчасово припинити запис під час виконання сценарію.
Ztyx

Це все ще чудово працює. Хоча інструменти були перейменовані, і тепер це називається pt-table-sync. Насправді, проте, я виявив, що їх інструмент для перезавантаження pt-slave працює як магія.
mlerley

7

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

На Master зробіть резервну копію таким чином:
mysqldump --skip-lock-table --single-транзакція --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

Підключіться до Slave mysql і запустіть команду, як це: ЗМІНІТЬ МАЙСТЕР MASTER_HOST = 'master-server-ip', MASTER_USER = 'реплікація-користувач', MASTER_PASSWORD = 'slave-сервер-пароль', MASTER_LOG_FILE = 'значення зверху', MASTER_LOG_POS = значення зверху; НАЧАЛЬНИЙ СЛАВ;

Щоб перевірити прогрес Slave: SHOW SLAVE STATUS;

Якщо все добре, Last_Error буде порожнім, а Slave_IO_State повідомить про "чекання від майстра надсилання події". Шукайте Seconds_Behind_Master, який вказує, наскільки далеко позаду. YMMV. :)


3
Це працює, і якщо підлеглий вже налаштований і лише вийшов із синхронізації, вам не потрібно запускати ЗМІНИ МАЙСТЕР; просто вкажіть --master-data=1(або просто --master-data).
LSerni

5

Ось що я зазвичай роблю, коли підлеглий mysql виходить із синхронізації. Я переглянув синхронізацію mk-table, але подумав, що розділ "Ризики" виглядає страшно.

Про Майстер:

SHOW MASTER STATUS

Виведені стовпці (Файл, Позиція) нам трохи будуть корисні.

На рабі:

STOP SLAVE

Потім скиньте головний db та імпортуйте його в підлеглий db.

Потім запустіть наступне:

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

Де [Файл] та [Положення] - значення, що виводяться із "ШОУ МАЙСТЕРСЬКОГО СТАТУСУ", що надходить вище.

Сподіваюся, це допомагає!


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

5

Продовження відповіді Девіда ...

Використання SHOW SLAVE STATUS\Gдасть зрозумілий для людини вихід.


Будь-який спосіб оформити сторінку результатами?
Йосія

"пейджер більше" Я думаю, що це зроблять
Ян

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 прямо зараз після короткого відключення мережі.
Майк Ш

10
Це вводить в оману, як тільки ви скидаєте раба, Salve повністю втратив знання про те, де господар.
Qian Chen

2

Ось повна відповідь, яка, сподіваємось, допоможе іншим ...


Я хочу налаштувати реплікацію mysql за допомогою master та slave, і оскільки єдине, що я знав, це те, що він використовує файли журналів для синхронізації, якщо підлеглий переходить в офлайн і виходить із синхронізації, теоретично йому потрібно лише підключитися назад своєму майстру і продовжуйте читати файл журналу з того місця, де він зупинився, як згадував користувач malonso.

Ось ось результат тесту після налаштування головного і веденого, як згадується: http://dev.mysql.com/doc/refman/5.0/en/replication-howto.html ...

Якщо ви користуєтесь рекомендованою конфігурацією master / slave і не пишете на підлеглого, він і я там, де це правильно (що стосується mysql-сервера 5.x). Мені навіть не потрібно було використовувати "START SLAVE;", він просто наздогнав свого господаря. Але є 88000 за замовчуванням, що-небудь повторюється кожні 60 секунд, тому я гадаю, що якщо ви будете вичерпані, вам, можливо, доведеться запустити або перезапустити підлеглий. У будь-якому випадку, для таких, як я, хто хотів дізнатися, чи потрібно, щоб раб переходив офлайн і знову створював резервні копії, вимагає вручну втручання .. ні, це не так.

Можливо, оригінальний плакат мав пошкодження у файлах журналів? Але, швидше за все, це не просто сервер, який виходить офлайн на день.


витягнуто з /usr/share/doc/mysql-server-5.1/README.Debian.gz, що, мабуть, має сенс і для недебінських серверів:

* ДАЛЬНІ ПРИМІТКИ ПРО ЗАМОВЛЕННЯ
=================================
Якщо сервер MySQL діє як ведений реплікації, ви не повинні
встановити --tmpdir для вказівки на каталог у файловій системі на основі пам'яті або на
каталог, який очищається при перезапуску хоста сервера. Реплікація
Slave потребує деяких своїх тимчасових файлів, щоб пережити перезапуск машини
що він може реплікувати тимчасові таблиці або операції ЗАВАНТАЖЕННЯ ДАНИХ INFILE. Якщо
Файли у тимчасовому каталозі файлів втрачаються, коли сервер перезавантажується,
реплікація не вдається.

ви можете використовувати щось sql на зразок: показувати змінні типу 'tmpdir'; знайти.


Чи автоматично обидва бази даних синхронізуються між собою? Наприклад, я пишу майстру, чи буде Slave оновлюватися автоматично?
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

Примітка: Після тиражування майстер і підлеглий поділяють той самий пароль!


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

1

Відновлення раба за допомогою LVM

Ось метод, який ми використовуємо для відновлення рабів MySQL за допомогою Linux LVM. Це гарантує послідовний знімок, вимагаючи дуже мінімального простою для вашого майстра.

Встановіть innodb max брудних сторінок відсотків до нуля на майстер-сервері 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, Juha Vehnia

Нещодавно я написав це у своєму блозі, який можна знайти тут ... Є ще кілька деталей, але історія така ж.

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


0

Я створив рето GitHub зі сценарієм, щоб швидко вирішити цю проблему. Просто змініть пару змінних і запустіть її (По-перше, сценарій створює резервну копію вашої бази даних).

Я сподіваюся, що це допоможе вам (і іншим людям теж).

Як скинути (повторно синхронізувати) MySQL Master-Slave реплікацію


Я бачу, що сценарій завжди встановлює положення головного журналу на 1 та ім'я головного файлу журналу. Я не знаю достатньо, щоб бути впевненим у тому, чи повинен мене це турбувати чи ні. Чи можете ви пояснити? В даний час я маю посаду понад 1 000 000. Чи означає це, що вона намагатиметься відтворити 1mil запитів, перш ніж досягти швидкості? Чи немає шансів на корупцію при відтворенні цих запитів на основі наявних даних? Мені цікаво, чому в сценарії під час виконання дампів mysql не використовується параметр --master-data = 2, а потім витягніть файл і поз з дампа, щоб їх встановити?
Йосія

0

Ми використовуємо техніку реплікації Master-master MySQL, і якщо один сервер MySQL скаже, що 1 видалено з мережі, він відновиться після відновлення з'єднання, і всі записи, які були зроблені на сервері 2, який був у мережі, передаються до сервера 1, який втратив з'єднання після відновлення. Підлеглий потік у MySQL намагається підключитися до свого майстра через кожні 60 секунд за замовчуванням. Цю властивість можна змінити, оскільки MySQL має прапор "master_connect_retry = 5", де 5 знаходиться в сек. Це означає, що ми хочемо повторити повтор через кожні 5 секунд.

Але вам потрібно переконатися, що сервер, який втратив з'єднання, не здійснює жодних зобов'язань у базі даних, оскільки ви отримуєте дублікат ключа помилки Код помилки: 1062


0

Майстер :

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 днів у разі проблем з рабом.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.