summaryrefslogtreecommitdiff
path: root/src/mongo/gotools/src/github.com/mongodb/mongo-tools/mongodump/mongodump.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/gotools/src/github.com/mongodb/mongo-tools/mongodump/mongodump.go')
-rw-r--r--src/mongo/gotools/src/github.com/mongodb/mongo-tools/mongodump/mongodump.go62
1 files changed, 54 insertions, 8 deletions
diff --git a/src/mongo/gotools/src/github.com/mongodb/mongo-tools/mongodump/mongodump.go b/src/mongo/gotools/src/github.com/mongodb/mongo-tools/mongodump/mongodump.go
index 7a7ec7b8efd..b5429504764 100644
--- a/src/mongo/gotools/src/github.com/mongodb/mongo-tools/mongodump/mongodump.go
+++ b/src/mongo/gotools/src/github.com/mongodb/mongo-tools/mongodump/mongodump.go
@@ -34,6 +34,14 @@ import (
"time"
)
+type storageEngineType int
+
+const (
+ storageEngineUnknown = 0
+ storageEngineMMAPV1 = 1
+ storageEngineModern = 2
+)
+
const defaultPermissions = 0755
// MongoDump is a container for the user-specified options and
@@ -57,6 +65,7 @@ type MongoDump struct {
oplogStart primitive.Timestamp
oplogEnd primitive.Timestamp
isMongos bool
+ storageEngine storageEngineType
authVersion int
archive *archive.Writer
// shutdownIntentsNotifier is provided to the multiplexer
@@ -123,6 +132,11 @@ func (dump *MongoDump) ValidateOptions() error {
// Init performs preliminary setup operations for MongoDump.
func (dump *MongoDump) Init() error {
log.Logvf(log.DebugHigh, "initializing mongodump object")
+
+ // this would be default, but explicit setting protects us from any
+ // redefinition of the constants.
+ dump.storageEngine = storageEngineUnknown
+
err := dump.ValidateOptions()
if err != nil {
return fmt.Errorf("bad option: %v", err)
@@ -157,6 +171,7 @@ func (dump *MongoDump) Init() error {
}
dump.manager = intents.NewIntentManager()
+
return nil
}
@@ -511,17 +526,48 @@ func (dump *MongoDump) DumpIntent(intent *intents.Intent, buffer resettableOutpu
if err != nil {
return err
}
- findQuery := &db.DeferredQuery{Coll: session.Database(intent.DB).Collection(intent.C)}
+ intendedDB := session.Database(intent.DB)
+ coll := intendedDB.Collection(intent.C)
+ // it is safer to assume that a collection is a view, if we cannot determine that it is not.
+ isView := true
+ // failure to get CollectionInfo should not cause the function to exit. We only use this to
+ // determine if a collection is a view.
+ collInfo, err := db.GetCollectionInfo(coll)
+ if err != nil {
+ isView = collInfo.IsView()
+ }
+ // The storage engine cannot change from namespace to namespace,
+ // so we set it the first time we reach here, using a namespace we
+ // know must exist. If the storage engine is not mmapv1, we assume it
+ // is some modern storage engine that does not need to use an index
+ // scan for correctness.
+ // We cannot determine the storage engine, if this collection is a view,
+ // so we skip attempting to deduce the storage engine.
+ if dump.storageEngine == storageEngineUnknown && !isView {
+ if err != nil {
+ return err
+ }
+ // storageEngineModern denotes any storage engine that is not MMAPV1. For such storage
+ // engines we assume that collection scans are consistent.
+ dump.storageEngine = storageEngineModern
+ isMMAPV1, err := db.IsMMAPV1(intendedDB, intent.C)
+ if err != nil {
+ log.Logvf(log.Always,
+ "failed to determine storage engine, an mmapv1 storage engine could result in"+
+ " inconsistent dump results, error was: %v", err)
+ } else if isMMAPV1 {
+ dump.storageEngine = storageEngineMMAPV1
+ }
+ }
+
+ findQuery := &db.DeferredQuery{Coll: coll}
switch {
case len(dump.query) > 0:
findQuery.Filter = dump.query
- case dump.OutputOptions.ViewsAsCollections || dump.InputOptions.TableScan || intent.IsSpecialCollection() || intent.IsOplog():
- // ---forceTablesScan runs the query without snapshot enabled
- // The system.profile collection has no index on _id so can't be hinted.
- // Views have an implied aggregation which does not support snapshot.
- // These are all a no-op.
- default:
- // Don't hint autoIndexId:false collections
+ // we only want to hint _id when the storage engine is MMAPV1 and this isn't a view, a
+ // special collection, the oplog, and the user is not asking to force table scans.
+ case dump.storageEngine == storageEngineMMAPV1 && !dump.InputOptions.TableScan &&
+ !isView && !intent.IsSpecialCollection() && !intent.IsOplog():
autoIndexId, found := intent.Options["autoIndexId"]
if !found || autoIndexId == true {
findQuery.Hint = bson.D{{"_id", 1}}