由于以下错误,我们有一个从属服务器已停止复制:
Slave SQL: Query caused different errors on master and slave.
此错误的原因可能是什么?什么是解决它的方法?
主从版本均为 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 '[email protected]: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
还有什么我想不通的是临时表如何导致这样的错误(在master中):
'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
附加信息:
- Master和Slave都在Windows上运行(我不知道这是否相关。)
- 两者的磁盘都有足够的空间。
- 复制格式是
MIXED
- innodb 在所有实例中都被跳过,master 和 slave。MyISAM 是默认设置。
我怀疑其中一些陈述是显而易见的。我为此道歉,但为了彻底起见,我想将其包括在内。
从站停止在这种情况下是预期的行为。
写入 binlog 的每个查询都有元数据,其中包括查询在生成 binlog 事件的服务器上返回的错误代码。错误代码通常为 0,表示“无错误”。如果您通过运行日志,您可以看到此错误代码和其他元数据
mysqlbinlog
。如果在查询执行到某个点后发生错误,查询仍然会与错误代码一起写入 binlog。
从站预计会遇到与主站遇到的相同的错误(通常但不总是 0),并在值不匹配时停止,以帮助避免在遇到这种情况后允许复制继续时可能导致的数据不一致。
binlog 数据结构似乎没有放置错误消息或 sprintf()'ed 到消息中的值 - 只是代码 - 所以从站必须将该代码翻译成人类可读的东西。缺少 master 将插入到消息中的值,它只显示原始消息格式,包括占位符。
因此,当主服务器上发生错误但相同的查询不会在从服务器上产生错误时,您所看到的从服务器上的最后一个复制错误是正常行为。
您可以跳过错误,
SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1; START SLAVE;
就像您现在可能已经完成的那样,但除此之外的恢复取决于您对该临时表的结果做了什么。如果临时表是由单个基于语句的事件创建和填充的,并且没有用于执行任何类型的进一步表更新,那么您可能会没事,因为复制通常会忽略尝试时发生的错误,DROP TEMPORARY TABLE
而临时表不会'不存在于从属线程上,因为从属线程没有可靠的方法来知道该CREATE TEMPORARY TABLE
语句之前是否实际出现在二进制日志中,或者从属线程是否可能在CREATE
与DROP
临时表上的事件(这将破坏在停止/启动之前由从属 SQL 线程创建的任何临时表)。另一方面,如果临时表用于更新其他表,您仍然可能会很好,因为这些更新可能已被编写为基于行的事件,因为您采用的是MIXED
binlog 格式......但我会验证任何您从临时表结果更新的表(如果有)。至于master上出现的错误:
起初我错过了一些关于这些的东西——我以为它们相隔 1 秒,但这些错误实际上似乎发生在两个不同的日子,即 25 日和 26 日,所以相隔 24 小时和 1 秒...... 2 个不同的警告在同一个临时表名称上,但实际上两个不同的临时表相隔一天生成。
起初我觉得很奇怪,您在主日志中没有“不正确的密钥文件”消息,但那些不会在日志中 - 这些将是返回给发出查询的客户端的错误。
我记得在我的服务器的错误日志中看到过类似的错误,但事实证明,据我所知,那些“不正确的密钥文件”错误只有在 slave_sql 线程或遇到时才会进入服务器错误日志由事件调度程序执行的查询,因为这些是唯一没有客户端连接来接收错误的时间......所以可能是运行创建临时表的查询的任何内容都生成了可能是的错误日志兴趣。
如果查询的一部分创建了自己的隐式临时表,我们不能从技术上假设它是“tmp_grades”表遇到“不正确的密钥文件”错误
SELECT
......它可能是那个表,导致错误影响了查询。稍微看一下内部,看起来当您
MyISAM
在语句中创建一个带有索引的临时表时CREATE TEMPORARY TABLE ... SELECT
,该表是在禁用索引的情况下创建的,然后服务器在写入数据后构建并启用索引,而不必更新索引,因为它插入数据...看起来您看到的警告可能是在它构建索引时出现的(“启用键...”)...假设这是正确的,它只建议一个少数可能性,没有特别的顺序列出,但所有这些都围绕着您的临时表正在损坏的想法:Using temporary
) 创建了一个巨大的临时表,因此您有一个短暂的磁盘空间不足情况,在另一个作业完成后立即消失SELECT
查询部分正在构建另一个隐式临时表,这会导致短暂的磁盘空间不足并与显式表竞争空间当然,这里最大的问题是这些解释似乎都不太可能。在验证了两台机器之间的数据当前是一致的之后,不幸的下一步可能是等待它再次发生,尽管如果是我,我会倾向于验证系统内存和临时磁盘的完整性。
正如迈克尔所说“你的系统内存有问题,所以临时表在操作系统缓存中被损坏”这是最常见的状态,尝试增加 tmp_table_size 和 max_heap_table_size,因为语句有“创建临时表”和“组by" 子句使用需要这些缓冲区的临时表我的建议是:增加主和从属上的这些缓冲区您可以在此链接中找到更多详细信息 http://dev.mysql.com/doc/refman/5.0/en/server- system-variables.html#sysvar_tmp_table_size