MySQL维护一个列队,叫GAQ(group assigned queue),当SQL协调器线程在分发莫事物时,会将这个事物加入这个列队,然后才会寻找一个空闲的worker线程来执行。在将每一个事物分发到worker之后,都会分配一个编号,这个编号一段时间时不变的,在事物被worker线程执行完成之后,的信息就会被刷新一次。
每个worker线程独立的位置信息都被存放在mysql.slave_worker_info表中,在该表中有多少个并行复制的线程,就会有多少行。(如果时多主复制,每个通道都有slave_parallel-workers变量制定的记录数)。
在多线程复制的执行过程中,随着每个worker线程不断地应用事物的binlog,检查点在GAQ中被不断地向前推进,每个worker线程通过checkpoint_point_bitmap字段记录自己已经执行过的事物和每个已经事物与之对应的当时最新检查点位置。
执行检查点过程:
1.在GAQ中从尾部开始扫描,如果时已经执行过的事物,则直接将其从列队中删除
2.持续扫描GAQ,直到找到一个未被执行过的事物即停止扫描
3.在2步骤中,扫描动作停止前扫描到的最后一个事物被确定为检查点的最新位置,并标记为LWM
4.将当前标记为LWM的这个事物的位置(master_log_pos和relay_log_pos位置)设置为此检查点对应的位置
5.通过所有的worker线程检查自己检查点,也就是查看每个worker线程自己的checkpoint_seqno字段值,这个字段值是每个worker线程在执行事物提交时更新的,更新的字段值为每个worker线程在做事物提交时对应的最新检查点的相应位置
6.将本次执行检查点的位置记录到mysql.slave_relay_log_info表中,作为全局binlog应用的位置。