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 |
#at627625495 #11101016:35:46serverid1end_log_pos627625631Querythread_id=45613333 exec_time=32758error_code=0 SETTIMESTAMP=1318289746/*!*/; deletefromfreeshipping_bef_updatewherepart='AR-4006WLM'andcode='' /*!*/; #at627625631 #11101016:35:46serverid1end_log_pos627625751Querythread_id=45613333 exec_time=32758error_code=0 SETTIMESTAMP=1318289746/*!*/; deletefromshippingFee_specialwherepart='AR-4006WLM' /*!*/; DELIMITER; #Endoflogfile ROLLBACK/*addedbymysqlbinlog*/; /*!50003SETCOMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; |
找到最接近错误标记627655136的一个position是627625631.再回到slave机器上,changemaster,将postion指向这个位置.
mysql>stopslave; mysql>changemastertomaster_log_file='mysql-bin.000288',master_log_pos=627625631; mysql>startslave; |
再次查看,复制已恢复正常。
mysql>showslavestatus\G |
***************************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 Slave_SQL_Running:Yes …… |
2.10621054等错误解决办法
如果日志中出现了Error_code:10621054这样代码,可能是master是跳过错误的insert或update操作,但是被记录到了二进制日志中,slave会依据二进制中的语句做相同的动作,就会报错。
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_Errno:1062 Last_Error:Error'Duplicateentry'193'forkey'PRIMARY''onquery.Defaultdatabase:'tso'.Query:'insertintotb_infovalues(193,'y10')' …… |
解决办法:
mysql>stopslave; mysql>setgloablesql_slave_skip_counter=1; mysql>startslave; |
在主从库维护中,有时候需要跳过某个无法执行的命令,需要在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的错误都会被忽略
slave-skip-errors=1062,1054
如果发生代码为1062和1054的错误都会被忽略
slave-skip-errors=all
忽略所有错误
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):不执行前滚的操作。