Files
mongo/jstests/dur/diskfull.js
2016-03-09 12:18:14 -05:00

166 lines
4.3 KiB
JavaScript

/** Test running out of disk space with durability enabled.
To set up the test, it's required to set up a small partition something like the following:
sudo umount /data/db/diskfulltest/
rm -rf /data/db/diskfulltest
mkdir -p /data/images
dd bs=512 count=83968 if=/dev/zero of=/data/images/diskfulltest.img
/sbin/mkfs.ext2 -m 0 -F /data/images/diskfulltest.img
mkdir -p /data/db/diskfulltest
mount -o loop /data/images/diskfulltest.img /data/db/diskfulltest
*/
startPath = MongoRunner.dataDir + "/diskfulltest";
recoverPath = MongoRunner.dataDir + "/dur_diskfull";
doIt = false;
files = listFiles(MongoRunner.dataDir);
for (i in files) {
if (files[i].name == startPath) {
doIt = true;
}
}
if (!doIt) {
print("path " + startPath + " missing, skipping diskfull test");
doIt = false;
}
function checkNoJournalFiles(path, pass) {
var files = listFiles(path);
if (files.some(function(f) {
return f.name.indexOf("prealloc") < 0;
})) {
if (pass == null) {
// wait a bit longer for mongod to potentially finish if it is still running.
sleep(10000);
return checkNoJournalFiles(path, 1);
}
print("\n\n\n");
print("FAIL path:" + path);
print("unexpected files:");
printjson(files);
assert(false, "FAIL a journal/lsn file is present which is unexpected");
}
}
/** Clear dbpath without removing and recreating diskfulltest directory, as resetDbpath does */
function clear() {
files = listFiles(startPath);
files.forEach(function(x) {
removeFile(x.name);
});
}
function log(str) {
print();
if (str)
print(testname + " step " + step++ + " " + str);
else
print(testname + " step " + step++);
}
function work() {
log("work");
try {
var d = conn.getDB("test");
var big = new Array(5000).toString();
var bulk = d.foo.initializeUnorderedBulkOp();
// This part of the test depends on the partition size used in the build env
// Currently, unused, but with larger partitions insert enough documents here
// to create a second db file
for (i = 0; i < 1; ++i) {
bulk.insert({_id: i, b: big});
}
assert.writeOK(bulk.execute());
} catch (e) {
print(e);
raise(e);
} finally {
log("endwork");
}
}
function verify() {
log("verify");
var d = conn.getDB("test");
c = d.foo.count();
v = d.foo.validate();
// not much we can guarantee about the writes, just validate when possible
if (c != 0 && !v.valid) {
printjson(v);
print(c);
assert(v.valid);
assert.gt(c, 0);
}
}
function runFirstMongodAndFillDisk() {
log();
clear();
conn = MongoRunner.runMongod({
restart: true,
cleanData: false,
dbpath: startPath,
journal: "",
smallfiles: "",
journalOptions: 8 + 64,
noprealloc: ""
});
assert.throws(work, null, "no exception thrown when exceeding disk capacity");
MongoRunner.stopMongod(conn);
sleep(5000);
}
function runSecondMongdAndRecover() {
// restart and recover
log();
conn = MongoRunner.runMongod({
restart: true,
cleanData: false,
dbpath: startPath,
journal: "",
smallfiles: "",
journalOptions: 8 + 64,
noprealloc: ""
});
verify();
log("stop");
MongoRunner.stopMongod(conn);
// stopMongod seems to be asynchronous (hmmm) so we sleep here.
sleep(5000);
// at this point, after clean shutdown, there should be no journal files
log("check no journal files");
checkNoJournalFiles(startPath + "/journal/");
log();
}
function someWritesInJournal() {
runFirstMongodAndFillDisk();
runSecondMongdAndRecover();
}
function noWritesInJournal() {
// It is too difficult to consistently trigger cases where there are no existing journal files
// due to lack of disk space, but
// if we were to test this case we would need to manualy remove the lock file.
// removeFile( startPath + "/mongod.lock" );
}
if (doIt) {
var testname = "dur_diskfull";
var step = 1;
var conn = null;
someWritesInJournal();
noWritesInJournal();
print(testname + " SUCCESS");
}