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

dropDatabase commands can be run concurrently, leading to an invalid state

    XMLWordPrintable

    Details

    • Type: Bug
    • Status: Closed
    • Priority: Major - P3
    • Resolution: Fixed
    • Affects Version/s: 4.2.0-rc8
    • Fix Version/s: 4.2.1, 4.3.1
    • Component/s: Storage
    • Labels:
      None
    • Backwards Compatibility:
      Fully Compatible
    • Operating System:
      ALL
    • Backport Requested:
      v4.2
    • Sprint:
      Execution Team 2019-08-12, Execution Team 2019-08-26

      Description

      dropDatabase runs in two steps. First it drops all collections. Then it waits for those drops to replicate (releasing locks). Lastly, it reacquires locks and finalizes the dropDatabase which among other things, writes the dropDatabase oplog entry.

      To manage concurrency control when locks are released, the command sets a drop pending flag. This flag is to prevent collections from being created until the dropDatabase is completed.

      However, that flag does not prevent a second, concurrent dropDatabase from being accepted. A second dropDatabase will not have any collections to drop and fast-paths into writing a dropDatabase oplog entry and deleting the database object.

      One manifestation of this bug is, when adding a third client that creates a collection, an illegal update chain can be created (an untimestamped write).

      | DropDB Client 1                          | DropDB Client2                      | CreateColl                                         |
      |------------------------------------------+-------------------------------------+----------------------------------------------------|
      | Grabs locks                              |                                     |                                                    |
      | Sets dropPending true                    |                                     |                                                    |
      | Drops Coll db.A (replicates) [1]         |                                     |                                                    |
      | Releases locks                           |                                     |                                                    |
      | Waits for replication of Drop A          |                                     |                                                    |
      |                                          | Grabs locks                         |                                                    |
      |                                          | Sets dropPending true               |                                                    |
      |                                          | Drops nothing                       |                                                    |
      |                                          | Finishes dropDatabase               |                                                    |
      |                                          | Writes dropDatabase oplog entry [2] |                                                    |
      |                                          | Deletes DB object                   |                                                    |
      |                                          | Releases locks                      |                                                    |
      |                                          |                                     | Gets locks                                         |
      |                                          |                                     | Creates db.B with a new DB object (replicates) [3] |
      |                                          |                                     | Releases locks                                     |
      | Gets locks                               |                                     |                                                    |
      | Acquires the new DB object               |                                     |                                                    |
      | Finishes dropDatabase                    |                                     |                                                    |
      | Drops db.B (unreplicated, untimestamped) |                                     |                                                    |
      | Writes dropDatabase oplog entry [4]      |                                     |                                                    |
      

      Results in the oplog entries:

      1. Drop `db.A`
      2. DropDatabase `db`.
      3. Create `db.B`
      4. DropDatabase `db`.

        Attachments

          Issue Links

            Activity

              People

              Assignee:
              daniel.gottlieb Daniel Gottlieb
              Reporter:
              daniel.gottlieb Daniel Gottlieb
              Participants:
              Votes:
              0 Vote for this issue
              Watchers:
              13 Start watching this issue

                Dates

                Created:
                Updated:
                Resolved: