天天看点

常见MySQL同步错误恢复方法

1.1236错误解决办法

由于主服务器异外重启,导致从报错,错误如下:

mysql>showslavestatus\g

master_log_file:mysql-bin.000288

read_master_log_pos:627655136

relay_log_file:mysql-relay-bin.000990

relay_log_pos:627806457

relay_master_log_file:mysql-bin.000288

slave_io_running:no

slave_sql_running:yes

exec_master_log_pos:627655136

relay_log_space:627806663

......

last_io_error:gotfatalerror1236frommasterwhenreadingdatafrombinarylog:'clientrequestedmastertostartreplicationfromimpossibleposition',readuptolog'mysql-bin.000288',position627655136.

登陆到主服务器查看binlog日志,先按照错误点的标记去主服务器日志中查找,没有看到这个位置。

shell>/usr/local/mysql/bin/mysqlbinlog--start-position=627655136/usr/local/mysql/data/mysql-bin.000288

/*!40019set@@session.max_insert_delayed_threads=0*/;

/*!50003set@old_completion_type=@@completion_type,completion_type=0*/;

delimiter/*!*/;

#at4

#11101013:31:19serverid4end_log_pos106start:binlogv4,serverv5.1.45-log

created11101013:31:19

#warning:thisbinlogiseitherinuseorwasnotclosedproperly.

binlog'

f1attg8eaaaazgaaagoaaaabaaqans4xljq1lwxvzwaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

aaaaaaaaaaaaaaaaaaaaaaaaezgnaagaegaebaqeegaauwaegggaaaaicagc

'/*!*/;

delimiter;

#endoflogfile

rollback/*addedbymysqlbinlog*/;

/*!50003setcompletion_type=@old_completion_type*/;

查看这个binlog最后一部分:

shell>mysqlbinlog/usr/local/mysql/data/mysql-bin.000288>binlog.txt

shell>tail-fbinlog.txt

找到最接近错误标记627655136的一个position是627625631.再回到slave机器上,changemaster,将postion指向这个位置.

mysql>stopslave;

mysql>changemastertomaster_log_file='mysql-bin.000288',master_log_pos=627625631;

mysql>startslave;

再次查看,复制已恢复正常。

***************************1.row***************************

slave_io_state:queueingmastereventtotherelaylog

master_host:192.168.21.105

master_user:rep

master_port:3306

connect_retry:10

master_log_file:mysql-bin.000289

read_master_log_pos:25433767

relay_log_file:mysql-relay-bin.000003

relay_log_pos:630

relay_master_log_file:mysql-bin.000289

slave_io_running:yes

……

2.10621054等错误解决办法

如果日志中出现了error_code:10621054这样代码,可能是master是跳过错误的insert或update操作,但是被记录到了二进制日志中,slave会依据二进制中的语句做相同的动作,就会报错。

last_errno:1062

last_error:error'duplicateentry'193'forkey'primary''onquery.defaultdatabase:'tso'.query:'insertintotb_infovalues(193,'y10')'

解决办法:

mysql>setgloablesql_slave_skip_counter=1;

在主从库维护中,有时候需要跳过某个无法执行的命令,需要在slave处于stop状态下,执行setglobalsql_slave_skip_counter=n以跳过命令。常用的且不易用错的是n=1的情况,这里详细介绍n的意义,及使用注意事项。

mysql从库从主库上复制binlog文件内容到本地执行。在binlog上命令以event的形式存在,并非一个命令对应一个event。以一个insert语句为例(引擎innodb、binglog_format=statement),在binlog中实际上有三个event,分别为begin\insert\commit。命令类型都是query_log_event。

而setglobalsql_slave_skip_counter=n的意思,即为在startslave时,从当前位置起,跳过n个event。每跳过一个event,则n--。

如果当前的执行位置是某个insert语句开头,那使用n=1实际上是从begin\insert\commit的第二个开始执行,这个insert语句还是不能被跳过?

实际上这里还有两个策略:

1、若n=1且当前event为begin,则n不变,跳过当前event继续。

2、若n=1且当前event处于一个事务之内(begin之后,commit之前),则n不变,跳过当前event继续。

说明:其实上面两个策略合起来就是一句话,当n=1时,会连续跳过若干个event,直到当前所在的事务结束。

当然如果n>1,则每跳过一个event都要n--.

命令举例:

所以我们平时最常用的n=1的情况,都是下一个事务。

假设某个pos之后执行如下命令(引擎innodb、binglog_format=statement),

insertintotvalues(x1);

begin;

insertintotvalues(x2);

insertintotvalues(x3);

commit;

insertintotvalues(x4);

你的从库stop在pos上,假设你要跳过前面几个命令直接执行插入x4的操作,则你的n设置为4或5或6或7均可。(x1语句为3个event)

其他说明:

上面举例中都特别说明了在innodb引擎和statement模式下。其他情况区别如下:

1、若引擎为myisam(等不支持事务的引擎),且在statement下,则binlog中不会有begin和commit,每个命令都是一个event;

2、row模式的binlog里,一个insert语句实际上是两个event(table_map_event和row_log_event),计算时应与statement不同。

3、在row模式下,不论引擎是否支持事务,一个insert语句都会加上begin和commit,也即变成4个event。

4、基于innodb引擎表的insert/delete/update操作都有显式样的begin/commit.

上面举的这个例子中,若为row模式,则要直接执行x4语句需要设置的n为5~10均可。

小结:

1、setglobalsql_slave_skip_counter=n中的n是指跳过n个event

2、最好记的是n被设置为1时,效果跳过下一个事务。

3、跳过第n个event后,位置若刚好落在一个事务内部,则会跳过这整个事务

4、一个insert/update/delete不一定只对应一个event,由引擎和日志格式决定

通常情况下从数据库在复制时发现任何错误都会停止复制,这样做是为了保证与主数据库数据完整性,有时候一些错误不会影响到主从数据完整性的问题我们就可以修改slave配置文件来/etc/my.cnf忽略:

slave-skip-errors=1062

如果发生代码为1062的错误都会被忽略

如果发生代码为1062和1054的错误都会被忽略

忽略所有错误

3.通用解决办法

在从库上运行以下shell程序,把数据库从主库上导到从库上(红色部分根据实际修改),重新设置同步binlog日志文件和同步点。

#!/bin/sh

#

#description:recovemysqlreplication.

read-p"masterip:"master_ip

read-p"masteradminusername:"master_admin_username

read-p"masteradminpassword:"master_admin_password

echo"-->lockmaster..."

mysql-h$master_ip-u$master_admin_username-p$master_admin_password-e"flushtableswithreadlock;"

echo"-->getmasterlogstate..."

mysql-h$master_ip-u$master_admin_username-p$master_admin_password-e"showmasterstatus\g;">masterstatus.txt

logfile=`grep"file"masterstatus.txt|awk'{print$2}'`

logposition=`grep"position"masterstatus.txt|awk'{print$2}'`

rm-rfmasterstatus.txt

echo"dumpmasterdate..."

#/usr/local/mysql/bin/mysqldump-h$master_ip-u$master_admin_username-p$master_admin_passwordtso>tso.sql

echo"-->unlockmaster..."

mysql-h$master_ip-u$master_admin_username-p$master_admin_password-e"unlocktables;"

echo"-->masterdone"

read-p"changingslave'smaster,enterrootpasswordofmysql:"password

mysql-uroot-p$password<<eof

stopslave;

changemastertomaster_host='$master_ip',master_user='repl',master_password='itserver',master_log_file='$logfile',master_log_pos=$logposition;

usetso;

sourcetso.sql;

startslave;

eof

这种办法能解决任何同步错误,但由于主库要锁表,在数据量比较大的情况耗时较长,建议在生产环境下尽量少使用。

一、mysqlinnodb表空间损坏的恢复

错误日志

innodb:databasepagecorruptionondiskorafailed

innodb:filereadofpage5761.

innodb:youmayhavetorecoverfromabackup.

innodb:itisalsopossiblethatyouroperating

innodb:systemhascorrupteditsownfilecache

innodb:andrebootingyourcomputerremovesthe

innodb:error.

innodb:ifthecorruptpageisanindexpage

innodb:youcanalsotrytofixthecorruption

innodb:bydumping,dropping,andreimporting

innodb:thecorrupttable.youcanusecheck

innodb:tabletoscanyourtableforcorruption.

innodb:seealsohttp://dev.mysql.com/doc/refman/5.5/en/forcing-innodb-recovery.html

innodb:aboutforcingrecovery.

innodb:endingprocessingbecauseofacorruptdatabasepage.

解决方法为:在配置文件[mysqld]段内添加以下行,重启mysql服务。待mysql恢复后,注释这行,再次重启mysql服务。

[mysqld]

innodb_force_recovery=4

说明:

1(srv_force_ignore_corrupt):忽略检查到的corrupt页。

2(srv_force_no_background):阻止主线程的运行,如主线程需要执行fullpurge操作,会导致crash。

3(srv_force_no_trx_undo):不执行事务回滚操作。

4(srv_force_no_ibuf_merge):不执行插入缓冲的合并操作。

5(srv_force_no_undo_log_scan):不查看重做日志,innodb存储引擎会将未提交的事务视为已提交。

6(srv_force_no_log_redo):不执行前滚的操作。

下一篇: 编译原理