mirror of https://github.com/mongodb/mongo
94 lines
3.8 KiB
JavaScript
94 lines
3.8 KiB
JavaScript
/**
|
|
* This test uses the test only `pinHistoryReplicated` command to exercise the DurableHistoryPins
|
|
* across restart.
|
|
*
|
|
* The `pinHistoryReplicated` command will pin the oldest timestamp at the requested time (with an
|
|
* optional rounding up to oldest). If the pin is successfully, the pinned time is written to a
|
|
* document inside `mdb_testing.pinned_timestamp`.
|
|
*
|
|
* When the `TestingDurableHistoryPin` is registered at startup, it will repin the oldest timestamp
|
|
* at the minimum of all documents written to `mdb_testing.pinned_timestamp`.
|
|
*
|
|
* This test does the following:
|
|
*
|
|
* 1) Pin the timestamp with an artificially small value to take advantage of rounding.
|
|
* 2) See that the timestamp is pinned via serverStatus.
|
|
* 3) Restart the node, see the pin persist.
|
|
* 4) Make a new pin at "original pin" + 1
|
|
* 5) Remove the pin at "original pin"
|
|
* 6) Restart the node, see the incremented pin value from serverStatus.
|
|
*
|
|
* @tags: [
|
|
* requires_majority_read_concern,
|
|
* requires_persistence,
|
|
* ]
|
|
*/
|
|
|
|
import {ReplSetTest} from "jstests/libs/replsettest.js";
|
|
|
|
function incTs(ts) {
|
|
return Timestamp(ts.t, ts.i + 1);
|
|
}
|
|
|
|
let replTest = new ReplSetTest({
|
|
name: "use_history_after_restart",
|
|
nodes: 1,
|
|
nodeOptions: {
|
|
setParameter: {
|
|
// Set the history window to zero to more aggressively advance the oldest timestamp.
|
|
minSnapshotHistoryWindowInSeconds: 0,
|
|
logComponentVerbosity: tojson({storage: {recovery: 2}}),
|
|
},
|
|
},
|
|
});
|
|
let nodes = replTest.startSet();
|
|
replTest.initiate();
|
|
let primary = replTest.getPrimary();
|
|
|
|
// Pin with an arbitrarily small timestamp. Let the rounding tell us where the pin ended up. The
|
|
// write to the `mdb_testing.pinned_timestamp` collection is not logged/replayed during replication
|
|
// recovery. Repinning across startup happens before replication recovery. Do a majority write for
|
|
// predictability of the test.
|
|
let result = assert.commandWorked(
|
|
primary.adminCommand({"pinHistoryReplicated": Timestamp(100, 1), round: true, writeConcern: {w: "majority"}}),
|
|
);
|
|
let origPinTs = result["pinTs"];
|
|
jsTestLog({"First pin result": result});
|
|
|
|
// Do some additional writes that would traditionally advance the oldest timestamp.
|
|
for (let idx = 0; idx < 10; ++idx) {
|
|
assert.commandWorked(primary.getDB("test")["coll"].insert({}));
|
|
}
|
|
assert.commandWorked(primary.getDB("test")["coll"].insert({}, {writeConcern: {w: "majority"}}));
|
|
|
|
// Observe that the pinned timestamp matches the command response.
|
|
let serverStatus = assert.commandWorked(primary.adminCommand("serverStatus"));
|
|
let pinnedTs = serverStatus["wiredTiger"]["snapshot-window-settings"]["min pinned timestamp"];
|
|
assert.eq(origPinTs, pinnedTs);
|
|
|
|
// Restarting the primary should preserve the pin.
|
|
replTest.restart(primary);
|
|
primary = replTest.getPrimary();
|
|
serverStatus = assert.commandWorked(primary.adminCommand("serverStatus"));
|
|
pinnedTs = serverStatus["wiredTiger"]["snapshot-window-settings"]["min pinned timestamp"];
|
|
assert.eq(origPinTs, pinnedTs);
|
|
|
|
// Create a new pin at "ts + 1". This should succeed, but have no effect.
|
|
result = assert.commandWorked(primary.adminCommand({"pinHistoryReplicated": incTs(result["pinTs"]), round: false}));
|
|
jsTestLog({"Second pin result": result});
|
|
let newPinTs = result["pinTs"];
|
|
assert.eq(newPinTs, incTs(origPinTs));
|
|
|
|
// Remove the old pin at "ts".
|
|
assert.commandWorked(
|
|
primary.getDB("mdb_testing")["pinned_timestamp"].remove({"pinTs": origPinTs}, {writeConcern: {w: "majority"}}),
|
|
);
|
|
|
|
// Restarting the node should observe a pin at "ts + 1".
|
|
replTest.restart(primary);
|
|
primary = replTest.getPrimary();
|
|
serverStatus = assert.commandWorked(primary.adminCommand("serverStatus"));
|
|
pinnedTs = serverStatus["wiredTiger"]["snapshot-window-settings"]["min pinned timestamp"];
|
|
assert.eq(newPinTs, pinnedTs);
|
|
replTest.stopSet();
|