Журнал реле MySQL пошкоджений, як це виправити? Спробував, але не вдався


25

Реле MySQL v5.1.61 пошкодилось, коли машина раптово вимкнулася. Я спробував це виправити, але це не вийшло.
- Як це виправити? Я щось зробив не так?

Наскільки я читав, пошкоджені журнали ретрансляції MySQL легко виправляються:

change master to master_log_file='<Relay_Master_Log_File>',
                 master_log_pos=<Exec_Master_Log_Pos>;

де Relay_Master_Log_Fileі Exec_Master_Log_Posперераховано:
mysql> show slave status;

Однак коли я це зробив change master status ..., у мене з’явилася помилка порушення первинного ключа. Як це можливо? Чи описана вище процедура не є правильною, або, наприклад, відсутній +1?

(Наразі я просто повторно імпортував - master-data mysqldump від ведучого до раба, і це вирішило проблему. Однак, в майбутньому, це може виявитися не доцільним.)


Тут наведено детальні відомості про мою конкретну проблему:

mysql> show slave status \G
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: the-master-host
                  Master_User: replication
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000021
          Read_Master_Log_Pos: 33639968
               Relay_Log_File: mysql-relay-bin.000271
                Relay_Log_Pos: 2031587
        Relay_Master_Log_File: mysql-bin.000020
             Slave_IO_Running: Yes
            Slave_SQL_Running: No
              Replicate_Do_DB: the_database
          Replicate_Ignore_DB: 
           Replicate_Do_Table: 
       Replicate_Ignore_Table: 
      Replicate_Wild_Do_Table: 
  Replicate_Wild_Ignore_Table: 
                   Last_Errno: 1594
                   Last_Error: Relay log read failure: Could not parse relay log event entry. The possible reasons are: the master's binary log is corrupted (you can check this by running 'mysqlbinlog' on the binary log), the slave's relay log is corrupted (you can check this by running 'mysqlbinlog' on the relay log), a network problem, or a bug in the master's or slave's MySQL code. If you want to check the master's binary log or slave's relay log, you will be able to know their names by issuing 'SHOW SLAVE STATUS' on this slave.
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 66395191
              Relay_Log_Space: 36559177
              Until_Condition: None
               Until_Log_File: 
                Until_Log_Pos: 0
           Master_SSL_Allowed: No
           Master_SSL_CA_File: 
           Master_SSL_CA_Path: 
              Master_SSL_Cert: 
            Master_SSL_Cipher: 
               Master_SSL_Key: 
        Seconds_Behind_Master: NULL
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error: 
               Last_SQL_Errno: 1594
               Last_SQL_Error: Relay log read failure: Could not parse relay log event entry. The possible reasons are: the master's binary log is corrupted (you can check this by running 'mysqlbinlog' on the binary log), the slave's relay log is corrupted (you can check this by running 'mysqlbinlog' on the relay log), a network problem, or a bug in the master's or slave's MySQL code. If you want to check the master's binary log or slave's relay log, you will be able to know their names by issuing 'SHOW SLAVE STATUS' on this slave.

І ось що я зробив:

mysql> stop slave;
mysql> reset slave;
mysql> change master to master_host='the-master-host', master_user='replication', master_password='the-password', master_log_file='mysql-bin.000020', master_log_pos=66395191;
mysql> start slave;

І ось що сталося, помилка ПК:

131122 15:17:29 [Note] Slave I/O thread: connected to master 'replication@the-master-host:3306',replication started in log 'mysql-bin.000020' at position 66395191
131122 15:17:29 [ERROR] Slave SQL: Error 'Duplicate entry '71373' for key 'PRIMARY'' on query. Default database: 'the_database'. Query: 'insert into ...  values ...', Error_code: 1062
131122 15:17:29 [Warning] Slave: Data truncated for column 'date' at row 1 Error_code: 1265
131122 15:17:29 [Warning] Slave: Duplicate entry '71373' for key 'PRIMARY' Error_code: 1062

Я думаю, що я дотримувався рекомендованої процедури (див. Посилання трохи нижче), все ж сталася помилка ПК :-(? Http://bugs.mysql.com/bug.php?id=26489 , пошук "Обхідні шляхи". Http: //mhbarr.wordpress.com/2013/07/26/mysql-slave-corrupted-relay-log/ /programming//a/14438408


1
Так, це здається, що він мав би спрацювати, і насправді це виглядає так, що він, мабуть, справді спрацював, як, можливо, оригінальний журнал ретрансляції перед корумпованою секцією вже зробив вставку в цьому положенні головного журналу, але не зміг просунути відображається головна позиція до наступного вказівника, оскільки цей покажчик зберігається в журналі ретрансляції (який був пошкодженим.) Отже, ви могли б уникнути пропуску цієї події та переходу до наступної події, а потім перевірити, що власник і підлеглий насправді мали однакові дані ... У мене ще не було можливості переглянути питання досить детально.
Michael - sqlbot

1
Дякую @ Michael-sqlbot, то я думаю, що якщо ця проблема повториться, я зроблю SET GLOBAL sql_slave_skip_counter = 1; START SLAVE;і пропущу одну подію на рабі, і сподіваюся, що це допоможе - чи має це сенс? Якщо це не допоможе (якщо все ще є помилка ПК), я імпортую дамп --master-dataізнов.
KajMagnus

Відповіді:


35

Помилка: Last_SQL_Errno: 1594 Last_SQL_Error: Помилка зчитування журналу ретрансляції: Не вдалося проаналізувати запис події журналу ретрансляції.

Ця помилка означає, що або файл головного журналу пошкоджений, або файл журналу ретрансляції пошкоджений.

  • Перш ніж робити щось резервне копіювання всіх ваших баз даних, журналів, серверів зображень, повторіть кілька разів і продовжуйте лише на свій страх і ризик.

Спочатку запустіть "показати статус підлеглого \ G" на підлеглому та зверніть увагу:

Master_Log_File: mysql-bin.000026
Read_Master_Log_Pos: 2377104
Relay_Log_File: mysqld-relay-bin.000056
Relay_Log_Pos: 1097303
Relay_Master_Log_File: mysql-bin.000026
Exec_Master_Log_Pos: 1097157

Спочатку ми хочемо переконатися, що файл основного журналу є непорушним, тому перескочіть на головний сервер і знайдіть Relay_Master_Log_File (check / var / log / mysql) та запустіть таку команду:

mysqlbinlog mysql-bin.000026

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

Далі запустіть ту саму команду в журналі реєстрованого реле (часто в / var / lib / mysql)

mysqlbinlog mysqld-relay-bin.000056

Ви, ймовірно, побачите деякі помилки, що показують корупцію, яка зупинила реплікацію, наприклад:

ERROR: Error in Log_event::read_log_event(): 'read error', data_len: 336, event_type: 2
ERROR: Could not read entry at offset 1097414: Error in log format or read error.
DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
root@db:/var/lib/mysql#

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

Якщо журнал реєстрованого пристрою має помилки, виконайте наступні команди, щоб скинути підлеглий та пошкоджені журнали, підключившись до головного, дістаньте журнали "ОК" та почніть повторне підключення. Зауважте, що MASTER_LOG_POS - це Exec_Master_Log_Pos, а MASTER_LOG_FILE - це Relay_Master_Log_File( НЕ перший, який відповідає логам ретрансляцій, які були отримані та які потрібно викинути) як з першої команди.

mysql> stop slave;
Query OK, 0 rows affected (0.14 sec)

mysql> reset slave all;
Query OK, 0 rows affected (0.43 sec)

mysql>  CHANGE MASTER TO MASTER_HOST='master.host.com', MASTER_USER='masteruser', MASTER_PASSWORD='masterpass', MASTER_LOG_FILE='mysql-bin.000026', MASTER_LOG_POS=1097157;
Query OK, 0 rows affected (0.93 sec)

mysql> start slave;
Query OK, 0 rows affected (0.00 sec)

2
Привіт, дякую за вашу відповідь. Якщо ви уважно прочитаєте запитання, ви помітите, що в ньому написано "Журнал ретрансляції пошкоджений" - це тому, що ми вже використовували mysqlbinlogзапропонований вами спосіб і з’ясували, що журнал ретрансляції (а не головний журнал) був пошкоджений. Якщо погодитись із запропонованим вами виправленням - якщо ви уважно прочитаєте запитання, ви помітите, що запропонований вами виправлення саме те, що ми вже намагалися. Але це не спрацювало, і ось про що йдеться. - Але ваша відповідь може бути корисною для інших людей із подібною проблемою.
KajMagnus

2
Напевно, слід зазначити, що MASTER_LOG_FILEв Росії CHANGE MASTERслід братиRelay_Master_Log_File а неMaster_Log_File . Зазвичай вони будуть однаковими, але це може бути не завжди (див. Percona.com/blog/2008/07/07/… ).
brablc

@brablc має рацію. Relay_Master_Log_Fileтреба використовувати, а не Master_Log_File. Дивіться також: percona.com/blog/2008/07/07/…
Mircea Vutcovici

у більшості випадків у цьому немає потреби reset slave all оскільки налаштування майстра не потрібно змінювати (наприклад, master_host, master_user, master_password), лише MASTER_LOG_FILE та MASTER_LOG_POS, то цього reset_slaveповинно вистачити
ympostor

Це запитання та відповідь уже кілька разів врятували мою недопалку. Дякую.
Артем Русаковський

8

[Виправлення реплікації MySQL після пошкодження журналу реле рабів]

Реплікація MySQL на підлеглому (версія 5.XX) зупинена. Slave_IO_Running було позначено як Так, але Slave_SQL_Running як ні. Простий підлеглий стоп / запуск не допоміг, тому необхідний подальший аналіз проблеми. Здавалося, що журнал реле поточного підлеглого був пошкоджений, оскільки тестування на "mysqlbinlog" надрукувало помилку. Тому рішенням було відмовитись від поточних реле бінлогів та вказати ведене місце на останнє головне бінлогічне положення.

Щоб виправити помилку, поточні файли бінарних файлів на підлеглому слід відкинути та встановити нове положення. Перш ніж встановлювати нову позицію бінарника, важливо пам’ятати значення Relay_Master_Log_File та Exec_Master_Log_Pos з пошкодженого підлеглого сервера за допомогою команди SHOW SLAVE STATUS \ G :

Relay_Master_Log_File: mysql-bin.002045
Exec_Master_Log_Pos: 103641119

Гаразд, за допомогою цих значень можна встановити нове бінлогічне положення:

# stop slave
mysql> stop slave;

# make slave forget its replication position in the master's binary log
mysql> reset slave;

# change slave to start reading from stopped position
mysql> change master to master_log_file='mysql-bin.002045', master_log_pos=103641119;

# start slave
mysql> start slave;

Просто зазначити це reset slave призведе до видалення master.info, relay-log.infoі всі файли журналу реле, так що це не потрібно , щоб очистити залишки в /var/lib/mysqlкаталозі.


1
Хороша відповідь - зазвичай нам не потрібно змінювати головний хост, пароль і т. Д. Thx!
andy250

3

Я знаю, що минуло більше року, але ось що може статися з цією конкретною проблемою.

mysql> stop slave;
mysql> reset slave;
mysql> change master to master_host='the-master-host', master_user='replication', master_password='the-password', master_log_file='mysql-bin.000020', master_log_pos=66395191;
mysql> start slave;

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

Тоді ви отримали помилку ПК 1062. Чому?

Виникла помилка ( http://bugs.mysql.com/bug.php?id=60847 ), яка все ще активна в MySQL 5.5

Хоча помилка стосується використання mysql --single-транзакції --flush-logs, існує відповідна примха.

Я бачив цю химерність на деяких серверах EC2, які працювали як Раби для клієнта лише минулого тижня в MySQL 5.5.15

У програмі Master було дивне кілька рядків, розширених INSERT, де кожен вставлений кортеж був SELECT. Сталося те, що LAST_INSERT_ID в журналі ретрансляцій, який формує наступний автоматичний приріст для призначення, вже використовувався на підлеглому через попередньо вставлені кілька рядків.

Виглядав серіалізований INSERT в журналі ретрансляції

INSERT INTO tablname (column,column) VALUES (value,value,...)

Список стовпців не містив числового первинного ключа. Коли помилка 1062 повернулася, я використовував би той самий запит, на якому не вдалося, запустити запит вручну. Помилка 1062 не потрапила. Потім я запустив звичайні команди пропускання підлеглого:

STOP SLAVE;
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1;
START SLAVE;
SET @sleepnumber = SLEEP(3);
SHOW SLAVE STATUS\G

Потім реплікація наздогнала.

Моя порада полягала б у тому, щоб належним чином серіалізувати свої ВИМІРКИ на Майстрі, тому що подібну помилку насправді можна уникнути.


1

Ви зробили це цілком правильно (як уже говорили інші).

Єдине питання полягає у файлі master.info (містить інформацію про позицію у master mysql-bin.log), оскільки цей файл не синхронізується з диском після кожного запиту, який обробляється.

Тож ваша інформація про позиції в журналі журналу застаріла, і ви обробляєте вже оброблені запити, з якими потрібно пропустити SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1;.

На жаль, якщо ви використовуєте такі запити, як, UPDATE table SET counter=counter+1 WHERE id = 12345і використання binlog_format=STATEMENTваших баз даних може не синхронізуватися.

Ви можете сказати серверу MySQL синхронізувати master.info після кожної події, встановивши змінну sync_master_info, але це, ймовірно, матиме величезні наслідки для продуктивності.

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