-
Type: Bug
-
Resolution: Fixed
-
Priority: Major - P3
-
Affects Version/s: None
-
Component/s: None
-
None
-
Cluster Scalability
-
Fully Compatible
-
ALL
-
v8.0, v7.0
-
0
Eager reaping is a mechanism to reap internal transactions spawned for retryable writes (ie session ids with txnNumbers in them) before their parent session expires to avoid unbounded memory growth. This works by triggering a callback when a new "client" transaction number is seen, ie the top level txnNumber in a retryable write or client started transaction, and will try to remove internal sessions with session id txnNumbers < the new client txnNumber, on the assumption that the client has forfeited their right to access operations with lower txnNumbers on that logical session. On a mongod, this will call this logic, which assumes it is safe to remove a session that only has a TransactionRouter, because that type is fully in-memory. This is problematic if the TransactionRouter is currently yielded, because some operation will eventually "unyield" and access the TransactionRouter again, expecting certain in-memory state. Currently, we can eager reap in this case, so when the yielded operation checks its session back out, it will recreate the Session with a default constructed TransactionRouter, which triggers an invariant because the participant that generated the response is no longer tracked.
The fix is to make eager reaping refuse to reap a session with a yielded TransactionRouter.