本篇内容主要讲解“怎么理解主库的DUMP线程”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“怎么理解主库的DUMP线程”吧!

DUMP 线程启动函数调用流程

1、多次select 交互,从库需要保存主库的信息

2、注册从库信息

3、读取从库发送的各种信息

com_binlog_dump_gtid读取从库的信息包括-serverid-需要读取的binlog为名字-读取的位点-从库GTID-kill_zombie_dump_threads杀掉本从库以前的DUMP线程根据UUID和SERVER_ID联合判断-mysql_binlog_send-Binlog_sendersender将读取的信息保存-sender.run()-Binlog_sender::init初始化检测-主库binlog没开不允许连接报错"Binarylogisnotopen"-如果masterserverid为0是不允许连接的报错"Misconfiguredmaster-masterserver_idis0"-如果GITD协议下GITD_MODE主库必须为ON,否则报错Thereplicationsenderthreadcannotstartin""AUTO_POSITIONmode:thisserverhasGTID_MODE=%.192s""insteadofON.-Binlog_sender::check_start_file()进行从库GTID值是否可行的判断,并且打开文件也就是确认binarylog的文件-取出从库关于主库server_uuid的GTID是小于等于主库的GTID如果不是则报错简单的说就是从库比主库多事物了。比如主库1:1-202:1-10从库:1:1-152:1-30判断1-15是否小于等于1-20SlavehasmoreGTIDsthanthemasterhas,usingthemaster'sSERVER_UUID.Thismayindicatethattheendofthebinarylogwastruncatedorthatthelastbinarylogfilewaslost,e.g.,afterapowerordiskfailurewhensync_binlog!=1.Themastermayormaynothaverolledbacktransactionsthatwerealreadyreplicatedtotheslave.Suggesttoreplicateanytransactionsthatmasterhasrolledbackfromslavetomaster,and/orcommitemptytransactionsonmastertoaccountfortransactionsthathavebeencommittedonmasterbutarenotincludedinGTID_EXECUTED."-判断主库的主库的GTID_PURGED是否是从库GTID的子集不是则报错简单的说就是主库已经清理了从库拉取需要的GTID。比如主库GTID_PURGED:1:1-102:1-5从库1:1-10因为从库还需要2:1-5这些GTID主库已经没有了报错TheslaveisconnectingusingCHANGEMASTERTOMASTER_AUTO_POSITION=1,butthemasterhaspurgedbinarylogscontainingGTIDsthattheslaverequires.-上面的情况还存在一种特殊情况比如主库手动删除了binarylogfile。这种情况GTID_PURGED可能没有更新需要继续检查。这一步涉及到实际的binlog扫描。先扫描最后一个binlog拿到P_EVENT检查是否需要拉取的GTID是否在此之后。是就结束,否则检查上一个binlog文件同样拉取P_EVENT检查是否需要拉取的GTID是否在此之后,如果延迟较高并且设置了relaylogreocvery参数的话这个过程可能有些长,比如几十秒。判断方式就是拉取P_EVENT来判断是否是需要的GTID的子集,正常情况这一步还是很快的。如果最后也没找到则同样报错,以前有朋友问我这一步是否能够省略这里知道这一步是不能省略的原因就是前面说的GTID_PURGED可能不准,并且后面要需要打开这个binlog作为扫描的起点binlogTheslaveisconnectingusingCHANGEMASTERTOMASTER_AUTO_POSITION=1,butthemasterhaspurgedbinarylogscontainingGTIDsthattheslaverequires.-将文件存入LOG_INFOm_linfo;中测试打开这个binlog文件进入循环会不断的读取下一个文件,如果不是历史binarylog是当前文件binarylog则会堵塞在send_binlog会不断的读取下,这一层循环是循环的binarylog文件一个文件,如果不是历史binarylog是当然binarylog则会堵塞-open_binlog_file打开文件初始化读取缓存IO_CACHE初始化CACHE为读CACHE大小为8K文件指向相应的binarylog-Binlog_sender::send_binlog-从初始化的位点开始读取-get_binlog_end_pos获取binarylog的最后位置,如果是当前binarylog则堵塞获取并且发送心跳EVENT获取当前读取的位置进入循环获取当前bianrylog的最后位点-如果不是当前binarylog获取需要读取binarylog的最后位置如果(log_pos==end_pos)读取到文件尾部返回0否则返回最后位置-如果是当前binarylogwait_new_events(log_pos)等待新event的到来进入状态sendingallevent-wait_with_heartbeat主要逻辑就是通过&update_cond,&LOCK_binlog_end_pos来完成如果没有新的event则循环等待心跳m_heartbeat_period的描述然后发一个心跳event给从库携带当前binlog的位置。如果有break退出循环了return1pthread_cond_timedwait实现有兴趣可以看看这里的实现。主要在于函数被信号唤醒返回0如果是超时为etimeout。-send_events发送相应位置的binlog给从库while循环为读取相应位置的binlogevent-获取EVENT的TYPE-检查-如果是auto_position=ON不能有匿名event的存在如果有则报错CannotreplicateanonymoustransactionwhenAUTO_POSITION=1,atfile%.512s,position%lld.-如果是GTID_MODE=ON不能有匿名event存在否则报错Cannotreplicateanonymoustransactionwhen@@GLOBAL.GTID_MODE=ON,atfile%.512s,position%lld-如果是GITD_MODE=OFF不能有GTID的event存在CannotreplicateGTID-transactionwhen@@GLOBAL.GTID_MODE=OFF,atfile%.512s,position%lld以上情况实际上如果正常操作是不会出现的,因为每次设置GITD_MODE总是会切换一个binlog,但是如果修改GTID_MODE不按照前面提到的流程可能会出现这些错误。对于第一种错误很容易重现,因为auto_postion是startslave初始化传入的。对于第二种和第三种错误因为EVENT的生成线程和DUMP线程不是同一个线程是异步通知的方式,也就是说生成GTIDevent到发送这段时间如果修改了GTID_MODE可能会出现这些问题。-上面只是取到filename,POS是从从库的masterinfo传送过来,这种情况下还会过滤掉从库已经执行的GTID,因此在GTID模式下主库会进行再次过滤。更加安全。-发送event

到此,相信大家对“怎么理解主库的DUMP线程”有了更深的了解,不妨来实际操作一番吧!这里是亿速云网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!