一、功能概述
阻塞事务在引擎层的提交或在事务引擎提交后阻塞,直到有rpl_semi_sync_master_wait_for_slave_count个从库确认收到涵盖该事务的binglog。整体架构略,请参考官网相关文档。
二、控制流分析
事务提交时,server会在指定的hook(AFTER_SYNC或AFTER_COMMIT)调用ReplSemiSyncMaster::commitTrx,在其中等待与ACK关联的条件变量,超时时间设置为rpl_semi_sync_source_timeout。
半同步插件加载时会启动一个单独的ACK线程Ack_receiver。
该线程监听从库的ACK包
经过ReplSemiSyncMaster::reportReplyPacket => ReplSemiSyncMaster::handleAck => ReplSemiSyncMaster::reportReplyBinlog一系列调用确定应该唤醒线程后在ActiveTranx::signal_waiting_sessions_up_to中激活相关事务的条件变量。
三、数据流分析
整个ACK过程仅涉及到server_id、binlog文件名和binlog偏移量(已接收的位置点),server_id标识从库,文件名和偏移量标识复制点位。为了与事务关联一般使用gtid,但在半同步插件中仅使用复制点位。
server_id在从库建立连接时由从库提供,从而在register_slave中注册从库。
binglog文件名和偏移量则在ACK包中获取。
四、算法细节
在rpl_semi_sync_master_wait_for_slave_count大于1时使用一个顺序表容器辅助判断已达可用性要求的复制点位。
容器容量设置为rpl_semi_sync_master_wait_for_slave_count。
对于收到的ACK包,如果server_id已被记录则只能更新复制点位而不能增加已完成ACK从库的数量,必不可能因为该ACK包而满足高可用条件唤醒线程;否则在容器中新增一个server_id,如果此时容器满了,说明存在满足高可用条件唤醒线程的可能性,此时在容器中删除进度最慢的从库并检查该进度是否足以满足高可用条件唤醒线程。