MySQL Slave复制失败:如何识别导致其失败的SQL

时间:2016-10-15 05:40:21

标签: mysql master-slave rds mysqlbinlog binlog

我在AWS RDS上运行MySQL。由于跟随错误,从属复制卡住了。它说它无法在从服务器表中找到记录......有没有办法知道哪条记录?或者是失败的SQL!

  

只读副本复制错误 - SQLError:1032,原因:无法   在表customers.visitor上执行Update_rows_v1事件;不能   在'visitor'中找到记录,Error_code:1032;处理程序错误   HA_ERR_END_OF_FILE;事件的主日志   mysql-bin-changelog.206572,end_log_pos 12627388

1 个答案:

答案 0 :(得分:1)

使用mysqlbinlog读取日志。

mysqlbinlog --verbose --base64-output=decode-rows mysql-bin-changelog.206572 \
| awk '/end_log_pos/{flag=0}/end_log_pos\ 12627388\ /{flag=1}flag' 

从错误消息中,这看起来像是以行格式记录的事件,因此mysqlbinlog会将其解码为伪sql,显示每个列的序号位置,如下所示:

### UPDATE `my_db_name`.`my_table_name`
### WHERE
###   @1=70
###   @2=1476602910
###   @3=NULL
###   @4=NULL
###   @5=NULL
###   @6=NULL
###   @7=NULL
### SET
###   @1=70
###   @2=1476602910
###   @3=1476602926
###   @4=000000016.283000000
###   @5=NULL
###   @6='0'
###   @7=NULL

输出中的@1@2等是第1列,第2列等.Banlog不包含列的实际名称,因为它们被假定为在主服务器和从服务器上相同,因此它们是冗余的...所以mysqlbinlog创建这个伪sql来说明它是如何解释记录的更改事件的。 WHERE是更新前主服务器上显示的行的版本(这将是您的从服务器上找不到的行),SET是行的值在主服务器上更新之后(奴隶应该将行更改为什么样,如果它已存在)。

这并不能识别您的原始查询,但它会显示主服务器上存在但在服务器上缺少的实际行。

如果您还没有日志,可以先从主程序中获取日志,然后使用:

mysqlbinlog --host=xxxx.rds.aws-regi-on.amazonaws.com --user 'rds-master-user' \
--password='rds-master-password' --read-from-remote-server \
--raw mysql-bin-changelog.206572

必须从主服务器获取日志。在这种情况下,它无法从从设备中取出。 (如果这不是RDS,您可以通过SSH登录到shell并直接读取中继日志来连接到从站,但是外部无法访问这些,这就是为什么你必须去主站进行log,在RDS中。)

除非您已经配置RDS以保留binlogs的时间超过技术上所需的时间,否则主机上可能不再提供日志,因此您可能会在下次运气之前失去运气。您可以使用MySQL 5.6及更高版本的所有RDS实例上包含的自定义过程在RDS上配置binlog保留。要将日志保留时间设置为24小时,例如:

CALL mysql.rds_set_configuration('binlog retention hours', 24);

另见http://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_LogAccess.Concepts.MySQL.html

归功于使用awk查找两种模式之间界限的灵感的source

请注意,在上面的命令匹配并打印出发生错误的事件后,它可能会挂起,因为awk继续扫描到文件的末尾。 Control-C终止。