summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndy Schwerin <schwerin@mongodb.com>2014-04-18 17:31:29 -0400
committerAndy Schwerin <schwerin@mongodb.com>2014-04-18 17:33:29 -0400
commit070d58c191ab626605bcdd45db2f7990faa46399 (patch)
treec44a81762cea27d5c84d5de7aad8f02160dfa1ca
parent9ad97ac9fd08cf56d4e6c4bdb5c1b10085b9040c (diff)
downloadmongo-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.err2
-rw-r--r--src/mongo/db/index_builder.cpp3
-rw-r--r--src/mongo/db/repl/oplog.cpp35
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