一台虚机在迁移过程中遇到点问题,然后运维做了重启的操作。重启后,发现该虚机中的 mysql 从库与主库的同步失败了。登录后查看,发现 sql thread 停止运行了:
mysql> show slave status\G *************************** 1. row *************************** Slave_IO_State: Waiting for source to send event Master_Host: 11.11.11.11 Master_User: repl Master_Port: 3306 Connect_Retry: 60 Master_Log_File: mysql-bin.000208 Read_Master_Log_Pos: 157 Relay_Log_File: myabc-relay-bin.000422 Relay_Log_Pos: 326 Relay_Master_Log_File: mysql-bin.000206 Slave_IO_Running: Yes Slave_SQL_Running: No Replicate_Do_DB: Replicate_Ignore_DB: Replicate_Do_Table: Replicate_Ignore_Table: Replicate_Wild_Do_Table: Replicate_Wild_Ignore_Table: Last_Errno: 1062 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.000206, end_log_pos 590031097. See error log and/or performance_schema.replication_applier_status_by_worker table for more details about this failure or others, if any. Skip_Counter: 0 Exec_Master_Log_Pos: 590022747 Relay_Log_Space: 46906817 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: 1062 Last_SQL_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.000206, end_log_pos 590031097. See error log and/or performance_schema.replication_applier_status_by_worker table for more details about this failure or others, if any. Replicate_Ignore_Server_Ids: Master_Server_Id: 1 Master_UUID: 123be9d9-2c3a-11sf-934f-003236b0e12b Master_Info_File: mysql.slave_master_info SQL_Delay: 0 SQL_Remaining_Delay: NULL Slave_SQL_Running_State: Master_Retry_Count: 86400 Master_Bind: Last_IO_Error_Timestamp: Last_SQL_Error_Timestamp: 241029 19:13:39 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, 1 warning (0.00 sec)
查看一下具体的原因,发现是有主键冲突了:
mysql> select * from performance_schema.replication_applier_status_by_worker\G *************************** 1. row *************************** CHANNEL_NAME: WORKER_ID: 1 THREAD_ID: NULL SERVICE_STATE: OFF LAST_ERROR_NUMBER: 1062 LAST_ERROR_MESSAGE: Worker 1 failed executing transaction 'ANONYMOUS' at master log mysql-bin.000206, end_log_pos 590031097; Could not execute Write_rows event on table xxx.abce; Duplicate entry '123450002-x-102996-1-Bccount-20241030' for key 'abce.PRIMARY', Error_code: 1062; handler error HA_ERR_FOUND_DUPP_KEY; the event's master log FIRST, end_log_pos 590031097 LAST_ERROR_TIMESTAMP: 2024-10-29 19:16:41.967281 LAST_APPLIED_TRANSACTION: LAST_APPLIED_TRANSACTION_ORIGINAL_COMMIT_TIMESTAMP: 0000-00-00 00:00:00.000000 LAST_APPLIED_TRANSACTION_IMMEDIATE_COMMIT_TIMESTAMP: 0000-00-00 00:00:00.000000 LAST_APPLIED_TRANSACTION_START_APPLY_TIMESTAMP: 0000-00-00 00:00:00.000000 LAST_APPLIED_TRANSACTION_END_APPLY_TIMESTAMP: 0000-00-00 00:00:00.000000 APPLYING_TRANSACTION: ANONYMOUS APPLYING_TRANSACTION_ORIGINAL_COMMIT_TIMESTAMP: 2024-10-29 17:21:51.397102 APPLYING_TRANSACTION_IMMEDIATE_COMMIT_TIMESTAMP: 2024-10-29 17:21:51.397102 APPLYING_TRANSACTION_START_APPLY_TIMESTAMP: 2024-10-29 19:16:41.967042 LAST_APPLIED_TRANSACTION_RETRIES_COUNT: 0 LAST_APPLIED_TRANSACTION_LAST_TRANSIENT_ERROR_NUMBER: 0 LAST_APPLIED_TRANSACTION_LAST_TRANSIENT_ERROR_MESSAGE: LAST_APPLIED_TRANSACTION_LAST_TRANSIENT_ERROR_TIMESTAMP: 0000-00-00 00:00:00.000000 APPLYING_TRANSACTION_RETRIES_COUNT: 0 APPLYING_TRANSACTION_LAST_TRANSIENT_ERROR_NUMBER: 0 APPLYING_TRANSACTION_LAST_TRANSIENT_ERROR_MESSAGE: APPLYING_TRANSACTION_LAST_TRANSIENT_ERROR_TIMESTAMP: 0000-00-00 00:00:00.000000 *************************** 2. row *************************** CHANNEL_NAME: WORKER_ID: 2 THREAD_ID: NULL SERVICE_STATE: OFF LAST_ERROR_NUMBER: 0 LAST_ERROR_MESSAGE: LAST_ERROR_TIMESTAMP: 0000-00-00 00:00:00.000000 LAST_APPLIED_TRANSACTION: LAST_APPLIED_TRANSACTION_ORIGINAL_COMMIT_TIMESTAMP: 0000-00-00 00:00:00.000000 LAST_APPLIED_TRANSACTION_IMMEDIATE_COMMIT_TIMESTAMP: 0000-00-00 00:00:00.000000 LAST_APPLIED_TRANSACTION_START_APPLY_TIMESTAMP: 0000-00-00 00:00:00.000000 LAST_APPLIED_TRANSACTION_END_APPLY_TIMESTAMP: 0000-00-00 00:00:00.000000 APPLYING_TRANSACTION: APPLYING_TRANSACTION_ORIGINAL_COMMIT_TIMESTAMP: 0000-00-00 00:00:00.000000 APPLYING_TRANSACTION_IMMEDIATE_COMMIT_TIMESTAMP: 0000-00-00 00:00:00.000000 APPLYING_TRANSACTION_START_APPLY_TIMESTAMP: 0000-00-00 00:00:00.000000 LAST_APPLIED_TRANSACTION_RETRIES_COUNT: 0 LAST_APPLIED_TRANSACTION_LAST_TRANSIENT_ERROR_NUMBER: 0 LAST_APPLIED_TRANSACTION_LAST_TRANSIENT_ERROR_MESSAGE: LAST_APPLIED_TRANSACTION_LAST_TRANSIENT_ERROR_TIMESTAMP: 0000-00-00 00:00:00.000000 APPLYING_TRANSACTION_RETRIES_COUNT: 0 APPLYING_TRANSACTION_LAST_TRANSIENT_ERROR_NUMBER: 0 APPLYING_TRANSACTION_LAST_TRANSIENT_ERROR_MESSAGE: APPLYING_TRANSACTION_LAST_TRANSIENT_ERROR_TIMESTAMP: 0000-00-00 00:00:00.000000 *************************** 3. row *************************** CHANNEL_NAME: WORKER_ID: 3 THREAD_ID: NULL SERVICE_STATE: OFF LAST_ERROR_NUMBER: 0 LAST_ERROR_MESSAGE: LAST_ERROR_TIMESTAMP: 0000-00-00 00:00:00.000000 LAST_APPLIED_TRANSACTION: LAST_APPLIED_TRANSACTION_ORIGINAL_COMMIT_TIMESTAMP: 0000-00-00 00:00:00.000000 LAST_APPLIED_TRANSACTION_IMMEDIATE_COMMIT_TIMESTAMP: 0000-00-00 00:00:00.000000 LAST_APPLIED_TRANSACTION_START_APPLY_TIMESTAMP: 0000-00-00 00:00:00.000000 LAST_APPLIED_TRANSACTION_END_APPLY_TIMESTAMP: 0000-00-00 00:00:00.000000 APPLYING_TRANSACTION: APPLYING_TRANSACTION_ORIGINAL_COMMIT_TIMESTAMP: 0000-00-00 00:00:00.000000 APPLYING_TRANSACTION_IMMEDIATE_COMMIT_TIMESTAMP: 0000-00-00 00:00:00.000000 APPLYING_TRANSACTION_START_APPLY_TIMESTAMP: 0000-00-00 00:00:00.000000 LAST_APPLIED_TRANSACTION_RETRIES_COUNT: 0 LAST_APPLIED_TRANSACTION_LAST_TRANSIENT_ERROR_NUMBER: 0 LAST_APPLIED_TRANSACTION_LAST_TRANSIENT_ERROR_MESSAGE: LAST_APPLIED_TRANSACTION_LAST_TRANSIENT_ERROR_TIMESTAMP: 0000-00-00 00:00:00.000000 APPLYING_TRANSACTION_RETRIES_COUNT: 0 APPLYING_TRANSACTION_LAST_TRANSIENT_ERROR_NUMBER: 0 APPLYING_TRANSACTION_LAST_TRANSIENT_ERROR_MESSAGE: APPLYING_TRANSACTION_LAST_TRANSIENT_ERROR_TIMESTAMP: 0000-00-00 00:00:00.000000 *************************** 4. row *************************** CHANNEL_NAME: WORKER_ID: 4 THREAD_ID: NULL SERVICE_STATE: OFF LAST_ERROR_NUMBER: 0 LAST_ERROR_MESSAGE: LAST_ERROR_TIMESTAMP: 0000-00-00 00:00:00.000000 LAST_APPLIED_TRANSACTION: LAST_APPLIED_TRANSACTION_ORIGINAL_COMMIT_TIMESTAMP: 0000-00-00 00:00:00.000000 LAST_APPLIED_TRANSACTION_IMMEDIATE_COMMIT_TIMESTAMP: 0000-00-00 00:00:00.000000 LAST_APPLIED_TRANSACTION_START_APPLY_TIMESTAMP: 0000-00-00 00:00:00.000000 LAST_APPLIED_TRANSACTION_END_APPLY_TIMESTAMP: 0000-00-00 00:00:00.000000 APPLYING_TRANSACTION: APPLYING_TRANSACTION_ORIGINAL_COMMIT_TIMESTAMP: 0000-00-00 00:00:00.000000 APPLYING_TRANSACTION_IMMEDIATE_COMMIT_TIMESTAMP: 0000-00-00 00:00:00.000000 APPLYING_TRANSACTION_START_APPLY_TIMESTAMP: 0000-00-00 00:00:00.000000 LAST_APPLIED_TRANSACTION_RETRIES_COUNT: 0 LAST_APPLIED_TRANSACTION_LAST_TRANSIENT_ERROR_NUMBER: 0 LAST_APPLIED_TRANSACTION_LAST_TRANSIENT_ERROR_MESSAGE: LAST_APPLIED_TRANSACTION_LAST_TRANSIENT_ERROR_TIMESTAMP: 0000-00-00 00:00:00.000000 APPLYING_TRANSACTION_RETRIES_COUNT: 0 APPLYING_TRANSACTION_LAST_TRANSIENT_ERROR_NUMBER: 0 APPLYING_TRANSACTION_LAST_TRANSIENT_ERROR_MESSAGE: APPLYING_TRANSACTION_LAST_TRANSIENT_ERROR_TIMESTAMP: 0000-00-00 00:00:00.000000 4 rows in set (0.01 sec)
数据库版本是 8.0.30,从库也没有对外提供写入操作,排除了从库写入相同记录的问题。在主从同步过程中,发生这种问题只可能是应用 relay log的时候发生了问题。
根据复制配置的不同,relay log 中执行的事务顺序可能会出现不一致。可能存在以下类型的不一致:
(1).半应用事务。更新非事务表的事务应用了部分更改,但不是全部更改。
(2).间隙。间隙是指事务序列中有的事务没有应用,但是其后面的某个或某些事务已经被应用到从库。间隙只会出现在从库开启多线程复制的时候。为避免出现间隙,需要设置 slave_preserve_commit_order=1,这要求 slave_parallel_type=LOGICAL_CLOCK,并启用 log-bin和 log-slave-updates 。请注意,slave_preserve_commit_order=1 不会保留非事务性 DML 更新的顺序,因此这些更新可能会在 relay log 中它们之前的事务之前提交,这可能会导致间隙。
(3).源二进制日志位置滞后
即使没有间隙,Exec_master_log_pos 之后的事务也有可能被应用。在这种情况下,Exec _master_log_pos 是已应用事务的 "低水位标记",滞后于最近应用事务的位置。这种情况只会发生在多线程从库上。启用 slave_preserve_commit_order 不能防止源二进制日志位置滞后。
以下一些场景会出现上面的三种不一致:
(1).当复制线程运行时,可能会出现间隙和半应用事务。
(2).mysqld 关闭。干净和不干净关闭都会中止正在进行的事务,并可能留下间隙和半应用事务。
(3).杀死复制线程(使用单线程复制时为 sql thread ,使用多线程复制时为协调器线程)。这会中止正在进行的事务,并可能留下间隙和半应用事务。
(4).应用线程(applier threads)出错。这可能会留下间隙。如果错误发生在 mixed 事务中,则该事务将被半应用。使用多线程从库时,未收到错误的 worker 会完成其队列,因此停止所有线程可能需要时间。
(5).使用多线程从库时,执行 stop slave。在发出stop slave 之后,从库会等待任何间隙被填补,然后更新 Exec_master_log_pos 。这可确保不会留下间隙或源二进制日志位置滞后,除非出现上述任何一种情况。
(6).如果 relay log 中的最后一个事务只接收了一半,而多线程从库协调器已开始将事务调度给 worker 线程,那么 stop slave 最多会等待 60 秒,等待接收事务。超时后,协调器会放弃并中止事务。如果事务是 mixed 类型的,则可能处于半完成状态。
(7).当正在进行的事务只更新事务表时执行 stop slave,事务会会回滚,stop slave 立即结束;如果正在进行的事务是 mixed 类型的事务,stop slave 最多会等待 60 秒,等待事务完成。超时后,stop slave 会中止事务,因此事务可能只完成了一半。
如果复制通道存在间隙,会产生以下后果
(1).从库处于主库可能从未存在过的状态
(2).show slave status 中的 Exec_master_log_pos 字段只是一个"低水位标记"。换句话说,在该位置之前出现的事务保证已提交,但该位置之后的事务可能已提交,也可能未提交
(3).除非应用线程正在运行,且 change master to 语句只设置了接收选项,否则该通道的 change master to 语句会出错
(4).如果使用 --relay-log-recovery 启动mysqld,则不会恢复该通道,并会打印警告
(5).如果使用 --dump-slave 启动 mysqldump,它不会记录间隙的存在
如果复制通道有源二进制日志位置滞后但无间隙,则上述第 2 至 5 种情况适用,但第 1 种情况不适用。
源二进制日志位置信息以二进制格式保存在内部表 mysql.slave_worker_info 中。start slave [sql_thread] 总是查询这些信息,以便只应用正确的事务。即使在 start slave 之前,slave_parallel_workers 已更改为 0;即使 start slave 与 until 子句一起使用,也是如此。
start slave until sql_after_mts_gaps 只应用所需的事务来填补空白。如果 start slave 与 until 子句一起使用,而 until 子句告诉 start slave 在填补所有间隙之前停止,那么它就会留下剩余的间隙。
使用基于 GTID 的复制时,从 MySQL 5.7.28 开始,多线程复制会首先检查 MASTER_AUTO_POSITION 是否设置为ON,如果是,则省略计算应跳过或未跳过事务的步骤。在这种情况下,恢复过程不需要旧的 relay log。
当 master_auto_position = 1设置为 1 时,在初始连接握手中,从库会发送一个 gtid 集,其中包含它已接收、已提交或已接收和已提交的事务。主库会做出响应,发送其二进制日志中记录的所有事务,这些事务的 gtid 未包含在从库发送的 gtid 集中。这种交换可确保主库只发送从库尚未记录或提交的 gtid 的事务。如果从库从多个主库接收事务,自动跳过功能可确保事务不会被应用两次。
回到本次问题的本身,因为负责数据库的管理员,在配置主从复制的时候,并没有使用基于gtid的复制,而是基于日志位置的复制,且开启了多线程复制。因而猜测在从库宕机重启过程中,遇到了上面提到的第三种不一致:源二进制日志位置滞后。从而发生了从库遇到主键冲突的问题。
标签:APPLIED,00,TRANSACTION,LAST,宕机,TIMESTAMP,MySQL,0000,主键 From: https://www.cnblogs.com/abclife/p/18515513