MongoDB复制集数据同步流程

  <标题>            

本文转自张友东的文章,文章链接:   http://www.mongoing.com/archives/2369   

  

正好解释了我的问题,所以转发记录下   

                          

     

  

Mongodb复制集里的二次会从初级上同步数据,以保持副本集所有节点的数据保持一致,数据同步主要包含2个过程:

  
      <李>初始同步李   <李>复制(oplog同步)
  

先通过初始化同步同步全量数据,再通过复制不断重放主要上的oplog同步增量数据。

  

初始同步   

二级启动后,如果满足以下条件之一,会先进行初始同步

  
      <李>二级上oplog为空,比如新加入的空节点李   <李> local.replset.minvalid集合里_initialSyncFlag标记被设置,当初始   同步开始时,同步线程会设置该标记,当初始同步结束时清除该标记,故如果原价   同步过程中途失败,节点重启后发现该标记被设置,就知道应该重新进行初始同步。   <李> BackgroundSync: _initialSyncRequestedFlag被设置。当向节点发送同步命令时,该标记会被设置,此时会强制重新初始同步。
  

初始同步同步流程

  
      <李> minValid集合设置_initialSyncFlag李   <李>获取同步源当前最新的oplog时间戳t0李   <李>从同步源克隆所有的集合数据李   <李>获取同步源最新的oplog时间戳t1李   <李>同步t0 ~ t1所有的oplog李   <李>获取同步源最新的oplog时间戳t2李   <李>同步t1 ~ t2所有的oplog李   <李>从同步源读取指数信息,并建立索引   <李>获取同步源最新的oplog时间戳t3李   <李>同步t2 ~ t3所有的oplog李   <李> minValid集合清除_initialSyncFlag,初始同步结束李
  

复制(同步oplog)

  

初始同步结束后,二次会建立到初级上local.oplog。rs的tailable游标,不断从初级上获取新写入的oplog,并应用到自身。

  

Tailable   光标每次会获取到一批oplog,二次采用多线程重放oplog以提高效率,通过将oplog按照所属的名称空间进行分组,划分到多个线程里,保证同一个名称空间的所有操作都由一个线程来回放,以保证统一名称空间的操作时序跟主要上保持一致(如果引擎支持文档锁,只需保证同一个文档的操作时序与主一致即可)。

  

同步场景分析

  

  <强> 1。副本集初始化

  

初始化选出主后,此时二次上无有效数据,oplog是空的,会先进行初始同步,然后不断的应用新的oplog

  

  <强> 2。新成员加入

  

因新成员上无有效数据,oplog是空的,会先进行初始同步,然后不断的应用新的oplog

  

  <强> 3。有数据的节点加入

  

有数据的节点加入有如下情况:

  
      <李>该节点与副本集其他节点断开连接,一段时间后恢复李   <李>该节点从副本集移除(处)于删除状态,通过replSetReconfig命令将其重新加入李   <李>其他吗?因同一个副本集的成员replSetName配置必须相同,除非有误配置,应该不会有其他场景李
  

此时,如果该节点最新的oplog时间戳,比所有节点最旧的oplog时间戳还要小,该节点将找不到同步源,会一直处于恢复而不能服务;反之,如果能找到同步源,则直接进入复制阶段,不断的应用新的oplog。

  

因oplog太旧而处于复苏的节点目前无法自动恢复,需人工介入处理(故设置合理的oplog大小非常重要),最简单的方式是发送同步命令,让该节点重新进行初始同步。

  

参考资料

  
      <李>   副本集数据同步李   <李>   同步复制组的成员李   <李>   创建游标tailable
  

作者简介

  

  张友东,就职于阿里云飞天技术部,主要关注分布式存储,Nosql等技术领域,参与   TFS(淘宝分布式文件系统),   AliCloudDB为复述等项目的开发工作,欢迎交流

MongoDB复制集数据同步流程