/* @file : jstests/fsync_lock_read_secondaries.js * * SERVER 4243 : If there is a pending write due to an fsync lock, all reads are blocked * * This test validates part of SERVER-4243 ticket. Allow reading on secondaries with fsyncLock * mode enabled. Previously oplog application would cause blocking. * The corresponding commit : * https://github.com/mongodb/mongo/commit/73aa870d129bd7d51de946b91c16cc056aaacbc7 */ /* * 1) Create a replica set. * 2) Add some documents to primary. * 3) Wait until the secondary nodes are in state "SECONDARY". * 4) Set secondaryOk on secondary. * 5) Take the fsync lock on a secondary. This will stop replication. * 6) Insert some more documents to primary. * 7) Expect to be able to read from the secondary; the count of documents should * be equal to the number of documents added in step 2. * 8) Release the fsync lock. This will resume replication. * 9) Soon, the secondary should be applying the oplog again, which we should * witness as an increase in the count of documents stored on the secondary. */ (function() { "use strict"; // Load utility methods for replica set tests load("jstests/replsets/rslib.js"); var replTest = new ReplSetTest({name: 'testSet', nodes: 2, oplogSize: 5}); // Start each mongod in the replica set. Returns a list of nodes var nodes = replTest.startSet(); // This will wait for initiation replTest.initiate(); var primary = replTest.getPrimary(); // The default WC is majority and fsyncLock will prevent satisfying any majority writes. assert.commandWorked(primary.adminCommand( {setDefaultRWConcern: 1, defaultWriteConcern: {w: 1}, writeConcern: {w: "majority"}})); var ret = primary.getDB("admin").fsyncLock(); if (!ret.ok) { assert.commandFailedWithCode(ret, ErrorCodes.CommandNotSupported); jsTestLog("Storage Engine does not support fsyncLock, so bailing"); return; } primary.getDB("admin").fsyncUnlock(); var docNum = 100; for (var i = 0; i < docNum; i++) { primary.getDB("foo").bar.save({a: i}); } waitForAllMembers(primary.getDB("foo")); replTest.awaitReplication(); // Calling getPrimary also populates '_secondaries'. var secondaries = replTest.getSecondaries(); secondaries[0].setSecondaryOk(); assert.commandWorked(secondaries[0].getDB("admin").runCommand({fsync: 1, lock: 1})); var docNum = 1000; for (var i = 0; i < docNum; i++) { primary.getDB("foo").bar.save({a: i}); } // Issue a read query on the secondary while holding the fsync lock. // This is what we are testing. Previously this would block. After the fix // this should work just fine. var secondary0count = secondaries[0].getDB("foo").bar.find().itcount(); assert.eq(secondary0count, 100, "Doc count in fsync lock wrong. Expected (=100), found " + secondary0count); assert(secondaries[0].getDB("admin").fsyncUnlock().ok); // The secondary should have equal or more documents than what it had before. assert.soon(function() { return secondaries[0].getDB("foo").bar.find().itcount() > 100; }, "count of documents stored on the secondary did not increase"); replTest.stopSet(); }());