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

Cloner needs to detect failure to create collection

    • Type: Icon: Bug Bug
    • Resolution: Done
    • Priority: Icon: Major - P3 Major - P3
    • 2.6.2, 2.7.1
    • Affects Version/s: 2.6.1, 2.7.0
    • Component/s: Replication, Storage
    • None
    • ALL

      Issue Status as of May 30, 2014

      ISSUE SUMMARY
      When a collection contains invalid options, cloning it will result in a collection created with default options. As a result, collections with invalid options created by an initial sync or using the copyDatabase command may lose some of their properties like their allocation strategy, or become non-capped collections.

      USER IMPACT
      Different members on a replica set might become out of sync when capped collections become non-capped during initial sync. In this scenario, or when the original storage strategy for a cloned collection is modified, storage utilization may be adversely affected. Only collections created with invalid options are affected by this issue.

      WORKAROUNDS
      N/A

      AFFECTED VERSIONS
      MongoDB production releases 2.6.0 and 2.6.1 are affected by this issue.

      FIX VERSION
      The fix is included in the 2.6.2 production release.

      RESOLUTION DETAILS
      Collections with invalid options are no longer cloned.

      Original description

      Cloner::go() proceeds with a collection copy even if the call to userCreateNS() fails, in which case the collection is created with default options (by the insert of the first document). As a result, collections created by an initial sync or the copydb command can lose their cappedness or allocation strategy.

      Reproduce by creating a collection with invalid options in 2.4.10:

      > db.version()
      2.4.10
      > db.runCommand({create: "foo", capped: true, size: 1024*1024, max: "foobar"})
      { "ok" : 1 }
      > db.foo.insert({})
      Cannot use commands write mode, degrading to compatibility mode
      WriteResult({ "nInserted" : 1 })
      

      And then upgrading to 2.6.1 and attempting to use copydb:

      > db.version()
      2.6.1
      > db.copyDatabase("test","test2")
      { "ok" : 1 }
      > db.system.namespaces.find()
      { "name" : "test.system.indexes" }
      { "name" : "test.foo.$_id_" }
      { "name" : "test.foo", "options" : { "create" : "foo", "capped" : true, "size" : 1048576, "max" : "foobar" } }
      > db.foo.stats().capped
      true
      > db.getSiblingDB("test2").system.namespaces.find()
      { "name" : "test2.foo" } // INCORRECT: "foo" is no longer capped
      { "name" : "test2.system.indexes" }
      { "name" : "test2.foo.$_id_" }
      > db.getSiblingDB("test2").foo.stats().capped
      >
      

            Assignee:
            rassi J Rassi
            Reporter:
            rassi J Rassi
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

              Created:
              Updated:
              Resolved: