事务的修改是怎么写进 oplog、再复制到 secondary 的?这篇提交一个事务,直接读 local.oplog.rs,看 applyOps 条目的结构、config.transactions 的记录,再对比中止和大事务的情形。
新增了 1 条 oplog 条目
条目的顶层字段: ['lsid', 'ns', 'o', 'op', 'prevOpTime', 't', 'ts', 'txnNumber', 'v', 'wall']
op='c' ns='admin.$cmd';o 里的键 ['applyOps'];applyOps 里有 3 个操作:
op=i ns=test.a o={'_id': 10, 'v': 10} o2={'_id': 10}
op=u ns=test.a o={'$v': 2, 'diff': {'u': {'v': 100}}} o2={'_id': 1}
op=d ns=test.a o={'_id': 2} o2=None
lsid 的键 ['id', 'uid'];txnNumber = 2;prevOpTime.ts = Timestamp(0, 0)(事务的第一条,没有前驱)事务提交时,所有操作被打包成一条 applyOps(op: "c"、ns: "admin.$cmd")写进 oplog,secondary 按这条原子地应用。
新增了 3 条:
op=i ns=test.a o={'_id': 20, 'v': 20} o2={'_id': 20} lsid=无
op=u ns=test.a o={'$v': 2, 'diff': {'u': {'v': 300}}} o2={'_id': 3} lsid=无
op=d ns=test.a o={'_id': 10} o2=None lsid=无同样三个操作不放进事务,各写一条 oplog;事务把它们合成了一条。
update 的 o = {'$v': 2, 'diff': {'u': {'v': 100}}}applyOps 里的 update 条目是 diff({$v: 2, diff: {u: {v: 100}}}),不是整个新文档。
config.transactions 记录: {'txnNum': 2, 'lastWriteOpTime': {'ts': Timestamp(1791774542, 3), 't': 1}, 'lastWriteDate': datetime.datetime(2026, 10, 12, 3, 9, 2, 42000), 'state': 'committed'}
与 applyOps 条目的 ts 相同: Trueconfig.transactions 里该会话的记录 state: "committed",lastWriteOpTime 指向 applyOps 条目。
insert + update 之后 abortTransaction:oplog 里新增了 0 条;文档 _id 30 存在: False
中止的事务在 oplog 里不留任何条目。
oplog 里新增 2 条 applyOps 条目:
条目 1: applyOps 里 16 个操作;partialTxn=True;count=None;prevOpTime.ts=(0,0)
条目 2: applyOps 里 5 个操作;partialTxn=None;count=21;prevOpTime.ts=Timestamp(1791774542, 7)事务的修改太大时拆成多条 applyOps:前面的带 partialTxn: true,最后一条带总操作数 count,用 prevOpTime 链接。