summaryrefslogtreecommitdiff
path: root/jstests/core/fsync.js
diff options
context:
space:
mode:
authorDavid Hows <howsdav@gmail.com>2015-09-10 09:41:04 +1000
committerDavid Hows <howsdav@gmail.com>2015-09-14 16:07:50 +1000
commite1d7404eae3a2c33fa4f15105b931f17d0c3d502 (patch)
treed475fcfb4793dcfd711ac48aef15de779383a9df /jstests/core/fsync.js
parentf2fc6a9329e5f24af4724cb5ee50bfdbb02a5116 (diff)
downloadmongo-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.js159
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");
+}());