一、概述mysql主从是常用的高可用架构之一,也是应用最广泛的系统架构。在生产环境中,mysql主从复制有时会出现复制错误。MySQL主从复制的问题(Coordinator停止是因为workers有错误...)2.mysql主从复制的原理mysql主从复制是一个异步复制过程(总体感觉是实时同步),mysql主从复制的整个过程是由三个线程完成的。从属端有两个线程(SQL线程和IO线程),主端有另一个(IO线程)。MYSQL主从复制过程在Slave服务器上执行startslave,开启主从复制开关。此时Slave服务器上的IO线程通过Master服务器上授权复制用户的请求连接到Master服务器上。它还请求从binlog日志文件的指定位置发送binlog日志内容。(配置主从复制任务时执行changemaster命令时指定日志文件名和位置)Master服务器收到Slave服务器IO线程的请求后,Master服务器上的IO线程根据奴隶。服务器的IO线程请求的信息指定binlog日志文件的指定位置后,读取binlog日志信息,然后返回给Slave端IO线程。除了binlog日志内容外,返回日志内容后Master服务器端多了一个新的binlog。binlog中的文件名和下一个指定的更新位置。当Slave服务器的IO线程获取到Master服务器IO线程发送过来的日志内容、日志文件和位置点时,添加binlog。日志内容依次写入Slave端的中继日志文件(mysql-relay-bin.xxxxxx)末尾。并在master-info文件中记录新的binlog文件名和位置,这样下次在Master端读取新的binlog日志时,可以告诉Master服务器从哪个文件和从哪里开始请求新的binlog日志新的binlog日志内容。从服务器端的SQL线程实时检测本地中继日志中新增的日志内容,及时中继日志。将文件内容解析为Master端执行的SQL语句内容,SQL应用程序按照语句顺序在Slave服务器本身执行。经过以上过程,可以保证Master和Slave端执行的是同一条SQL语句。当复制状态正常时,master端和slave端的数据是完全一致的。3.问题及解决方案1.Showslavestatus\G显示如下错误信息:Coordinatorstoppedbecausetherewereerror(s)intheworker(s).最近一次失败是:Worker1failedexecutingtransaction...2.根据提示信息定位错误位置情况一:“**Delete_rows”**select*fromperformance_schema.replication_applier_status_by_worker\G原因:一条记录??删除于主人,但无法在奴隶身上找到。解决方法:由于master要删除一条记录,slave找不到,报错。这种情况master删除,slave可以直接跳过。停止从机;设置全局sql_slave_skip_counter=1;启动从机;如果上述命令报错:ERROR1858(HY000):sql_slave_skip_countercannotbesetwhentheserverarerunningwith@@GLOBAL.GTID_MODE=ON。相反,对于您要跳过的每个事务,生成一个与该事务具有相同GTID的空事务,或者改用以下命令:STOPSLAVE;SET@@SESSION.GTID_NEXT='f396f867-d755-11xxx85-005xxxxxb5a:264261655'--在session中设置gtid_next,即跳过这??个GTIDBEGIN;犯罪;--设置空东西SETSESSIONGTID_NEXT=AUTOMATIC;--RestoreGTIDSTARTSLAVE;xxxx情况2:"Duplicate"Last_SQL_Error:CouldnotexecuteWrite_rowseventontablexxx;Duplicateentry'xxx'forkey'PRIMARY',原因:该记录已经存在于slave中,同一条记录是插入主解:从库中删除记录,或跳过记录。然后分别在master和slave上确认。情况三:“Update_rows”(还没遇到待验证)Last_SQL_Error:CouldnotexecuteUpdate_rowseventontablexxx;无法在'xxx'中找到记录,参考原因:在master上更新一条记录,但在slave上找不到它,丢失数据。参考方法:在master上,使用mysqlbinlog分析errorbinlog日志在做什么。/usr/local/mysql/bin/mysqlbinlog--no-defaults-v-v--base64-output=DECODE-ROWSmysql-bin.000010|grep-A'10'794#12030212:08:36服务器ID22end_log_pos794更新行:表ID33标志:STMT_END_F###UPDATEhcy.t1###WHERE###@1=2/*INTmeta=0nullable=0is_null=0*/###@2='bbc'/*STRING(4)meta=65028nullable=1is_null=0*/###SET###@1=2/*INTmeta=0nullable=0is_null=0*/###@2='BTV'/*STRING(4)meta=65028nullable=1is_null=0*/#at794#12030212:08:36服务器id22end_log_pos821Xid=60COMMIT/*!*/;DELIMITER;#日志文件结束ROLLBACK/*mysqlbinlog添加*/;/*!50003SETCOMPLETION_TYPE=@OLD_COMPLETION_TYPE*??/;在从机上,查找更新的记录,该记录不应该存在。mysql>select*fromt1whereid=2;清空set(0.00sec)然后去master查看ysql>select*fromt1whereid=2;+----+-----+|编号|名字|+----+------+|2|BTV|+----+-----+1rowinset(0.00sec)补上slave上缺失的数据,然后跳过报错即可。mysql>insertintot1values(2,'BTV');QueryOK,1rowaffected(0.00sec)mysql>select*fromt1whereid=2;+----+------+|编号|名字|+----+------+|2|BTV|+----+-----+1rowinset(0.00sec)mysql>stopslave;setglobalsql_slave_skip_counter=1;startslave;QueryOK,0rowsaffected(0.01sec)QueryOK,0rowsaffected(0.00sec)QueryOK,0rowsaffected(0.00sec)mysql>showslavestatus\G;……Slave_IO_Running:YesSlave_SQL_Running:Yes4.一般解决方案Mysql主从复制经常遇到错误导致slave端复制被中断。这时候一般需要人工干预。只有跳过错误,才能继续跳过错误。有两种方式4.1跳过指定数量的事务mysql>slavestop;mysql>SETGLOBALSQL_SLAVE_SKIP_COUNTER=1#跳过一个事务mysql>slavestart4.2跳过所有错误或指定类型的错误修改mysql的配置文件,使用slave_skip_errors参数跳过所有错误或指定类型的错误vi/etc/my.cnf[mysqld]#slave-skip-errors=1062,1053,1146#跳过指定错误notype的错误#slave-skip-errors=all#跳过所有错误
