Log relay MySQL rusak, bagaimana cara memperbaikinya? Sudah mencoba tetapi gagal

25

Relay MySQL v5.1.61 rusak ketika mesin tiba-tiba mati. Saya mencoba memperbaikinya tetapi tidak berhasil.
- Bagaimana saya memperbaikinya? Apakah saya melakukan sesuatu yang salah?

Sejauh yang saya baca, log relay MySQL yang rusak mudah diperbaiki:

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

di mana Relay_Master_Log_Filedan Exec_Master_Log_Posterdaftar oleh:
mysql> show slave status;

Namun ketika saya melakukannya change master status ..., saya mendapat kesalahan pelanggaran kunci primer. Bagaimana mungkin? Apakah prosedur di atas tidak benar, atau apakah beberapa +1 hilang?

(Untuk saat ini saya baru saja mengimpor ulang mysqldump - master-data dari master ke slave, dan ini menyelesaikan masalah. Namun, di masa depan, melakukan hal itu mungkin tidak sesuai.)


Berikut ini rincian tentang masalah khusus saya:

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.

Dan inilah yang saya lakukan:

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;

Dan inilah yang terjadi, kesalahan PK:

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

Saya pikir saya mengikuti prosedur yang disarankan (lihat tautan di bawah), masih ada kesalahan PK :-(? Http://bugs.mysql.com/bug.php?id=26489 , cari "Penanganan Masalah". Http: //mhbarr.wordpress.com/2013/07/26/mysql-slave-corrupted-relay-log/ /programming//a/14438408

KajMagnus
sumber
1
Ya, sepertinya itu seharusnya bekerja, dan sebenarnya sepertinya itu benar-benar bekerja, karena mungkin log relay asli, sebelum bagian korup, sudah melakukan penyisipan pada posisi master log, tetapi tidak dapat memajukan ditampilkan posisi master ke pointer berikutnya, karena pointer itu disimpan di log relai (yang rusak.) Jadi, Anda mungkin lolos dengan melewatkan acara itu dan pindah ke acara berikutnya, lalu memverifikasi bahwa master dan slave benar-benar memiliki data yang identik ... Saya belum memiliki kesempatan untuk meninjau pertanyaan dengan cukup detail.
Michael - sqlbot
1
Terima kasih @ Michael-sqlbot, maka saya pikir jika masalah ini terjadi lagi, saya akan melakukan SET GLOBAL sql_slave_skip_counter = 1; START SLAVE;dan melewatkan satu peristiwa pada budak, dan berharap itu membantu - apakah itu masuk akal? Jika tidak membantu (jika masih ada kesalahan PK), saya akan mengimpor dump --master-datalagi.
KajMagnus

Jawaban:

35

Galat: Last_SQL_Errno: 1594 Last_SQL_Error: Kegagalan pembacaan log relai: Tidak dapat menguraikan entri log peristiwa relai.

Kesalahan ini berarti bahwa file log master rusak atau file log relai rusak.

  • Sebelum melakukan apa pun buat cadangan semua database, log, server gambar, ulangi, beberapa kali, dan hanya lanjutkan dengan risiko Anda sendiri.

Jalankan pertama "tampilkan status budak \ G" pada budak dan perhatikan:

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

Pertama-tama kita ingin memastikan bahwa file master log masih utuh, jadi lompat ke server master dan temukan Relay_Master_Log_File (centang / var / log / mysql) dan jalankan perintah berikut:

mysqlbinlog mysql-bin.000026

Log akan ditampilkan tetapi mudah-mudahan Anda tidak akan melihat pesan kesalahan. Jika Anda melihat pesan kesalahan maka master log rusak dan Anda mungkin harus melakukan gambar ulang.

Selanjutnya jalankan perintah yang sama pada log relai slave (sering di / var / lib / mysql)

mysqlbinlog mysqld-relay-bin.000056

Anda mungkin akan melihat beberapa kesalahan yang menunjukkan korupsi yang telah menghentikan replikasi, seperti ini:

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#

Jika Anda melihat kesalahan maka log baik-baik saja pada master dan hanya log relay slave yang korup. Ini adalah berita baik, kita dapat mengatur ulang budak dan memberi tahu detail master dan dari mana harus melanjutkan. Jika Anda tidak melihat kesalahan apa pun kemudian berhenti membaca sekarang, Anda memiliki masalah yang berbeda.

Jika slave relay log memiliki kesalahan, jalankan perintah berikut untuk mereset slave dan log yang rusak terhubung kembali ke master, dapatkan log ok dan mulailah slaving lagi. Perhatikan bahwa MASTER_LOG_POS adalah Exec_Master_Log_Pos, dan MASTER_LOG_FILE adalah Relay_Master_Log_File( BUKAN yang pertama, yang cocok dengan log relai yang telah diambil dan perlu dibuang) baik dari perintah pertama.

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)
A.Badger
sumber
2
Hai, terima kasih atas jawaban Anda. Jika Anda membaca pertanyaan dengan seksama, Anda akan melihat kata "Relay log rusak" - itu karena kami telah menggunakan mysqlbinlogcara yang Anda sarankan, dan mengetahui bahwa log relai (bukan master log) telah rusak. Mengenai perbaikan yang Anda sarankan - jika Anda membaca pertanyaan dengan seksama, Anda akan melihat bahwa perbaikan yang Anda sarankan persis seperti yang telah kami coba. Tapi itu tidak berhasil, dan itulah pertanyaannya. - Tetapi jawaban Anda mungkin berguna untuk orang lain dengan masalah yang sama.
KajMagnus
2
Ini mungkin harus dicatat, bahwa MASTER_LOG_FILEdalam CHANGE MASTERharus diambil dari Relay_Master_Log_Filedan bukan dari Master_Log_File. Biasanya mereka akan sama tetapi mungkin tidak selalu demikian (lihat percona.com/blog/2008/07/07/… ).
brablc
@ brablc benar. Relay_Master_Log_Fileharus digunakan, bukan Master_Log_File. Lihat juga: percona.com/blog/2008/07/07/...
Mircea Vutcovici
dalam kebanyakan kasus, tidak perlu reset slave allkarena pengaturan master tidak perlu diubah (mis. master_host, master_user, master_password), hanya MASTER_LOG_FILE dan MASTER_LOG_POS, maka reset_slaveitu sudah cukup
ympostor
Pertanyaan dan jawaban ini telah menyelamatkan pantat saya beberapa kali. Terima kasih.
Artem Russakovskii
8

[Memperbaiki replikasi MySQL setelah log relay budak rusak]

Replikasi MySQL pada slave (versi 5.XX) telah berhenti. Slave_IO_Running ditandai sebagai Ya, tetapi Slave_SQL_Running sebagai No. Slave berhenti / mulai yang sederhana tidak membantu sehingga diperlukan analisis masalah lebih lanjut. Tampaknya log relay slave saat ini rusak karena pengujian dengan "mysqlbinlog" telah mencetak kesalahan. Oleh karena itu, solusinya adalah membuang binlog relai saat ini dan mengarahkan slave ke posisi master binlog terakhir.

Untuk memperbaiki kesalahan, file binlog saat ini pada slave harus dibuang dan atur posisi baru. Sebelum menetapkan posisi binlog baru itu penting untuk diingat Relay_Master_Log_File dan Exec_Master_Log_Pos nilai-nilai dari server slave rusak menggunakan perintah TAMPILKAN budak STATUS \ G :

Relay_Master_Log_File: mysql-bin.002045
Exec_Master_Log_Pos: 103641119

OK, dengan nilai-nilai ini, posisi binlog baru dapat diatur:

# 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;

Hanya untuk dicatat yang reset slaveakan dihapusmaster.info , relay-log.infodan semua file log relai, sehingga tidak perlu membersihkan sisa dalam /var/lib/mysqldirektori.

Mohamed Ayas
sumber
1
Jawaban yang bagus - biasanya kita tidak perlu mengganti master host, kata sandi dll. Thx!
andy250
3

Saya tahu ini sudah lebih dari setahun, tapi inilah yang mungkin terjadi pada masalah khusus ini.

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;

Itu terlihat seperti yang seharusnya memperbaikinya karena menghapus log relay yang korup.

Lalu, Anda mendapat kesalahan PK 1062. Mengapa?

Ada bug yang luar biasa ( http://bugs.mysql.com/bug.php?id=60847 ) yang masih aktif di MySQL 5.5

Meskipun bug berhubungan dengan menggunakan mysql --single-transaction --flush-logs, ada kekhasan terkait.

Saya telah melihat kekhasan itu pada beberapa server EC2 berjalan sebagai Budak untuk klien minggu lalu di MySQL 5.5.15

Pada Master, ada beberapa baris aneh yang diperluas INSERT di mana setiap tuple yang dimasukkan adalah SELECT. Apa yang terjadi adalah bahwa LAST_INSERT_ID dalam log relai, yang membentuk kenaikan otomatis berikutnya untuk ditetapkan, sudah digunakan pada Slave karena sebelumnya memasukkan banyak baris.

SERI serial dalam log relai tampak seperti

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

Daftar kolom tidak menyertakan kunci primer numerik. Ketika kesalahan 1062 kembali, saya akan menggunakan kueri yang sama dengan yang gagal, jalankan kueri secara manual. Itu tidak mencapai kesalahan 1062. Kemudian, saya menjalankan perintah skip slave yang biasa:

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

Kemudian, replikasi menyusul.

Saran saya adalah membuat serial dengan benar INSERT Anda pada Master karena situasi seperti bug ini sebenarnya cukup dapat dihindari.

RolandoMySQLDBA
sumber
1

Anda telah melakukannya dengan benar (seperti yang sudah dikatakan oleh orang lain).

Satu-satunya masalah adalah dengan file master.info (berisi informasi tentang posisi di master mysql-bin.log) karena file ini tidak disinkronkan ke disk setelah setiap permintaan diproses.

Jadi info Anda tentang posisi dalam log master sudah usang dan Anda memproses kueri yang sudah diproses yang perlu dilewati SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1;.

Sayangnya, jika Anda menggunakan beberapa permintaan seperti UPDATE table SET counter=counter+1 WHERE id = 12345dan menggunakan binlog_format=STATEMENTbasis data Anda mungkin tidak sinkron, saya kira.

Anda dapat memberi tahu server MySQL untuk menyinkronkan master.info setelah setiap peristiwa dengan mengatur variabel sync_master_info tetapi mungkin akan memiliki konsekuensi kinerja yang sangat besar.

Dragonn
sumber