blob: b48774efdd3c2327b8ec72b6d313fd51752f6050 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
|
/*
* Test that the server is able to roll back a 'dropDatabase' entry correctly. This test creates
* a collection, then executes a 'dropDatabase' command, partitioning the primary such that the
* final 'dropDatabase' oplog entry is not replicated. The test then forces rollback of that entry.
*
* The 'dropDatabase' command drops each collection, ensures that the last drop is committed,
* and only then logs a 'dropDatabase' oplog entry. This is therefore the only entry that could
* get rolled back.
*/
(function() {
load("jstests/replsets/libs/rollback_test.js");
load("jstests/libs/check_log.js");
const testName = "rollback_drop_database";
const oldDbName = "oldDatabase";
const newDbName = "newDatabase";
let rollbackTest = new RollbackTest(testName);
let rollbackNode = rollbackTest.getPrimary();
let syncSourceNode = rollbackTest.getSecondary();
// Perform initial insert (common operation).
assert.writeOK(rollbackNode.getDB(oldDbName)["beforeRollback"].insert({"num": 1}));
// Set a failpoint on the original primary, so that it blocks after it commits the last
// 'dropCollection' entry but before the 'dropDatabase' entry is logged.
assert.commandWorked(rollbackNode.adminCommand(
{configureFailPoint: "dropDatabaseHangAfterLastCollectionDrop", mode: "alwaysOn"}));
// Issue a 'dropDatabase' command.
let dropDatabaseFn = function() {
const rollbackDb = "oldDatabase";
var primary = db.getMongo();
jsTestLog("Dropping database " + rollbackDb + " on primary node " + primary.host);
var dbToDrop = db.getSiblingDB(rollbackDb);
assert.commandWorked(dbToDrop.dropDatabase());
};
let waitForDropDatabaseToFinish = startParallelShell(dropDatabaseFn, rollbackNode.port);
// Ensure that we've hit the failpoint before moving on.
checkLog.contains(rollbackNode,
"dropDatabase - fail point dropDatabaseHangAfterLastCollectionDrop enabled");
assert.eq(false,
syncSourceNode.getDB(oldDbName).getCollectionNames().includes("beforeRollback"));
rollbackTest.transitionToRollbackOperations();
// Allow the final 'dropDatabase' entry to be logged on the now isolated primary.
// This is the rollback node's divergent oplog entry.
assert.commandWorked(rollbackNode.adminCommand(
{configureFailPoint: "dropDatabaseHangAfterLastCollectionDrop", mode: "off"}));
waitForDropDatabaseToFinish();
assert.eq(false, rollbackNode.getDB(oldDbName).getCollectionNames().includes("beforeRollback"));
jsTestLog("Database " + oldDbName + " successfully dropped on primary node " +
rollbackNode.host);
rollbackTest.transitionToSyncSourceOperationsBeforeRollback();
// Perform an insert on another database while interfacing with the new primary.
// This is the sync source's divergent oplog entry.
assert.writeOK(syncSourceNode.getDB(newDbName)["afterRollback"].insert({"num": 2}));
rollbackTest.transitionToSyncSourceOperationsDuringRollback();
rollbackTest.transitionToSteadyStateOperations();
rollbackTest.stop();
})();
|