Nhật ký chuyển tiếp MySQL bị hỏng, làm thế nào để tôi sửa nó? Đã thử nhưng thất bại


25

Rơle MySQL v5.1.61 bị hỏng khi máy đột ngột tắt. Tôi đã cố gắng sửa nó nhưng nó không hoạt động.
- Làm thế nào để tôi sửa chữa nó? Tôi đã làm gì sai sao?

Theo như tôi đã đọc, các bản ghi chuyển tiếp MySQL bị hỏng rất dễ sửa:

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

ở đâu Relay_Master_Log_FileExec_Master_Log_Posđược liệt kê bởi:
mysql> show slave status;

Tuy nhiên, khi tôi làm change master status ..., tôi đã gặp một lỗi vi phạm khóa chính. Làm thế nào là có thể? Là quy trình trên không đúng, hay ví dụ như thiếu +1?

(Hiện tại, tôi chỉ cần nhập lại một mysqldump - dữ liệu chính từ chủ sang nô lệ và điều này đã giải quyết được vấn đề. Tuy nhiên, trong tương lai, việc đó có thể không phù hợp.)


Dưới đây là chi tiết về vấn đề cụ thể của tôi:

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.

Và đây là những gì tôi đã làm:

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;

Và đây là những gì đã xảy ra, một lỗi 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

Tôi nghĩ rằng tôi đã làm theo quy trình được đề xuất (xem các liên kết ngay bên dưới), vẫn có lỗi PK :-(? Http://bugs.mysql.com/orms.php?id=26361 , tìm kiếm "Giải pháp thay thế". Http: //mhbarr.wordpress.com/2013/07/26/mysql-slave-corrupted-relay-log/ /programming//a/14438408


1
Vâng, có vẻ như nó nên hoạt động, và thực sự có vẻ như nó thực sự đã hoạt động, vì có lẽ nhật ký chuyển tiếp ban đầu, trước phần bị hỏng, đã thực hiện thao tác chèn tại vị trí nhật ký chính đó, nhưng không thể tiến lên hiển thị vị trí chính cho con trỏ tiếp theo, vì con trỏ đó được lưu trong nhật ký chuyển tiếp (đã bị hỏng.) Vì vậy, bạn có thể đã bỏ qua sự kiện đó và chuyển sang sự kiện tiếp theo, sau đó xác minh rằng chủ và nô lệ thực sự có dữ liệu giống hệt nhau ... Tôi chưa có cơ hội để xem xét câu hỏi một cách chi tiết.
Michael - sqlbot

1
Cảm ơn @ Michael-sqlbot, sau đó tôi nghĩ rằng nếu vấn đề này xảy ra lần nữa, tôi sẽ làm SET GLOBAL sql_slave_skip_counter = 1; START SLAVE;và bỏ qua một sự kiện trên nô lệ, và hy vọng điều đó có ích - điều đó có hợp lý không? Nếu nó không hữu ích (nếu vẫn còn lỗi PK), tôi sẽ nhập lại một bãi chứa --master-data.
KajMagnus

Câu trả lời:


35

Lỗi: Last_Query_Errno: 1594 Last_Query_Error: Lỗi đọc nhật ký chuyển tiếp: Không thể phân tích mục nhập sự kiện nhật ký chuyển tiếp.

Lỗi này có nghĩa là tệp nhật ký chính bị hỏng hoặc tệp nhật ký chuyển tiếp bị hỏng.

  • Trước khi thực hiện bất kỳ việc gì, hãy sao lưu tất cả cơ sở dữ liệu, nhật ký, máy chủ hình ảnh của bạn, lặp lại, nhiều lần và chỉ tiếp tục chịu rủi ro.

Lần chạy đầu tiên "hiển thị trạng thái nô lệ \ G" trên nô lệ và ghi chú:

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

Trước tiên, chúng tôi muốn đảm bảo rằng tệp nhật ký chính còn nguyên vẹn, vì vậy hãy nhảy lên máy chủ chính và tìm Relay_Master_Log_File (check / var / log / mysql) và chạy lệnh sau:

mysqlbinlog mysql-bin.000026

Nhật ký sẽ được hiển thị nhưng hy vọng bạn sẽ không thấy bất kỳ thông báo lỗi nào. Nếu bạn thấy thông báo lỗi thì nhật ký chính bị hỏng và có thể bạn sẽ phải hình ảnh lại.

Tiếp theo chạy cùng một lệnh trên nhật ký chuyển tiếp nô lệ (thường là trong / var / lib / mysql)

mysqlbinlog mysqld-relay-bin.000056

Bạn có thể sẽ thấy một số lỗi hiển thị tham nhũng đã ngừng sao chép, như thế này:

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#

Nếu bạn thấy bất kỳ lỗi nào thì nhật ký vẫn ổn trên bản gốc và chỉ có nhật ký chuyển tiếp của nô lệ bị hỏng. Đây là tin tốt, chúng ta có thể thiết lập lại nô lệ và cho nó biết chi tiết về chủ và tiếp tục từ đâu. Nếu bạn không thấy bất kỳ lỗi nào thì hãy ngừng đọc ngay bây giờ, bạn có một vấn đề khác.

Nếu nhật ký chuyển tiếp nô lệ có lỗi, hãy chạy các lệnh sau để đặt lại nô lệ và nhật ký bị hỏng kết nối lại với bản gốc, lấy nhật ký ok và bắt đầu trượt lại. Lưu ý rằng MASTER_LOG_POS là Exec_Master_Log_Posvà MASTER_LOG_FILE là Relay_Master_Log_File( KHÔNG phải cái đầu tiên, phù hợp với nhật ký chuyển tiếp đã được tìm nạp và cần phải vứt đi) cả từ lệnh đầu tiên.

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
Chào, cảm ơn cho câu trả lời của bạn. Nếu bạn đọc kỹ câu hỏi, bạn sẽ nhận thấy câu "Nhật ký chuyển tiếp bị hỏng" - đó là vì chúng tôi đã sử dụng mysqlbinlogtheo cách bạn đề xuất và phát hiện ra rằng nhật ký chuyển tiếp (không phải nhật ký chính) đã bị hỏng. Liên quan đến bản sửa lỗi mà bạn đề xuất - nếu bạn đọc kỹ câu hỏi, bạn sẽ nhận thấy rằng bản sửa lỗi mà bạn đề xuất là chính xác những gì chúng tôi đã thử. Nhưng điều đó đã không làm việc, và đó là những gì câu hỏi về. - Nhưng câu trả lời của bạn có thể hữu ích cho những người khác có vấn đề tương tự.
KajMagnus

2
Nó có lẽ nên được lưu ý rằng MASTER_LOG_FILEtrong CHANGE MASTERnên được lấy từ Relay_Master_Log_Filevà không từ Master_Log_File. Thông thường chúng sẽ giống nhau nhưng có thể không phải luôn luôn như vậy (xem percona.com/blog/2008/07/07/ mẹo ).
brablc

@brablc nói đúng. Relay_Master_Log_Filephải được sử dụng, không Master_Log_File. Xem thêm: percona.com/blog/2008/07/07/ Mạnh
Mircea Vutcovici

trong hầu hết các trường hợp, không cần thiết reset slave allvì cài đặt chính không cần phải thay đổi (ví dụ: master_host, master_user, master_password), chỉ MASTER_LOG_FILE và MASTER_LOG_POS, sau đó reset_slavesẽ là đủ
ympostor

Câu hỏi và câu trả lời này đã cứu mông tôi nhiều lần rồi. Cảm ơn bạn.
Artem Russakovskii

8

[Sửa lỗi sao chép MySQL sau khi nhật ký chuyển tiếp của nô lệ bị hỏng]

Bản sao MySQL trên nô lệ (phiên bản 5.XX) đã dừng. Slave_IO_Rasty được đánh dấu là Có, nhưng Slave_Query_Rucky là Không. Slave dừng / khởi động đơn giản không giúp phân tích vấn đề thêm nữa. Có vẻ như nhật ký chuyển tiếp của nô lệ hiện tại đã bị hỏng vì thử nghiệm với mys mysbinbinlog đã in ra một lỗi. Do đó, giải pháp là loại bỏ các binlog chuyển tiếp hiện tại và trỏ nô lệ đến vị trí binlog chính cuối cùng.

Để khắc phục lỗi, các tệp binlog hiện tại trên Slave cần được loại bỏ và đặt vị trí mới. Trước khi cài đặt vị trí binlog mới điều quan trọng là phải nhớ Relay_Master_Log_FileExec_Master_Log_Pos giá trị từ máy chủ nô lệ hỏng cách sử dụng lệnh SHOW SLAVE STATUS \ G :

Relay_Master_Log_File: mysql-bin.002045
Exec_Master_Log_Pos: 103641119

OK, với các giá trị này, vị trí binlog mới có thể được đặt:

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

Chỉ cần lưu ý rằng reset slavesẽ xóa master.info, relay-log.infovà tất cả các file log tiếp sức, vì vậy nó không cần thiết để thức ăn thừa sạch trong /var/lib/mysqlthư mục.


1
Câu trả lời hay - thông thường chúng ta không cần thay đổi máy chủ chính, mật khẩu, v.v. Thx!
andy250

3

Tôi biết đã hơn một năm, nhưng đây là những gì có thể xảy ra với vấn đề đặc biệt này.

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;

Có vẻ như đã sửa nó vì nó đã xóa nhật ký chuyển tiếp bị hỏng.

Sau đó, bạn gặp lỗi PK 1062. Tại sao?

Có một lỗi nổi bật ( http://bugs.mysql.com/orms.php?id=60847 ) vẫn hoạt động trong MySQL 5.5

Mặc dù lỗi liên quan đến việc sử dụng mysql --single-giao dịch --flush-log, một tồn tại có liên quan.

Tôi đã thấy rằng việc giải quyết vấn đề trên một số máy chủ EC2 đang hoạt động như một nô lệ cho một khách hàng chỉ mới tuần trước trong MySQL 5.5.15

Trên Master, có một hàng INSERT nhiều hàng kỳ lạ được mở rộng trong đó mỗi bộ được chèn là một CHỌN. Điều đã xảy ra là LAST_INSERT_ID trong nhật ký chuyển tiếp, hình thành mức tăng tự động tiếp theo để gán, đã được sử dụng trên Slave do chèn nhiều hàng trước đó.

INSERT được tuần tự hóa trong nhật ký chuyển tiếp trông giống như

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

Danh sách cột không bao gồm khóa chính số. Khi lỗi 1062 quay trở lại, tôi sẽ sử dụng cùng một truy vấn mà nó đã thất bại, chạy truy vấn theo cách thủ công. Nó không gặp lỗi 1062. Sau đó, tôi chạy các lệnh bỏ qua nô lệ thông thường:

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

Sau đó, nhân rộng bắt kịp.

Lời khuyên của tôi sẽ là tuần tự hóa các INSERT của bạn trên Master một cách chính xác vì tình huống giống như lỗi này thực sự khá khó tránh khỏi.


1

Bạn đã làm điều đó hoàn toàn đúng (như đã nói khác).

Vấn đề duy nhất là với tệp master.info (chứa thông tin về vị trí trong mysql-bin.log của master) vì tệp này không được đồng bộ hóa vào đĩa sau mỗi lần truy vấn được xử lý.

Vì vậy, thông tin của bạn về các vị trí trong nhật ký chính đã lỗi thời và bạn đang xử lý các truy vấn đã được xử lý cần bỏ qua SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1;.

Thật không may, nếu bạn sử dụng một số truy vấn như UPDATE table SET counter=counter+1 WHERE id = 12345và sử dụng binlog_format=STATEMENTcơ sở dữ liệu của bạn có thể không đồng bộ, tôi nghĩ vậy.

Bạn có thể yêu cầu máy chủ MySQL đồng bộ hóa master.info sau mỗi sự kiện bằng cách thiết lập biến sync_master_info nhưng nó có thể sẽ có hậu quả hiệu suất rất lớn.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.