bigywater.tech
MongoDB · 66

initial sync:新节点加入时做了哪几步

新节点加入时 initial sync 做了哪几步?怎么看进度?期间的写入会不会丢?这篇给副本集加一个新成员,记录状态、进度、日志,最后用 dbHash 核对数据。

2.5 s
121 MB 数据的 initial sync 总耗时(STARTUP2 到 SECONDARY)
dbHash 相同
同步完成后 primary 与新成员逐集合的哈希完全一致
1,784 对 429 条
primary 与新成员的 oplog 条目数:新成员只有同步点之后的历史

状态

实测 · 本机执行输出
  成员状态变化(距加入的秒数): [(0.01, 'STARTUP'), (0.78, 'STARTUP2'), (2.55, 'SECONDARY')]
  initial sync 总耗时约 2.5 s(数据 121 MB);同步期间 primary 上并发写入了 278 轮(每轮一个 $inc 加一个 insert)

新成员依次经过 STARTUP、STARTUP2(正在 initial sync)、SECONDARY。

进度

实测 · 本机执行输出
  initialSyncStatus 的键: ['appliedOps', 'approxTotalBytesCopied', 'approxTotalDataSize', 'bytesPerSecond', 'databases', 'failedInitialSyncAttempts', 'initialSyncAttempts', 'initialSyncOplogFetchingStart', 'initialSyncOplogStart', 'initialSyncStart', 'maxFailedInitialSyncAttempts', 'method', 'phase', 'remainingInitialSyncEstimatedMillis', 'totalAttempts', 'totalInitialSyncElapsedMillis', 'totalTimeUnreachableMillis']
  method = logical;maxFailedInitialSyncAttempts = 10;failedInitialSyncAttempts = 0
       距加入         已复制          总量          复制速度    已应用的 oplog
    0.78 s      0.0 MB    120.8 MB       0.0 MB/s         0
    1.03 s     15.5 MB    120.8 MB       0.0 MB/s         0
    1.28 s     62.0 MB    120.8 MB       0.0 MB/s         0
    1.54 s    108.5 MB    120.8 MB       0.0 MB/s         0
    1.79 s    120.7 MB    120.8 MB       0.0 MB/s         0
    2.04 s    120.7 MB    120.8 MB       0.0 MB/s         0

replSetGetStatus 里的 initialSyncStatus 有 approxTotalBytesCopied、approxTotalDataSize、appliedOps 等字段;方式是 logical(逐个集合复制)。

日志里程碑

实测 · 本机执行输出
  11:42:41.795  Initial sync required. Attempting to start initial sync...
  11:42:41.803  Initial sync started
  11:42:41.803  Starting initial sync attempt
  11:42:41.816  Initial syncer oplog truncation finished
  11:42:41.910  About to abort all running index builders
  11:42:41.931  Failed to refresh key cache
  11:42:43.419  Writing to the oplog and applying operations until stopTimestamp before initial sync can complete
  11:42:43.429  Finished fetching oplog during initial sync
  11:42:43.430  Initial sync attempt finishing up
  11:42:43.430  Initial sync status and statistics
  11:42:43.447  Initial sync done

从 “Initial sync required” 到 “Writing to the oplog and applying operations until stopTimestamp” 再到 “Initial sync done”。

一致性

实测 · 本机执行输出
  primarybig=600,000 small=1000 live=278  dbHash(big)=5b2ec3035bfb…  dbHash(live)=8ede2cb02f76…
  新成员   big=600,000 small=1000 live=278  dbHash(big)=5b2ec3035bfb…  dbHash(live)=8ede2cb02f76…

同步期间 primary 上并发的写入也被带过来,完成后 dbHash 完全相同。

oplog 窗口

实测 · 本机执行输出
  primary oplog 最早 ts = Timestamp(1791776557, 1);新成员 oplog 最早 ts = Timestamp(1791776561, 130);primary oplog 条目数 1,784,新成员 429

新成员的 oplog 只从同步点开始,没有更早的历史,所以更早的 change stream token 在它上面恢复不了。

固定开销

实测 · 本机执行输出
  数据只剩几千个文档:新成员 2.0 s 就进入 SECONDARY(对比 121 MB 时的 2.5 s)

即使数据很少也有约 2 秒的固定开销;数据多时主要是复制数据的时间。

分步演示

initial sync
本步的对象

    本文用到的工具与边界

    • 本机 macOS 27 arm64 / MongoDB 9.0.2(Homebrew 的 mongod、mongos)/ mongosh 2.12.0 / pymongo 4.18.3;每个实验在临时目录里起全新的 mongod(独立 dbpath,端口 9900 以上,只监听 127.0.0.1,WiredTiger 缓存 0.25 GB),需要副本集或分片集群时在本机起多个进程;命令输出来自真实的 mongosh,批量写入、计时与多线程用 pymongo;计时用 time.perf_counter,数字每次运行会有小幅抖动,ObjectId、时间戳等每次运行都不同。单节点副本集加 priority 0、votes 0 的新成员;本机回环,没有网络瓶颈
    • 没有验证:大数据量(GB 级以上)时复制与建索引阶段的耗时分布;fileCopyBased 方式(仅企业版);initial sync 失败重试(failedInitialSyncAttempts)的触发场景;从 secondary 而不是 primary 同步;initial sync 期间对 primary 性能的影响
    京ICP备2026067502号-1京公网安备11010502063487号