Follow one AtlasMart write from primary acceptance to oplog replication and majority commitment so replica-set durability is observable.

Replica-Set Roles, Primary/Secondary Members, Oplog Replication, and Majority Commit Point

Trace roles, oplog entries, optimes, and majority commitment while separating replication from backup.

Intermediate110–170 minutesReplica-set replication/failure labMongoDB 8.3.8 · mongosh 2.10.0 · PyMongo 4.17.0Last reviewed: September 2026

Learning objectives

01

Define primary, secondary, replica set, oplog, optime, term, and majority commit point before using them.

02

Trace one AtlasMart write from primary application to oplog replication and secondary application.

03

Read rs.status() optimes without confusing replication with majority commitment.

04

Inspect matching oplog history on multiple members while treating oplog internals as version-sensitive evidence.

05

Explain why a replica set improves availability but is not a backup or historical recovery strategy.

Reproducible lab baseline

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 27084–27086. 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. 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: what happened after checkout returned success?

A replica set is a group of mongod processes maintaining copies of the same logical data set. One data-bearing member normally acts as primary and accepts application writes; secondary members copy and apply history asynchronously. The replication record is the oplog, a special capped collection at local.oplog.rs. An optime combines an operation timestamp and election term. The majority commit point is the newest operation known written to a majority of voting data-bearing members—not simply the newest local operation.

isolated three-member replica-set setup (l1)
docker rm -f atlasmart-mongo-ch14-l1-a atlasmart-mongo-ch14-l1-b atlasmart-mongo-ch14-l1-c 2>/dev/null || truedocker network rm atlasmart-ch14-l1-net 2>/dev/null || truedocker volume rm atlasmart-mongo-ch14-l1-a-data atlasmart-mongo-ch14-l1-b-data atlasmart-mongo-ch14-l1-c-data 2>/dev/null || truedocker network create atlasmart-ch14-l1-netdocker run -d --name atlasmart-mongo-ch14-l1-a --network atlasmart-ch14-l1-net -p 127.0.0.1:27084:27017 -v atlasmart-mongo-ch14-l1-a-data:/data/db mongodb/mongodb-community-server:8.3.8-ubuntu2204-slim --replSet atlasmart-rs14-l1 --bind_ip_alldocker run -d --name atlasmart-mongo-ch14-l1-b --network atlasmart-ch14-l1-net -p 127.0.0.1:27085:27017 -v atlasmart-mongo-ch14-l1-b-data:/data/db mongodb/mongodb-community-server:8.3.8-ubuntu2204-slim --replSet atlasmart-rs14-l1 --bind_ip_alldocker run -d --name atlasmart-mongo-ch14-l1-c --network atlasmart-ch14-l1-net -p 127.0.0.1:27086:27017 -v atlasmart-mongo-ch14-l1-c-data:/data/db mongodb/mongodb-community-server:8.3.8-ubuntu2204-slim --replSet atlasmart-rs14-l1 --bind_ip_alluntil mongosh "mongodb://127.0.0.1:27084/admin?directConnection=true" --quiet --eval 'quit(db.runCommand({ping:1}).ok===1?0:1)'; do sleep 1; donemongosh "mongodb://127.0.0.1:27084/admin?directConnection=true" --quiet --eval 'rs.initiate({_id:"atlasmart-rs14-l1",members:[  {_id:0,host:"atlasmart-mongo-ch14-l1-a:27017",priority:1},  {_id:1,host:"atlasmart-mongo-ch14-l1-b:27017",priority:1},  {_id:2,host:"atlasmart-mongo-ch14-l1-c:27017",priority:1}]})'until mongosh "mongodb://127.0.0.1:27084/admin?directConnection=true" --quiet --eval 'quit(db.hello().isWritablePrimary?0:1)'; do sleep 1; donemongosh "mongodb://127.0.0.1:27084/admin?directConnection=true" --quiet --eval 'printjson({server:db.version(),hello:db.hello(),fcv:db.runCommand({getParameter:1,featureCompatibilityVersion:1}).featureCompatibilityVersion})' 

2. Observe member state and commit progress before writing

Start from the server’s current view instead of assuming container A is primary forever. rs.status() includes heartbeat-derived state, so it is a current observation rather than a permanent assignment.

member states and optimes before the test write
const s=rs.status();printjson({set:s.set,myState:s.myState,term:s.term});printjson(s.members.map(m=>({name:m.name,stateStr:m.stateStr,optime:m.optime,optimeDate:m.optimeDate,health:m.health})));printjson(s.optimes);printjson(rs.conf().members.map(m=>({_id:m._id,host:m.host,votes:m.votes,priority:m.priority})));
Field Meaning Do not infer
stateStr Current role such as PRIMARY or SECONDARY. SECONDARY alone does not prove zero lag.
appliedOpTime Newest operation applied to this member’s data state. It is not automatically majority committed.
durableOpTime Newest operation known durable on this member. One-member durability is not majority durability.
lastCommittedOpTime Newest operation known written to a majority. It does not mean every secondary has applied it.
term Election generation attached to history. It is not a wall-clock timestamp.

3. Write with majority acknowledgment and find the oplog entry

The fixture requests w:"majority". The exact oplog document is implementation-facing/version-sensitive evidence; the stable mechanism is that secondaries reproduce primary history by copying and applying oplog entries.

majority-acknowledged AtlasMart order write
const shop=db.getSiblingDB("atlasmart");const orders=shop.orders_ch14_l1;orders.drop();const r=orders.insertOne({_id:"ORD-1401",tenantId:"tenant-a",status:"placed",totalCents:12900,createdAt:new Date()},{writeConcern:{w:"majority",wtimeout:10000}});printjson({acknowledged:r.acknowledged,insertedId:r.insertedId});const s=rs.status();printjson({term:s.term,lastCommittedOpTime:s.optimes.lastCommittedOpTime,appliedOpTime:s.optimes.appliedOpTime,durableOpTime:s.optimes.durableOpTime});const oplog=db.getSiblingDB("local").getCollection("oplog.rs");printjson(oplog.find({ns:"atlasmart.orders_ch14_l1"}).sort({$natural:-1}).limit(3).toArray());
Expected evidence

The insert is acknowledged if majority write concern succeeds. The primary’s oplog contains an entry for the namespace and lastCommittedOpTime should advance to at least the write once the majority condition is met. Exact optimes are runtime values; record them rather than copying canned output.

4. Inspect the same logical history from a secondary

Direct diagnostic connections avoid replica-set discovery through Docker-only hostnames. This is an inspection path, not the application connection architecture.

inspect secondary state and oplog directly
mongosh "mongodb://127.0.0.1:27085/admin?directConnection=true" --quiet --eval 'const h=db.hello(); printjson({host:h.me,secondary:h.secondary,primary:h.primary});const s=rs.status(); printjson({term:s.term,optimes:s.optimes});const o=db.getSiblingDB("local").getCollection("oplog.rs");printjson(o.find({ns:"atlasmart.orders_ch14_l1"}).sort({$natural:-1}).limit(3).toArray());printjson(db.getSiblingDB("atlasmart").orders_ch14_l1.findOne({_id:"ORD-1401"}));' 

If the secondary has applied the write, both the document and matching history are visible. That proves local replication/application at that moment; it does not prove all members are forever caught up.

5. Deliberately wrong: “three copies means backup”

Replication propagates current history, including destructive history. The following disposable delete shows why replicas are not independent restore points.

replicated destructive change
const orders=db.getSiblingDB("atlasmart").orders_ch14_l1;const before=orders.findOne({_id:"ORD-1401"});const d=orders.deleteOne({_id:"ORD-1401"},{writeConcern:{w:"majority",wtimeout:10000}});printjson({before,deletedCount:d.deletedCount,after:orders.findOne({_id:"ORD-1401"})});printjson(db.getSiblingDB("local").getCollection("oplog.rs").find({ns:"atlasmart.orders_ch14_l1"}).sort({$natural:-1}).limit(3).toArray());
Diagnosis and repair

The replica set faithfully replicates the delete. Replication is not point-in-time backup, retention, or protection from authorized logical corruption. Production needs independent restorable backups and tested recovery procedures.

Production judgment. Replica sets add redundancy and failover but consume storage, network, CPU/cache, and operational/security budget. Monitor member state, optime lag, majority commit lag, flow control, disk, and oplog window. A three-member set on one laptop demonstrates protocol mechanisms, not independent failure domains.

Bridge. Lesson 2 builds the topology incrementally so configuration revision and member readiness become observable.

cleanup / full reset
docker rm -f atlasmart-mongo-ch14-l1-a atlasmart-mongo-ch14-l1-b atlasmart-mongo-ch14-l1-c atlasmart-mongo-ch14-l1-d 2>/dev/null || truedocker volume rm atlasmart-mongo-ch14-l1-a-data atlasmart-mongo-ch14-l1-b-data atlasmart-mongo-ch14-l1-c-data atlasmart-mongo-ch14-l1-d-data 2>/dev/null || truedocker network rm atlasmart-ch14-l1-net 2>/dev/null || true

Check your understanding

  1. How does applied optime differ from majority commit point?
  2. Why is local.oplog.rs not an application audit log?
  3. Does w:"majority" mean every secondary has applied the write?
  4. Why does a replicated delete disprove “replication equals backup”?
  5. What does the laptop topology fail to demonstrate?
Review the answers

1. Applied optime is local member progress; majority commit point is history known written to a majority.

2. It is rolling replication machinery with implementation-facing structure, not a permanent business-history contract.

3. No. It satisfies the majority acknowledgement rule, not all-member synchronization.

4. The delete propagates, so replicas do not preserve an independent historical recovery point.

5. Independent host/zone failures and realistic network/storage latency/capacity.

Authoritative references

Keep knowledge open

Help the academy stay free and grow.

If these tutorials save you time, a small donation supports new lessons, technical review, diagrams, examples, and long-term maintenance.

ETHEthereum / ERC-20 only
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0

Send only Ethereum or ERC-20 compatible assets to this address.