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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
|
/**
* Tests that having journaled write operations since the last checkpoint triggers an error when
* --wiredTigerEngineConfigString log=(recover=error) is specified in combination with --nojournal.
* Also verifies that deleting the journal/ directory allows those operations to safely be ignored.
*/
(function() {
'use strict';
// Skip this test if not running with the "wiredTiger" storage engine.
if (jsTest.options().storageEngine && jsTest.options().storageEngine !== 'wiredTiger') {
jsTest.log('Skipping test because storageEngine is not "wiredTiger"');
return;
}
var dbpath = MongoRunner.dataPath + 'wt_nojournal_skip_recovery';
resetDbpath(dbpath);
// Start a mongod with journaling enabled.
var conn = MongoRunner.runMongod({
dbpath: dbpath,
noCleanData: true,
journal: '',
// Wait an hour between checkpoints to ensure one isn't created after the fsync command is
// executed and before the mongod is terminated. This is necessary to ensure that exactly 90
// documents with the 'journaled' field exist in the collection.
wiredTigerEngineConfigString: 'checkpoint=(wait=3600)'
});
assert.neq(null, conn, 'mongod was unable to start up');
// Execute unjournaled inserts, but periodically do a journaled insert. Triggers a checkpoint
// prior to the mongod being terminated.
var awaitShell = startParallelShell(function() {
for (var iter = 1; iter <= 1000; ++iter) {
var bulk = db.nojournal.initializeUnorderedBulkOp();
for (var i = 0; i < 100; ++i) {
bulk.insert({unjournaled: i});
}
assert.writeOK(bulk.execute({j: false}));
assert.writeOK(db.nojournal.insert({journaled: iter}, {writeConcern: {j: true}}));
// Create a checkpoint slightly before the mongod is terminated.
if (iter === 90) {
assert.commandWorked(db.adminCommand({fsync: 1}));
}
}
}, conn.port);
// After some journaled write operations have been performed against the mongod, send a SIGKILL
// to the process to trigger an unclean shutdown.
assert.soon(function() {
var count = conn.getDB('test').nojournal.count({journaled: {$exists: true}});
if (count >= 100) {
MongoRunner.stopMongod(conn, 9);
return true;
}
return false;
}, 'the parallel shell did not perform at least 100 journaled inserts');
var exitCode = awaitShell({checkExitSuccess: false});
assert.neq(0, exitCode, 'expected shell to exit abnormally due to mongod being terminated');
// Restart the mongod with journaling disabled, but configure it to error if the database needs
// recovery.
conn = MongoRunner.runMongod({
dbpath: dbpath,
noCleanData: true,
nojournal: '',
wiredTigerEngineConfigString: 'log=(recover=error)',
});
assert.eq(null, conn, 'mongod should not have started up because it requires recovery');
// Remove the journal files.
assert(removeFile(dbpath + '/journal'), 'failed to remove the journal directory');
// Restart the mongod with journaling disabled again.
conn = MongoRunner.runMongod({
dbpath: dbpath,
noCleanData: true,
nojournal: '',
wiredTigerEngineConfigString: 'log=(recover=error)',
});
assert.neq(null, conn, 'mongod was unable to start up after removing the journal directory');
var count = conn.getDB('test').nojournal.count({journaled: {$exists: true}});
assert.lte(90, count, 'missing documents that were present in the last checkpoint');
assert.gte(90,
count,
'journaled write operations since the last checkpoint should not have been' +
' replayed');
MongoRunner.stopMongod(conn);
})();
|