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

Need to handle case of indexes being created on an empty collection when cloning starts.

    • Fully Compatible
    • Repl 2021-02-22, Repl 2021-03-08

      We are blocking user creations of indexes on empty collections during migration. But the scenario below can still happen in certain cases when collections are created implicitly, only when migrating from a donor secondary. To avoid it, we will add a stage to cloning: we will read the _id of one document from the donor collection before listIndexes. If the collection is empty, we will do the listIndexes, create the indexes, and skip normal cloning (if any documents are added while we're doing the listIndexes, they will be inserted during oplog application). If the collection is not empty, we will proceed normally. Thus we know the collection has become non-empty before we check the indexes.

      There could still be a problem if the collection is made empty through deletes, then an index created, then documents inserted. However, that can only happen with explicit user-created indexes (which are blocked), not implicit indexes.

      — old description follows---
      In the current implementation, "CreateIndexes" oplog entry gets generated only when the indexes are created on empty collections. And, the secondary oplog applier applier on processing CreateIndexes oplog entry performs single phase index build assuming that the collection is empty. Doing single phase index builds on non-empty collections would be performance problem as it can make cause replication lag. To avoid it, we moved to 2-phase index build. But with the multi-tenant migration project, there are chances that the primary can generate "CreateIndexes" oplog entry on non-empty collections and bringing the perf problem back. Consider the below sequence.

      Donor: At TS:11, created a collection 'foo'.
      Recipient: At TS:12, starts the "foo" collection cloner and performs "listIndexes" cmd on donor and gets the result as empty.
      Donor: At TS:13, creates an index 'a_1' on empty collection and createIndexBuild oplog gets generated.
      Donor : At TS:15 - TS:20, documents gets inserted into 'foo' collection.
      Recipient: At TS:30 , finishes cloning the collection 'foo' and has cloned all the 'foo' collection docs from TS:15 thru TS:20.
      Recipient: At TS:31, moves to tenant oplog applier phase and starts applying "createIndexes" oplog entry at donor timestamp TS(12) on a non-empty collection "foo". The recipient primary now generates "createIndexes" oplog entry on non-empty collection "foo".

      P.S: Apart from "createIndexes" cmd, "renameCollection" cross-db also generates "createIndexes" oplog entry on the intermediate temp collection.

            Assignee:
            matthew.russotto@mongodb.com Matthew Russotto
            Reporter:
            suganthi.mani@mongodb.com Suganthi Mani
            Votes:
            0 Vote for this issue
            Watchers:
            7 Start watching this issue

              Created:
              Updated:
              Resolved: