Uploaded image for project: 'Core Server'
  1. Core Server
  2. SERVER-32989

`repairDatabase` can race with `dropDatabase`.

    • Fully Compatible
    • ALL
    • v3.6
    • Repl 2018-02-12, Repl 2018-02-26
    • 0

      3.6 introduced two phase drops where, with respect to dropDatabase, all collection drops must be majority confirmed before the database drop is processed. When starting to process dropDatabase, the in-memory Database catalog object is marked as "drop pending". This is used to protect against things like collections being created, which is normally protected by the database lock preventing concurrent access. The problem is that when waiting for the drops to become majority confirmed, dropDatabase releases all locks. That is done because locks should not be held by a block that is running a blocking operation.

      The interleaving of `repairDatabase` and `dropDatabase`, specifically, is amusing. `repairDatabase` I believe deletes and recreates the in-memory `Database` object, resetting the `_dropPending` member field to false. This allows a `createCollection` to now occur before the `dropDatabase` finishes being processed.

      Some considerations for addressing this bug:

      I believe this means that anything acquiring a Database object should check Database::isDropPending. Additionally, it may make sense for AutoGetDb to check the drop pending flag as a way to centralize that logic. Note that repairDatabase grabs a global lock, circumventing any protection the AutoGetDb would offer.

            judah.schvimer@mongodb.com Judah Schvimer
            daniel.gottlieb@mongodb.com Daniel Gottlieb (Inactive)
            0 Vote for this issue
            3 Start watching this issue