[SERVER-60321] Lock-free reads can leave CollectionCatalog stashed Created: 29/Sep/21  Updated: 29/Oct/23  Resolved: 04/Mar/22

Status: Closed
Project: Core Server
Component/s: None
Affects Version/s: None
Fix Version/s: 6.0.0-rc0

Type: Bug Priority: Major - P3
Reporter: Henrik Edin Assignee: Henrik Edin
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Depends
Backwards Compatibility: Fully Compatible
Operating System: ALL
Sprint: Execution Team 2021-11-01, Execution Team 2021-11-15, Execution Team 2021-12-13, Execution Team 2022-02-07, Execution Team 2022-02-21, Execution Team 2022-03-07
Participants:
Linked BF Score: 15

 Description   

If the root LFR operation is on a non-existing Collection it will not stash the CollectionCatalog onto the OperationContext

If there is a nested LFR operation under a Lock-free read that did not stash the CollectionCatalog the nested operation will instead do the stashing: https://github.com/mongodb/mongo/blob/45bc7a2c06d788a2fddc8601450d4a1fb8dbf489/src/mongo/db/db_raii.cpp#L142

When the nested LFR lock helper is destroyed the CollectionCatalog will not be unstashed because only the root LFR helper may unstash: https://github.com/mongodb/mongo/blob/45bc7a2c06d788a2fddc8601450d4a1fb8dbf489/src/mongo/db/catalog/collection_catalog.cpp#L1163-L1167

But the root LFR lock helper will not unstash either because it never stashed anything: https://github.com/mongodb/mongo/blob/45bc7a2c06d788a2fddc8601450d4a1fb8dbf489/src/mongo/db/catalog/collection_catalog.cpp#L1178

This can cause logic that runs after an operation, like the profile operation, to use this stashed CollectionCatalog. If the system.profile collection is missing that would result in the profile operation not being able to see the collection that was just created: https://github.com/mongodb/mongo/blob/45bc7a2c06d788a2fddc8601450d4a1fb8dbf489/src/mongo/db/introspect.cpp#L142-L144

This can happen on a secondary if the system.profile collection is removed concurrently.



 Comments   
Comment by Githook User [ 04/Mar/22 ]

Author:

{'name': 'Henrik Edin', 'email': 'henrik.edin@mongodb.com', 'username': 'henrikedin'}

Message: SERVER-60321 Fix edge cases when setting up state for Lock-free reads

When LFR is setup we should now always:

  • Open a storage snapshot
  • Stash the catalog
  • Mark the OperationContext that we are in LFR
    None of the three is done if we are not LFR.

This fixes an edge case where the opCtx was marked as LFR when no
collection was found and no snapshot or catalog was stashed. A sub op
could then stash a catalog that wasn't cleaned up properly when tearing
down. Anything that happened afterwords, like the profile logic, now had
a stashed catalog when there should be none.

Also fixed when we lock for reading on a view that we are not marking
the OperationContext to be LFR as we never opened a storage snapshot or
stashed the catalog.
Branch: master
https://github.com/mongodb/mongo/commit/3d6b70fbba9eaf468644d3a35429c71446f9c459

Generated at Thu Feb 08 05:49:30 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.