mongodb runtime_error ai_generated true

MongoServerError: TransactionTooOldForSnapshot: Read timestamp is older than the oldest timestamp in the storage engine

ID: mongodb/transaction-snapshot-too-old

Also available as: JSON · Markdown · 中文
85%Fix Rate
85%Confidence
1Evidence
2024-06-01First Seen

Version Compatibility

VersionStatusIntroducedDeprecatedNotes
mongodb-4.0 active
mongodb-4.2 active
mongodb-4.4 active
mongodb-5.0 active
mongodb-6.0 active
mongodb-7.0 active

Root Cause

A multi-document transaction attempted to read from a snapshot that has been pruned by the storage engine due to cache pressure or write conflicts.

generic

中文

多文档事务尝试读取已被存储引擎由于缓存压力或写入冲突修剪的快照。

Official Documentation

https://www.mongodb.com/docs/manual/core/transactions/

Workarounds

  1. 85% success Reduce transaction duration by committing quickly. Keep transactions as short as possible; avoid long-running transactions with many operations. Example: session.startTransaction(); await collection1.insertOne(a); await collection2.updateOne(b); await session.commitTransaction();
    Reduce transaction duration by committing quickly. Keep transactions as short as possible; avoid long-running transactions with many operations. Example: session.startTransaction(); await collection1.insertOne(a); await collection2.updateOne(b); await session.commitTransaction();
  2. 70% success Increase the WiredTiger cache size to retain older snapshots: storage.wiredTiger.engineConfig.cacheSizeGB: 8. Restart mongod.
    Increase the WiredTiger cache size to retain older snapshots: storage.wiredTiger.engineConfig.cacheSizeGB: 8. Restart mongod.
  3. 80% success If the transaction conflicts with writes, use retry logic with exponential backoff. Example in Python: for i in range(3): try: with client.start_session() as session: session.start_transaction(); ...; session.commit_transaction(); break except pymongo.errors.OperationFailure as e: if 'TransactionTooOldForSnapshot' in str(e): time.sleep(0.5 * (2**i)); continue
    If the transaction conflicts with writes, use retry logic with exponential backoff. Example in Python: for i in range(3): try: with client.start_session() as session: session.start_transaction(); ...; session.commit_transaction(); break except pymongo.errors.OperationFailure as e: if 'TransactionTooOldForSnapshot' in str(e): time.sleep(0.5 * (2**i)); continue

中文步骤

  1. Reduce transaction duration by committing quickly. Keep transactions as short as possible; avoid long-running transactions with many operations. Example: session.startTransaction(); await collection1.insertOne(a); await collection2.updateOne(b); await session.commitTransaction();
  2. Increase the WiredTiger cache size to retain older snapshots: storage.wiredTiger.engineConfig.cacheSizeGB: 8. Restart mongod.
  3. If the transaction conflicts with writes, use retry logic with exponential backoff. Example in Python: for i in range(3): try: with client.start_session() as session: session.start_transaction(); ...; session.commit_transaction(); break except pymongo.errors.OperationFailure as e: if 'TransactionTooOldForSnapshot' in str(e): time.sleep(0.5 * (2**i)); continue

Dead Ends

Common approaches that don't work:

  1. 80% fail

    This does not affect snapshot pruning; the error is about the read timestamp being too old, not the transaction timing out.

  2. 70% fail

    Snapshot read concern is already the default for transactions; the issue is the snapshot itself being pruned.

  3. 100% fail

    This is not configurable and would cause memory exhaustion.