前言 今天发现有一套 MySQL 8 数据库主从不同步了,报错如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 mysql> show slave status \G; Last_Errno: 1032 Last_Error: Coordinator stopped because there were error(s) in the worker(s). The most recent failure being: Worker 1 failed executing transaction 'ANONYMOUS' at master log mysql- bin.003633 , end_log_pos 603058578. See error log and / or performance_schema.replication_applier_status_by_worker table for more details about this failure or others, if any. mysql> SELECT * FROM performance_schema.replication_applier_status_by_worker WHERE LAST_ERROR_NUMBER = 1032 \G; LAST_ERROR_TIMESTAMP: 2025 -09 -06 20 :08 :06.998256 ... LAST_ERROR_MESSAGE: Worker 1 failed executing transaction 'ANONYMOUS' at master log mysql- bin.003633 , end_log_pos 603058578 ; Could not execute Update_rows event on table ci_sch* * * .qrtz_* * * _triggers; Can't find record in ' qrtz_* * * _triggers', Error_code: 1032; handler error HA_ERR_KEY_NOT_FOUND; the event' s master log FIRST , end_log_pos 603058578
由于不同步的时间已经很久了,主库的 binlog 已经不存在,所以只能重建从库了,本文使用 MySQL 8 的 clone 插件进行主从重建。
主从重建 安装插件 主从均需安装 clone 插件:
1 2 3 4 5 6 7 8 9 mysql> install plugin clone soname 'mysql_clone.so' ; Query OK mysql> select plugin_name, plugin_status from information_schema.plugins where plugin_name = 'clone' ; + | PLUGIN_NAME | PLUGIN_STATUS | + | clone | ACTIVE | +
确保安装完成即可。
配置权限 执行克隆操作需要特定的权限,本地复制和远程复制权限不同:
本地克隆 :执行克隆操作的用户需要 BACKUP_ADMIN 权限;
远程克隆 :捐赠者(数据源)用户需要 BACKUP_ADMIN 权限;接受者(目标)用户需要 CLONE_ADMIN 权限(该权限隐含了 BACKUP_ADMIN 和 SHUTDOWN 权限);
主(源端):
1 2 mysql> GRANT BACKUP_ADMIN ON * .* TO 'root' @'%' ; mysql> FLUSH PRIVILEGES;
从(目标端):
1 2 mysql> GRANT CLONE_ADMIN ON * .* TO 'root' @'%' ; mysql> FLUSH PRIVILEGES;
远程克隆 从库开始克隆:
1 2 3 4 5 mysql> set global clone_valid_donor_list= '192.168.31.188:3306' ; mysql> clone instance from root@'192.168.31.188' :3306 identified by 'P@ssw0rd' ;
克隆过程中,从库可以查询进度:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 mysql> SELECT stage, state, CAST (begin_time AS DATETIME) AS "START TIME", CAST (end_time AS DATETIME) AS "FINISH TIME", LPAD(sys.format_time(POWER (10 , 12 ) * (UNIX_TIMESTAMP(end_time) - UNIX_TIMESTAMP(begin_time))), 10 , ' ' ) AS DURATION, LPAD(CONCAT(FORMAT(ROUND(estimate / 1024 / 1024 , 0 ), 0 ), "MB"), 16 , ' ' ) AS "Estimate", CASE WHEN begin_time IS NULL THEN LPAD('%0' , 7 , ' ' ) WHEN estimate > 0 THEN LPAD(CONCAT(ROUND(data * 100 / estimate, 0 ), "%"), 7 , ' ' ) WHEN end_time IS NULL THEN LPAD('0%' , 7 , ' ' ) ELSE LPAD('100%' , 7 , ' ' ) END AS "Done(%)" FROM performance_schema.clone_progress;+ | stage | state | START TIME | FINISH TIME | DURATION | Estimate | Done(% ) | + | DROP DATA | Completed | 2026 -01 -05 15 :34 :10 | 2026 -01 -05 15 :34 :13 | 3.07 s | 0 MB | 100 % | | FILE COPY | Completed | 2026 -01 -05 15 :34 :13 | 2026 -01 -05 15 :58 :13 | 24 m | 347 ,246 MB | 100 % | | PAGE COPY | Completed | 2026 -01 -05 15 :58 :13 | 2026 -01 -05 15 :58 :13 | 507.57 ms | 18 MB | 100 % | | REDO COPY | Completed | 2026 -01 -05 15 :58 :13 | 2026 -01 -05 15 :58 :14 | 368.4 ms | 0 MB | 100 % | | FILE SYNC | Completed | 2026 -01 -05 15 :58 :14 | 2026 -01 -05 15 :58 :15 | 895.55 ms | 0 MB | 100 % | | RESTART | Completed | 2026 -01 -05 15 :58 :15 | 2026 -01 -05 15 :58 :21 | 6.47 s | 0 MB | 100 % | | RECOVERY | Completed | 2026 -01 -05 15 :58 :21 | 2026 -01 -05 15 :58 :23 | 1.64 s | 0 MB | 100 % | + mysql> SELECT * FROM performance_schema.clone_status; + | ID | PID | STATE | BEGIN_TIME | END_TIME | SOURCE | DESTINATION | ERROR_NO | ERROR_MESSAGE | BINLOG_FILE | BINLOG_POSITION | GTID_EXECUTED | + | 1 | 0 | Completed | 2026 -01 -05 15 :34 :09.386 | 2026 -01 -05 15 :58 :22.894 | 192.168 .31 .188 :3306 | LOCAL INSTANCE | 0 | | mysql- bin.004291 | 630818978 | | +
等待克隆完成后,会自动重新启动从库 MySQL 实例。
启动主从复制 从库配置并启动主从复制:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 mysql> show variables like '%server_id%' ; + | Variable_name | Value | + | server_id | 2 | | server_id_bits | 32 | + mysql> change master to master_host= '192.168.31.188' , master_port= 3306 , master_user= 'repl' , master_password= 'P@ssw0rd' , master_log_file= 'mysql-bin.004291' , master_log_pos= 630818978 ; mysql> start slave; Query OK mysql> show slave status \G; * * * * * * * * * * * * * * * * * * * * * * * * * * * 1. row * * * * * * * * * * * * * * * * * * * * * * * * * * * Slave_IO_State: Waiting for source to send event Master_Host: 192.168 .31 .188 Master_User: repl Master_Port: 3306 Connect_Retry: 60 Master_Log_File: mysql- bin.004291 Read_Master_Log_Pos: 633519126 Relay_Log_File: mysql- relay- bin.000002 Relay_Log_Pos: 2697758 Relay_Master_Log_File: mysql- bin.004291 Slave_IO_Running: Yes Slave_SQL_Running: Yes Replicate_Do_DB: Replicate_Ignore_DB: Replicate_Do_Table: Replicate_Ignore_Table: Replicate_Wild_Do_Table: Replicate_Wild_Ignore_Table: Last_Errno: 0 Last_Error: Skip_Counter: 0 Exec_Master_Log_Pos: 633516410 Relay_Log_Space: 2700684 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: 0 Master_SSL_Verify_Server_Cert: No Last_IO_Errno: 0 Last_IO_Error: Last_SQL_Errno: 0 Last_SQL_Error: Replicate_Ignore_Server_Ids: Master_Server_Id: 1 Master_UUID: 0 df21031- d536-11 ee- a0cd-005056 a91cf7 Master_Info_File: mysql.slave_master_info SQL_Delay: 0 SQL_Remaining_Delay: NULL Slave_SQL_Running_State: Replica has read all relay log; waiting for more updates Master_Retry_Count: 86400 Master_Bind: Last_IO_Error_Timestamp: Last_SQL_Error_Timestamp: Master_SSL_Crl: Master_SSL_Crlpath: Retrieved_Gtid_Set: Executed_Gtid_Set: Auto_Position: 0 Replicate_Rewrite_DB: Channel_Name: Master_TLS_Version: Master_public_key_path: Get_master_public_key: 0 Network_Namespace: 1 row in set
可以发现,主从已经恢复正常同步。
写在最后 以前搭建 MySQL 主从都是使用 mysqldump 或者 PXB 备份恢复,耗时耗力。使用 clone 插件,只要符合它的限制条件,将是非常实用便捷的搭建方式。