复制错误

ype*_*eᵀᴹ 7 mysql replication mysql-5.5

由于以下错误,我们有一个从服务器已停止复制:

Slave SQL: Query caused different errors on master and slave.
Run Code Online (Sandbox Code Playgroud)

导致此错误的原因可能是什么?什么是修复它的方法?

主从版本均为 MySQL 5.5.30

130726 23:55:45 [Note] C:\Program Files\MySQL\MySQL Server 5.5\bin\mysqld: Shutdown complete

130726 23:58:39 [Note] Plugin 'FEDERATED' is disabled.
130726 23:58:39 [Warning] C:\Program Files\MySQL\MySQL Server 5.5\bin\mysqld: ignoring option '--innodb-file-per-table' due to invalid value 'ON'
130726 23:58:39 [Note] Plugin 'InnoDB' is disabled.
130726 23:58:39 [Note] Server hostname (bind-address): '0.0.0.0'; port: 3306
130726 23:58:39 [Note]   - '0.0.0.0' resolves to '0.0.0.0';
130726 23:58:39 [Note] Server socket created on IP: '0.0.0.0'.
130726 23:58:39 [Note] Slave SQL thread initialized, starting replication 
    in log 'mysql-bin.000234' at position 1065421256, 
    relay log '.\slave-relay-bin.000917' position: 1065421402
130726 23:58:39 [Note] Slave I/O thread: connected to master 'replication@191.5.3.4:3306',
    replication started in log 'mysql-bin.000235' at position 166680598
130726 23:58:39 [Note] Event Scheduler: Loaded 0 events
130726 23:58:39 [Note] C:\Program Files\MySQL\MySQL Server 5.5\bin\mysqld: 
    ready for connections.
Version: '5.5.30-log'  socket: ''  port: 3306  MySQL Community Server (GPL)
130726 23:59:04 [ERROR] Slave SQL: Query caused different errors on master and slave.
    Error on master: message (format)='Incorrect key file for table '%-.200s'; 
    try to repair it' error code=1034 ; 
    Error on slave: actual message='no error', error code=0. 
    Default database: 'shared'. 
    Query: 'CREATE TEMPORARY TABLE tmp_grades (
                        vehsysid INT(11),
                        grade INT(1),
                        dt TIMESTAMP,
                        INDEX(vehsysid),
                        INDEX(grade),
                        INDEX(dt)
                    ) SELECT vehsysid, Grade, MAX(dt) AS dt
                        FROM shared.tbl_valuations 
                        GROUP BY vehsysid, grade', Error_code: 0
130726 23:59:04 [ERROR] Error running query, slave SQL thread aborted. Fix the problem,
   and restart the slave SQL thread with "SLAVE START". 
   We stopped at log 'mysql-bin.000234' position 1065421256
Run Code Online (Sandbox Code Playgroud)

还有什么我想不通的是临时表如何导致这样的错误(在主人中):
'Incorrect key file for table '%-.200s'; try to repair it' error code=1034

主错误日志的最后几行:

130725 23:15:57 [Warning] Warning: Enabling keys got errno 120 on shared.tmp_grades, retrying
130726 23:15:58 [Warning] Warning: Enabling keys got errno 137 on shared.tmp_grades, retrying
Run Code Online (Sandbox Code Playgroud)

附加信息:

  • Master 和 Slave 都在 Windows 上运行(我不知道这是否相关。)
  • 两者的磁盘都有足够的空间。
  • 复制格式是 MIXED
  • innodb 在所有实例中都被跳过,master 和 slaves。MyISAM 是默认设置。

Mic*_*bot 9

我怀疑其中一些陈述是显而易见的。我为此道歉,但为了彻底起见,我想将其包括在内。

从站停止在这种情况下是预期的行为。

写入 binlog 的每个查询都有元数据,其中包括查询在生成 binlog 事件的服务器上返回的错误代码。错误代码通常为 0,表示“没有错误”。如果通过 运行日志,您可以看到此错误代码和其他元数据mysqlbinlog

#130727 10:52:46 server id 10 end_log_pos 166 Query thread_id=673471 exec_time=1 error_code=0
Run Code Online (Sandbox Code Playgroud)

如果在查询执行到某个特定点后发生错误,该查询仍会与错误代码一起写入 binlog。

从站希望遇到与主站遇到的相同的错误(通常但不总是 0),并在值不匹配时停止,以帮助避免数据不一致,如果在遇到此类情况后允许继续复制,则可能会导致数据不一致。

binlog 数据结构似乎没有为错误消息或 sprintf() 放入消息中的值提供位置——只是代码——因此从站必须将该代码转换为人类可读的内容。由于缺少主机插入到消息中的值,它只显示原始消息格式,包括占位符。

# from source file include/mysqld_ername.h
{ "ER_NOT_KEYFILE", 1034, "Incorrect key file for table \'%-.200s\'; try to repair it" },
Run Code Online (Sandbox Code Playgroud)

因此,当主服务器上发生错误但相同的查询不会在从服务器上生成错误时,您在从服务器上看到的最后一个复制错误是正常行为。

您可以跳过错误,SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1; START SLAVE;就像您现在可能已经完成的那样,但超出此范围的恢复取决于您对该临时表的结果所做的操作。如果临时表是由单个基于语句的事件创建和填充的,并且不用于进行任何类型的进一步表更新,那么您可能没问题,因为复制通常会忽略尝试时发生的错误,DROP TEMPORARY TABLE而临时表不会'不存在于从站上,因为从站线程没有可靠的方法知道该CREATE TEMPORARY TABLE语句之前是否确实出现在 binlog 中,或者从站是否可能在CREATEDROP临时表上的事件(这会破坏在停止/启动之前由从属 SQL 线程创建的任何临时表)。另一方面,如果临时表用于更新其他表,您仍然可能没问题,因为自从您采用MIXEDbinlog 格式以来,这些更新可能已被编写为基于行的事件……但我会验证任何表之间的一致性您从临时表结果更新的表(如果有)。

至于master上发生的错误:

130725 23:15:57 [Warning] Warning: Enabling keys got errno 120 on shared.tmp_grades, retrying
130726 23:15:58 [Warning] Warning: Enabling keys got errno 137 on shared.tmp_grades, retrying
Run Code Online (Sandbox Code Playgroud)

起初我错过了一些东西——我以为它们相隔 1 秒,但这些错误实际上似乎发生在两个不同的日子,25 日和 26 日,所以相隔 24 小时 1 秒...... 2 个不同的警告在同一个临时表名称上,但实际上两个不同的临时表相隔一天生成。

MySQL error code 120: Didn't find key on read or update (HA_ERR_KEY_NOT_FOUND)
MySQL error code 137: No more records (read after end of file) (HA_ERR_END_OF_FILE)
Run Code Online (Sandbox Code Playgroud)

起初我觉得奇怪的是,你在主日志中没有“不正确的密钥文件”消息,但那些不会在日志中——那些将是返回给发出查询的客户端的错误。

我记得在我的服务器的错误日志中看到过类似的错误,但事实证明,据我所知,那些“不正确的密钥文件”错误只会在 slave_sql 线程或由事件调度程序执行的查询,因为这是唯一没有客户端连接接收错误的时间......兴趣。

如果SELECT查询的部分创建了自己的隐式临时表,我们不能从技术上假设它是 'tmp_grades' 表遇到“不正确的密钥文件”错误......它可能是那个表,导致错误影响了查询。

查看内部结构,有点,当您MyISAMCREATE TEMPORARY TABLE ... SELECT语句中创建带有索引的临时表时,该表是在禁用索引的情况下创建的,然后服务器在写入数据后构建并启用索引,而不必更新索引插入数据......看起来你看到的警告可能是在它构建索引时(“启用键......”)......并且假设这是正确的,它只建议一个少数可能性,没有按特定顺序列出,但所有这些都围绕着您的临时表已损坏的想法:

  • 您有另一个同时运行的作业,它也显式或隐式 ( Using temporary)创建了一个巨大的临时表,因此您有一个短暂的磁盘空间不足情况,该情况在另一个作业完成后立即消失
  • SELECT多数民众赞成填充临时表查询的一部分正在建设这是造成一过性低磁盘空间条件的另一个隐含的临时表与空间的明确表竞
  • 您的系统内存有问题,因此操作系统缓存中的临时表已损坏
  • 您的磁盘有问题,临时表太大而无法保留在操作系统缓存中,临时表在刷新到磁盘时已损坏。

当然,这里最大的问题是这些解释似乎都不太可能。在验证两台机器之间的数据目前是一致的后,不幸的下一步可能是等待它再次发生,尽管如果是我,我会倾向于验证系统内存和临时磁盘的完整性。