Build AtlasMart’s replica set incrementally so configuration revision, initial synchronization, and member readiness are observable.
Initialize a Replica Set, Add Members, Inspect Status, and Understand Configuration Versions
Initialize one member, add fresh secondaries, inspect configuration metadata, and avoid unsafe force reconfiguration.
Learning objectives
Initialize from one member, add fresh members, and recognize STARTUP2/SECONDARY transitions.
Interpret configuration version and
term without editing them manually.
Use rs.conf(), rs.status(), and
configuration commitment evidence.
Explain the newlyAdded safety behavior for new
voting secondaries.
Avoid unsafe forced reconfiguration and sequence membership changes deliberately.
This lesson pins MongoDB Community Server
8.3.8 with
mongodb/mongodb-community-server:8.3.8-ubuntu2204-slim, mongosh 2.10.0, and PyMongo
4.17.0 where the driver is used. The mandatory
topology is a disposable three-member replica set on one Docker
host, with loopback-published diagnostic ports 27087–27089.
Members communicate over a lesson-specific Docker bridge network
by container DNS names. Authentication and TLS are disabled only
for this isolated local learning topology. Feature Compatibility
Version (FCV) is observed and never changed. Unless explicitly
overridden, writes use the deployment default and reads target
the primary; examples that need stronger durability state
w:"majority" explicitly. Run only one Chapter 14
topology at a time and budget roughly 3–4 GB of free RAM plus
disk headroom. Atlas, Search, Vector Search, KMS, and Enterprise
Advanced are not mandatory. This lesson starts with one member
and adds two empty members so initial synchronization and
configuration propagation are visible. Product commands were not
executed in this generation environment because Docker, mongod,
mongosh, and PyMongo are unavailable here; expected state is
documentation-derived and measured values must be recorded on
the learner’s machine.
1. AtlasMart problem: add redundancy without confusing configured with ready
Adding a process to configuration does not instantly produce a
healthy secondary. A new member must receive configuration,
perform initial synchronization as needed, reach
SECONDARY, and become eligible according to
votes/priority. Replica configurations carry an incrementing
version and an election-related term;
members compare them to determine the newest configuration.
docker rm -f atlasmart-mongo-ch14-l2-a atlasmart-mongo-ch14-l2-b atlasmart-mongo-ch14-l2-c 2>/dev/null || truedocker network rm atlasmart-ch14-l2-net 2>/dev/null || truedocker volume rm atlasmart-mongo-ch14-l2-a-data atlasmart-mongo-ch14-l2-b-data atlasmart-mongo-ch14-l2-c-data 2>/dev/null || truedocker network create atlasmart-ch14-l2-netdocker run -d --name atlasmart-mongo-ch14-l2-a --network atlasmart-ch14-l2-net -p 127.0.0.1:27087:27017 -v atlasmart-mongo-ch14-l2-a-data:/data/db mongodb/mongodb-community-server:8.3.8-ubuntu2204-slim --replSet atlasmart-rs14-l2 --bind_ip_alluntil mongosh "mongodb://127.0.0.1:27087/admin?directConnection=true" --quiet --eval 'quit(db.runCommand({ping:1}).ok===1?0:1)'; do sleep 1; donemongosh "mongodb://127.0.0.1:27087/admin?directConnection=true" --quiet --eval 'rs.initiate({_id:"atlasmart-rs14-l2",members:[{_id:0,host:"atlasmart-mongo-ch14-l2-a:27017"}]})'until mongosh "mongodb://127.0.0.1:27087/admin?directConnection=true" --quiet --eval 'quit(db.hello().isWritablePrimary?0:1)'; do sleep 1; donedocker run -d --name atlasmart-mongo-ch14-l2-b --network atlasmart-ch14-l2-net -p 127.0.0.1:27088:27017 -v atlasmart-mongo-ch14-l2-b-data:/data/db mongodb/mongodb-community-server:8.3.8-ubuntu2204-slim --replSet atlasmart-rs14-l2 --bind_ip_alldocker run -d --name atlasmart-mongo-ch14-l2-c --network atlasmart-ch14-l2-net -p 127.0.0.1:27089:27017 -v atlasmart-mongo-ch14-l2-c-data:/data/db mongodb/mongodb-community-server:8.3.8-ubuntu2204-slim --replSet atlasmart-rs14-l2 --bind_ip_all
2. Capture configuration identity before and after each change
const before=rs.conf();printjson({_id:before._id,version:before.version,term:before.term,members:before.members});printjson(db.adminCommand({replSetGetConfig:1,commitmentStatus:true}));printjson(rs.add({_id:1,host:"atlasmart-mongo-ch14-l2-b:27017"}));printjson(rs.conf());printjson(rs.status().members.map(m=>({name:m.name,stateStr:m.stateStr,health:m.health})));printjson(rs.add({_id:2,host:"atlasmart-mongo-ch14-l2-c:27017"}));printjson(rs.conf());printjson(db.adminCommand({replSetGetConfig:1,commitmentStatus:true}));
The server maintains configuration metadata. Starting in MongoDB
5.0, a newly added voting member is temporarily prevented from
counting/electing until it reaches SECONDARY; a transient
newlyAdded field may be visible.
3. Observe STARTUP2 and initial-sync status
for port in 27088 27089; do mongosh "mongodb://127.0.0.1:${port}/admin?directConnection=true" --quiet --eval ' const s=rs.status(); printjson({myState:s.myState,members:s.members.map(m=>({name:m.name,stateStr:m.stateStr}))}); if (s.initialSyncStatus) printjson(s.initialSyncStatus);'done
A fresh member can be STARTUP2 while initial sync clones
data/indexes and applies buffered oplog history. After
successful sync it becomes SECONDARY.
initialSyncStatus is expected to disappear after
initial sync completes.
4. Deliberately wrong: duplicate member then reach for force
Expose configuration validation with a harmless duplicate-host add. The server should reject it; the repair is to correct the desired config, not bypass consensus.
try { rs.add({_id:9,host:"atlasmart-mongo-ch14-l2-b:27017"});} catch (e) { printjson({expectedConfigError:e.codeName || e.name,message:e.message});}printjson(rs.conf());printjson(db.adminCommand({replSetGetConfig:1,commitmentStatus:true}));
Forced reconfiguration bypasses normal safety and can create
unexpected rollback/history outcomes. This lesson deliberately
does not execute rs.reconfig(cfg,{force:true}).
5. Configuration acceptance criteria
| Check | Evidence |
|---|---|
| Identity | All members report the intended set name and reachable member hostnames. |
| Configuration | Intended members, votes/priorities, newer version/appropriate term. |
| Commitment | Current config commitment status is observed where supported. |
| Data readiness | New data-bearing members reach SECONDARY and catch up. |
| Failure domains | Production members are not co-located on one host/power/network domain. |
Production judgment. Membership changes alter quorum math, election eligibility, sync load, disk/network consumption, and availability. Add/remove voting members one at a time, budget oplog window for initial sync, and schedule reconfigurations because they can cause elections. Production requires internal authentication, TLS, and network isolation.
Bridge. Lesson 3 follows the election protocol: heartbeats, terms, votes, priorities, stepdown, and the temporary no-primary window.
docker rm -f atlasmart-mongo-ch14-l2-a atlasmart-mongo-ch14-l2-b atlasmart-mongo-ch14-l2-c atlasmart-mongo-ch14-l2-d 2>/dev/null || truedocker volume rm atlasmart-mongo-ch14-l2-a-data atlasmart-mongo-ch14-l2-b-data atlasmart-mongo-ch14-l2-c-data atlasmart-mongo-ch14-l2-d-data 2>/dev/null || truedocker network rm atlasmart-ch14-l2-net 2>/dev/null || true
Check your understanding
- What do configuration version and term do?
- Why is STARTUP2 not automatically failure?
- Why change voting membership incrementally?
- Why is force reconfiguration dangerous?
- Why does oplog window matter before a large initial sync?
Review the answers
1. They order configuration revisions; term reflects election generation and version increments across revisions.
2. A fresh member may be performing initial sync before becoming SECONDARY.
3. It provides supported consensus checkpoints and limits simultaneous quorum changes.
4. It bypasses normal commitment safety and can produce rollback/history surprises.
5. The new member must retain enough history to bridge changes occurring during the copy.
Authoritative references
- MongoDB 8.3 release notes — Current server release line and patch-sensitive replication behavior.
- Replication — Replica-set purpose, asynchronous replication, failover, and topology concepts.
- Replica set oplog — Oplog semantics, rolling history, and majority-commit retention behavior.
- replSetGetStatus — Member states, optimes, terms, and majority commit point evidence.
- Replica-set configuration — version, term, members, votes, priorities, heartbeats, and election settings.
- Replica-set data synchronization — Initial sync and ongoing oplog application.
- Rollbacks during failover — Divergent former-primary writes and rollback protection.
- Troubleshoot replica sets — Replication lag, oplog window, and operational diagnostics.
- replSetStepDown — Safe primary stepdown and secondary catch-up behavior.
- replSetReconfig — Reconfiguration commitment, elections, and force-reconfiguration risks.
- Retryable writes — Driver retry semantics on replica sets and sharded clusters.
- PyMongo replica-set connections — Seed lists, discovery, failover, and AutoReconnect behavior.
- PyMongo release notes — Current 4.17 driver baseline.
- mongosh release notes — Current 2.10.0 shell baseline.