diff options
author | matt dannenberg <matt.dannenberg@10gen.com> | 2014-01-07 11:22:05 -0500 |
---|---|---|
committer | Dan Pasette <dan@mongodb.com> | 2014-03-09 19:28:26 -0400 |
commit | 435f6118c5c3f2515970c65aab53f59bb54f2982 (patch) | |
tree | 4680f0fd8fc39a06dd5ec6da20040af2cf63f42e | |
parent | 67c47db36f9195679382062d52db0151251c6074 (diff) | |
download | mongo-435f6118c5c3f2515970c65aab53f59bb54f2982.tar.gz |
SERVER-12264 prevent from tryToGoLiveAsSecondary() from waiting on global writelock during compact
-rw-r--r-- | jstests/replsets/compact.js | 55 | ||||
-rw-r--r-- | src/mongo/db/repl/rs_sync.cpp | 15 |
2 files changed, 63 insertions, 7 deletions
diff --git a/jstests/replsets/compact.js b/jstests/replsets/compact.js new file mode 100644 index 00000000000..7758f4fedf5 --- /dev/null +++ b/jstests/replsets/compact.js @@ -0,0 +1,55 @@ +// test that nodes still respond to heartbeats during compact() SERVER-12264 +var replTest = new ReplSetTest({ name: 'compact', nodes: 3 }); + +replTest.startSet(); +replTest.initiate(); + +var master = replTest.getMaster(); +var compactingSlave = replTest.liveNodes.slaves[0]; + +// populate data +for (i=0; i<1000; i++) { + var bulkInsertArr = []; + for (j=0; j<1000; j++) { + bulkInsertArr.push({x:i, y:j}); + } + master.getDB("compact").foo.insert(bulkInsertArr); +} + +// takes a while to replicate all this data... +replTest.awaitReplication(1000*60*5); + +// run compact in parallel with this rest of the script +var cmd = "tojson(db.getSiblingDB('compact').runCommand({'compact': 'foo', 'paddingFactor': 2}));"; +var compactor = startParallelShell(cmd, compactingSlave.port);; + +// wait for compact to show up in currentOp +assert.soon(function() { + var curop = compactingSlave.getDB('compact').currentOp(); + for (index in curop.inprog) { + entry = curop.inprog[index]; + if (entry.query.hasOwnProperty("compact") && entry.query.compact === "foo" + && entry.hasOwnProperty("locks") && entry.locks.hasOwnProperty("^compact") + && entry.locks["^compact"] === "W") { + return true; + } + } + return false; +}, "compact didn't start in 30 seconds", 30*1000, 100); + +// then check that it is still responding to heartbeats +for (i=0; i<5; i++) { + var start = new Date(); + var result = compactingSlave.getDB("admin").runCommand({"replSetHeartbeat": "compact", + "v": NumberInt(1), + "pv": NumberInt(1), + "checkEmpty": false, + "fromId": NumberInt(0) + }); + var end = new Date(); + assert.eq(result.ok, 1, "heartbeat didn't return properly"); + // wait for 10 seconds because that's how long it takes for a node to be considered down + assert.lt(end - start, 10 * 1000, "heartbeat didn't return quickly enough"); +} + +replTest.stopSet(); diff --git a/src/mongo/db/repl/rs_sync.cpp b/src/mongo/db/repl/rs_sync.cpp index e6e31943a9f..f904d86c5ad 100644 --- a/src/mongo/db/repl/rs_sync.cpp +++ b/src/mongo/db/repl/rs_sync.cpp @@ -585,13 +585,6 @@ namespace replset { bool golive = false; lock rsLock( this ); - Lock::GlobalWrite writeLock; - - // make sure we're not primary, secondary, rollback, or fatal already - if (box.getState().primary() || box.getState().secondary() || - box.getState().fatal()) { - return false; - } if (_maintenanceMode > 0) { // we're not actually going live @@ -603,6 +596,14 @@ namespace replset { return false; } + Lock::GlobalWrite writeLock; + + // make sure we're not primary, secondary, rollback, or fatal already + if (box.getState().primary() || box.getState().secondary() || + box.getState().fatal()) { + return false; + } + minvalid = getMinValid(); if( minvalid <= lastOpTimeWritten ) { golive=true; |