diff options
author | David Hows <howsdav@gmail.com> | 2015-09-10 09:41:04 +1000 |
---|---|---|
committer | David Hows <howsdav@gmail.com> | 2015-09-14 16:07:50 +1000 |
commit | e1d7404eae3a2c33fa4f15105b931f17d0c3d502 (patch) | |
tree | d475fcfb4793dcfd711ac48aef15de779383a9df /jstests/core/fsync.js | |
parent | f2fc6a9329e5f24af4724cb5ee50bfdbb02a5116 (diff) | |
download | mongo-e1d7404eae3a2c33fa4f15105b931f17d0c3d502.tar.gz |
SERVER-18899 - Add beginBackup and endBackup to storage API
Diffstat (limited to 'jstests/core/fsync.js')
-rw-r--r-- | jstests/core/fsync.js | 159 |
1 files changed, 110 insertions, 49 deletions
diff --git a/jstests/core/fsync.js b/jstests/core/fsync.js index 14c5d323591..b3cc0a5992e 100644 --- a/jstests/core/fsync.js +++ b/jstests/core/fsync.js @@ -1,49 +1,110 @@ -// Tests the db.fsyncLock/fsyncUnlock features - -// Start with a clean DB -var fsyncLockDB = db.getSisterDB('fsyncLockTestDB'); -fsyncLockDB.dropDatabase(); - -// Test it doesn't work unless invoked against the admin DB -var resFail = fsyncLockDB.runCommand({fsync:1, lock:1}); -assert(!resFail.ok, "fsyncLock command succeeded against DB other than admin."); - -// Uses admin automatically and locks the server for writes -var fsyncLockRes = db.fsyncLock(); -assert(fsyncLockRes.ok, "fsyncLock command failed against admin DB"); -assert(db.currentOp().fsyncLock, "Value in db.currentOp incorrect for fsyncLocked server"); - -// Make sure writes are blocked. Spawn a write operation in a separate shell and make sure it -// is blocked. There is really now way to do that currently, so just check that the write didn't -// go through. -var writeOpHandle = startParallelShell("db.getSisterDB('fsyncLockTestDB').coll.insert({x:1});"); -sleep(1000); - -// Make sure reads can still run even though there is a pending write and also that the write -// didn't get through -assert.eq(0, fsyncLockDB.coll.count({})); - -// Unlock and make sure the insert succeeded -var fsyncUnlockRes = db.fsyncUnlock(); -assert(fsyncUnlockRes.ok, "fsyncUnlock command failed"); -assert(db.currentOp().fsyncLock == null, "fsyncUnlock is not null in db.currentOp"); - -// Make sure the db is unlocked and the initial write made it through. -writeOpHandle(); -fsyncLockDB.coll.insert({x:2}); - -assert.eq(2, fsyncLockDB.coll.count({})); - -// Ensure eval is not allowed to invoke fsyncLock -assert(!db.eval('db.fsyncLock()').ok, "eval('db.fsyncLock()') should fail."); - -// Check that the fsyncUnlock pseudo-command (a lookup on cmd.$sys.unlock) -// still has the same effect as a legitimate 'fsyncUnlock' command -// TODO: remove this in in the release following MongoDB 3.2 when pseudo-commands -// are removed -var fsyncCommandRes = db.fsyncLock(); -assert(fsyncLockRes.ok, "fsyncLock command failed against admin DB"); -assert(db.currentOp().fsyncLock, "Value in db.currentOp incorrect for fsyncLocked server"); -var fsyncPseudoCommandRes = db.getSiblingDB("admin").$cmd.sys.unlock.findOne(); -assert(fsyncPseudoCommandRes.ok, "fsyncUnlock pseudo-command failed"); -assert(db.currentOp().fsyncLock == null, "fsyncUnlock is not null in db.currentOp"); +/** + * Test fsyncLock functionality + * - Skip for all storage engines which don't support fsync + * - Run the fsyncLock command, confirm we lock correctly with currentOp + * - Confirm that backup cursors are created and released in WT + * - Confirm that we cannot insert during fsyncLock + * - Confirm that writes can progress after fsyncUnlock + * - Confirm that the command can be run repeatedly without breaking things + * - Confirm that the pseudo commands and eval can perform fsyncLock/Unlock + */ +(function() { + "use strict"; + + // Start with a clean DB + var fsyncLockDB = db.getSisterDB('fsyncLockTestDB'); + fsyncLockDB.dropDatabase(); + + // Tests the db.fsyncLock/fsyncUnlock features + var storageEngine = db.serverStatus().storageEngine.name; + + // As of SERVER-18899 fsyncLock/fsyncUnlock will error when called on a storage engine + // that does not support the begin/end backup commands. The array below contains a + // list of engines which do support this option and should be ammended as needed. + var supportsFsync = db.fsyncLock(); + + if ( supportsFsync.ok != 1) { + jsTestLog("Skipping test for " + storageEngine + " as it does not support fsync"); + return; + } else { + db.fsyncUnlock(); + } + + var resFail = fsyncLockDB.runCommand({fsync:1, lock:1}); + + // Start with a clean DB + var fsyncLockDB = db.getSisterDB('fsyncLockTestDB'); + fsyncLockDB.dropDatabase(); + + // Test it doesn't work unless invoked against the admin DB + var resFail = fsyncLockDB.runCommand({fsync:1, lock:1}); + assert(!resFail.ok, "fsyncLock command succeeded against DB other than admin."); + + // Uses admin automatically and locks the server for writes + var fsyncLockRes = db.fsyncLock(); + assert(fsyncLockRes.ok, "fsyncLock command failed against admin DB"); + assert(db.currentOp().fsyncLock, "Value in db.currentOp incorrect for fsyncLocked server"); + + // Make sure writes are blocked. Spawn a write operation in a separate shell and make sure it + // is blocked. There is really now way to do that currently, so just check that the write didn't + // go through. + var writeOpHandle = startParallelShell("db.getSisterDB('fsyncLockTestDB').coll.insert({x:1});"); + sleep(1000); + + // Make sure reads can still run even though there is a pending write and also that the write + // didn't get through + assert.eq(0, fsyncLockDB.coll.count({})); + + // Unlock and make sure the insert succeeded + var fsyncUnlockRes = db.fsyncUnlock(); + assert(fsyncUnlockRes.ok, "fsyncUnlock command failed"); + assert(db.currentOp().fsyncLock == null, "fsyncUnlock is not null in db.currentOp"); + + // Make sure the db is unlocked and the initial write made it through. + writeOpHandle(); + fsyncLockDB.coll.insert({x:2}); + + assert.eq(2, fsyncLockDB.coll.count({})); + + // Issue the fsyncLock and fsyncUnlock a second time, to ensure that we can + // run this command repeatedly with no problems. Additionally check that the WT + // backup session and cursor are closed when we unlock. + var beforeSS = db.serverStatus(); + var fsyncLockRes = db.fsyncLock(); + assert(fsyncLockRes.ok, "Second execution of fsyncLock command failed"); + + // Under WiredTiger we will open a backup session and cursor. Confirm that these are opened. + if (storageEngine == "wiredTiger") { + var afterSS = db.serverStatus().wiredTiger.session + beforeSS = beforeSS.wiredTiger.session + assert.gt(afterSS["open session count"], beforeSS["open session count"], + "WiredTiger did not open a backup session as expected"); + assert.gt(afterSS["open cursor count"], beforeSS["open cursor count"], + "WiredTiger did not open a backup cursor as expected"); + } + + var fsyncUnlockRes = db.fsyncUnlock(); + assert(fsyncUnlockRes.ok, "Second execution of fsyncUnlock command failed"); + + if (storageEngine == "wiredTiger") { + var finalSS = db.serverStatus().wiredTiger.session; + assert.eq(beforeSS["open session count"], finalSS["open session count"], + "WiredTiger did not close its backup session as expected"); + assert.eq(beforeSS["open cursor count"], finalSS["open cursor count"], + "WiredTiger did not close its backup cursor as expected after "); + } + + // Ensure eval is not allowed to invoke fsyncLock + assert(!db.eval('db.fsyncLock()').ok, "eval('db.fsyncLock()') should fail."); + + // Check that the fsyncUnlock pseudo-command (a lookup on cmd.$sys.unlock) + // still has the same effect as a legitimate 'fsyncUnlock' command + // TODO: remove this in in the release following MongoDB 3.2 when pseudo-commands + // are removed + var fsyncCommandRes = db.fsyncLock(); + assert(fsyncLockRes.ok, "fsyncLock command failed against admin DB"); + assert(db.currentOp().fsyncLock, "Value in db.currentOp incorrect for fsyncLocked server"); + var fsyncPseudoCommandRes = db.getSiblingDB("admin").$cmd.sys.unlock.findOne(); + assert(fsyncPseudoCommandRes.ok, "fsyncUnlock pseudo-command failed"); + assert(db.currentOp().fsyncLock == null, "fsyncUnlock is not null in db.currentOp"); +}()); |