diff options
author | Andy Schwerin <schwerin@mongodb.com> | 2014-04-18 17:31:29 -0400 |
---|---|---|
committer | Andy Schwerin <schwerin@mongodb.com> | 2014-04-18 17:33:29 -0400 |
commit | 070d58c191ab626605bcdd45db2f7990faa46399 (patch) | |
tree | c44a81762cea27d5c84d5de7aad8f02160dfa1ca | |
parent | 9ad97ac9fd08cf56d4e6c4bdb5c1b10085b9040c (diff) | |
download | mongo-070d58c191ab626605bcdd45db2f7990faa46399.tar.gz |
SERVER-13620 When applying operations from the oplog, wait for background operations to complete as necessary.
-rw-r--r-- | src/mongo/base/error_codes.err | 2 | ||||
-rw-r--r-- | src/mongo/db/index_builder.cpp | 3 | ||||
-rw-r--r-- | src/mongo/db/repl/oplog.cpp | 35 |
3 files changed, 36 insertions, 4 deletions
diff --git a/src/mongo/base/error_codes.err b/src/mongo/base/error_codes.err index 42784e4c0e8..ebcedfc46d1 100644 --- a/src/mongo/base/error_codes.err +++ b/src/mongo/base/error_codes.err @@ -92,6 +92,8 @@ error_code("DuplicateKey", 11000) error_code("InterruptedAtShutdown", 11600) error_code("Interrupted", 11601) error_code("OutOfDiskSpace", 14031 ) +error_code("BackgroundOperationInProgressForDatabase", 12586); +error_code("BackgroundOperationInProgressForNamespace", 12587); error_class("NetworkError", ["HostUnreachable", "HostNotFound"]) error_class("Interruption", ["Interrupted", "InterruptedAtShutdown", "ExceededTimeLimit"]) diff --git a/src/mongo/db/index_builder.cpp b/src/mongo/db/index_builder.cpp index af13ee8acd9..92b4c404150 100644 --- a/src/mongo/db/index_builder.cpp +++ b/src/mongo/db/index_builder.cpp @@ -31,6 +31,7 @@ #include "mongo/db/client.h" #include "mongo/db/curop.h" #include "mongo/db/catalog/database.h" +#include "mongo/db/d_concurrency.h" #include "mongo/db/repl/rs.h" #include "mongo/util/mongoutils/str.h" @@ -53,6 +54,8 @@ namespace mongo { LOG(2) << "IndexBuilder building index " << _index; Client::initThread(name().c_str()); + Lock::ParallelBatchWriterMode::iAmABatchParticipant(); + replLocalAuth(); cc().curop()->reset(HostAndPort(), dbInsert); diff --git a/src/mongo/db/repl/oplog.cpp b/src/mongo/db/repl/oplog.cpp index 32a4cccd8bf..85c3c3ed0e2 100644 --- a/src/mongo/db/repl/oplog.cpp +++ b/src/mongo/db/repl/oplog.cpp @@ -38,6 +38,7 @@ #include "mongo/db/auth/action_type.h" #include "mongo/db/auth/authorization_manager.h" #include "mongo/db/auth/authorization_manager_global.h" +#include "mongo/db/background.h" #include "mongo/db/auth/privilege.h" #include "mongo/db/commands.h" #include "mongo/db/commands/dbhash.h" @@ -654,10 +655,36 @@ namespace mongo { verify( opType[1] == 'b' ); // "db" advertisement } else if ( *opType == 'c' ) { - BufBuilder bb; - BSONObjBuilder ob; - _runCommands(ns, o, bb, ob, true, 0); - // _runCommands takes care of adjusting opcounters for command counting. + bool done = false; + while (!done) { + BufBuilder bb; + BSONObjBuilder ob; + _runCommands(ns, o, bb, ob, true, 0); + // _runCommands takes care of adjusting opcounters for command counting. + Status status = Command::getStatusFromCommandResult(ob.done()); + switch (status.code()) { + case ErrorCodes::BackgroundOperationInProgressForDatabase: { + dbtemprelease release; + BackgroundOperation::awaitNoBgOpInProgForDb(nsToDatabaseSubstring(ns)); + break; + } + case ErrorCodes::BackgroundOperationInProgressForNamespace: { + dbtemprelease release; + BackgroundOperation::awaitNoBgOpInProgForNs( + Command::findCommand(o.firstElement().fieldName())->parseNs( + nsToDatabase(ns), o)); + break; + } + default: + warning() << "repl Failed command " << o << " on " << + nsToDatabaseSubstring(ns) << " with status " << status << + " during oplog application"; + // fallthrough + case ErrorCodes::OK: + done = true; + break; + } + } } else if ( *opType == 'n' ) { // no op |