mongodblocks

What is a FeatureCompatibilityVersion lock in Mongo?


Versions: mongod 5.0.13, mongosh 1.6. Mongo standalone, no other traffic than mine. When profiling a slow query (find({name: "Pat"}).count() - yes, I could do just count), I get (along many others) a locks section:

locks: {
      FeatureCompatibilityVersion: { acquireCount: { r: Long("102") } },
      ReplicationStateTransition: { acquireCount: { w: Long("1") } },
      Global: { acquireCount: { r: Long("102") } },
      Mutex: { acquireCount: { r: Long("1") } }

Per https://www.mongodb.com/docs/manual/faq/concurrency/ and https://www.mongodb.com/docs/manual/reference/database-profiler/ I see no type of lock that fits the first value (Feature...).

Numbers and symbol r suggest that FCV is global (intent shared) read lock, but its name confuses me, also, why doubling the lock?

AFAIK, feature compatibility is (IIRC, primarily) for using older features in newer versions. What's it doing in locking, especially for a read operation?


Solution

  • AFAIK, feature compatibility is (IIRC, primarily) for using older features in newer versions.

    This is actually a bit backwards for what featureCompatibilityVersion (FCV) is used for in MongoDB. Instead, FCV is about preventing features from persisting data which is incompatible with earlier versions of the database. From the documentation directly:

    Enabling backwards-incompatible features can complicate the downgrade process since you must remove any persisted backwards-incompatible features before you downgrade.

    It is recommended that after upgrading, you allow your deployment to run without enabling backwards-incompatible features for a burn-in period to ensure the likelihood of downgrade is minimal. When you are confident that the likelihood of downgrade is minimal, enable these features.

    Therefore FCV primarily serves to reduce the risk of upgrading by allowing the database to be downgraded more easily. FCV will prevent new features or capabilities available on the upgraded version from being used until its value has similarly been upgraded.

    What's it doing in locking, especially for a read operation?

    To answer that we must dig deeper than the two pages that you linked. There are a variety of guides about the MongoDB architecture that are generally helpful here. The Replication one has a section titled Feature Compatibility Version which points toward a standalone FCV and Feature Flag page. That latter page has an entire section titled SetFCV Locks which likely helps answer your questions on the topic. One particular line which is worth copying back to this answer is:

    Other operations should take this lock in shared mode if they want to ensure that the FCV state does not change at all during the operation.

    The takeaway here is that many operations must check refer to the FCV setting to both make sure that they operate with the appropriate behavior to begin with and so that they maintain that correctness throughout the duration of their execution. While it is not a common operation, an administrator could attempt to modify the FCV value at any time.

    When profiling a slow query (find({name: "Pat"}).count())

    If the motivation for investigating behaviors of the FeatureCompatibilityVersion lock are associated with performance of that query, then I suspect the two things are unrelated. If there were meaningful performance implications to the FCV locking then I would expect that to be more discoverable on their general documentation. It's relatedly notable that the snippet that you've provided also does not report any timeAcquiringMicros for the locking.

    Taking a look at the log entry associated with the slow query is a great start, and understandably locks would be a reasonable section to review. I would think that one potential next step here would be to gather the .explain("executionStats") output and review it for bottlenecks.