mirror of
https://github.com/mongodb/mongo.git
synced 2024-11-30 00:56:44 +01:00
ad06b5ffbc
delete mode 100644 jstests/core/restart_catalog.js delete mode 100644 jstests/noPassthrough/closeAll_with_background_ops_fails_safely.js delete mode 100644 jstests/noPassthrough/restart_catalog_preserves_min_visible.js delete mode 100644 jstests/noPassthrough/restart_catalog_sharded_cluster.js delete mode 100644 jstests/noPassthroughWithMongod/restart_catalog_interrupts_background_validation.js delete mode 100644 src/mongo/db/commands/restart_catalog_command.cpp delete mode 100644 src/mongo/s/commands/cluster_restart_catalog_command.cpp
148 lines
6.4 KiB
JavaScript
148 lines
6.4 KiB
JavaScript
/**
|
|
* Tests that a collection drop can be rolled back.
|
|
* @tags: [requires_replication, requires_wiredtiger]
|
|
*/
|
|
(function() {
|
|
'use strict';
|
|
|
|
load('jstests/replsets/libs/rollback_test.js');
|
|
|
|
// Returns list of collections in database, including pending drops.
|
|
// Assumes all collections fit in first batch of results.
|
|
function listCollections(database) {
|
|
return assert
|
|
.commandWorked(database.runCommand({listCollections: 1, includePendingDrops: true}))
|
|
.cursor.firstBatch;
|
|
}
|
|
|
|
// Operations that will be present on both nodes, before the common point.
|
|
const collName = 'test.t';
|
|
const renameTargetCollName = 'test.x';
|
|
const noOpsToRollbackCollName = 'test.k';
|
|
let CommonOps = (node) => {
|
|
const coll = node.getCollection(collName);
|
|
const mydb = coll.getDB();
|
|
assert.commandWorked(mydb.createCollection(coll.getName()));
|
|
assert.commandWorked(coll.createIndex({a: 1}));
|
|
assert.commandWorked(coll.insert({_id: 0, a: 0}));
|
|
|
|
// Replicate a drop.
|
|
const replicatedDropCollName = 'w';
|
|
const collToDrop = mydb.getCollection(replicatedDropCollName);
|
|
assert.commandWorked(mydb.createCollection(collToDrop.getName()));
|
|
assert(collToDrop.drop());
|
|
|
|
// This collection will be dropped during a rename.
|
|
const renameTargetColl = node.getCollection(renameTargetCollName);
|
|
assert.commandWorked(mydb.createCollection(renameTargetColl.getName()));
|
|
assert.commandWorked(renameTargetColl.createIndex({b: 1}));
|
|
assert.commandWorked(renameTargetColl.insert({_id: 8, b: 8}));
|
|
assert.commandWorked(renameTargetColl.insert({_id: 9, b: 9}));
|
|
|
|
// This collection will be dropped without any CRUD ops to rollback.
|
|
const noOpsToRollbackColl = node.getCollection(noOpsToRollbackCollName);
|
|
assert.commandWorked(mydb.createCollection(noOpsToRollbackColl.getName()));
|
|
assert.commandWorked(noOpsToRollbackColl.createIndex({c: 1}));
|
|
assert.commandWorked(noOpsToRollbackColl.insert({_id: 20, c: 20}));
|
|
assert.commandWorked(noOpsToRollbackColl.insert({_id: 21, c: 21}));
|
|
};
|
|
|
|
// Operations that will be performed on the rollback node past the common point.
|
|
let RollbackOps = (node) => {
|
|
const coll = node.getCollection(collName);
|
|
|
|
// Rollback algorithm may refer to dropped collection if it has to undo an insert.
|
|
assert.commandWorked(coll.insert({_id: 1, a: 1}));
|
|
|
|
const mydb = coll.getDB();
|
|
const collectionsBeforeDrop = listCollections(mydb);
|
|
assert(coll.drop());
|
|
const collectionsAfterDrop = listCollections(mydb);
|
|
const supportsPendingDrops = mydb.serverStatus().storageEngine.supportsPendingDrops;
|
|
jsTestLog('supportsPendingDrops = ' + supportsPendingDrops);
|
|
if (!supportsPendingDrops) {
|
|
assert.eq(collectionsAfterDrop.length,
|
|
collectionsBeforeDrop.length,
|
|
'listCollections did not report the same number of collections in database ' +
|
|
mydb.getName() + ' after dropping collection ' + coll.getFullName() +
|
|
'. Before: ' + tojson(collectionsBeforeDrop) +
|
|
'. After: ' + tojson(collectionsAfterDrop));
|
|
} else {
|
|
assert.lt(collectionsAfterDrop.length,
|
|
collectionsBeforeDrop.length,
|
|
'listCollections did not report fewer collections in database ' + mydb.getName() +
|
|
' after dropping collection ' + coll.getFullName() + '. Before: ' +
|
|
tojson(collectionsBeforeDrop) + '. After: ' + tojson(collectionsAfterDrop));
|
|
assert.gt(mydb.serverStatus().storageEngine.dropPendingIdents,
|
|
0,
|
|
'There is no drop pending ident in the storage engine.');
|
|
}
|
|
|
|
const renameTargetColl = node.getCollection(renameTargetCollName);
|
|
assert.commandWorked(renameTargetColl.insert({_id: 10, b: 10}));
|
|
assert.commandWorked(renameTargetColl.insert({_id: 11, b: 11}));
|
|
const renameSourceColl = mydb.getCollection('z');
|
|
assert.commandWorked(mydb.createCollection(renameSourceColl.getName()));
|
|
assert.commandWorked(renameSourceColl.renameCollection(renameTargetColl.getName(), true));
|
|
|
|
const noOpsToRollbackColl = node.getCollection(noOpsToRollbackCollName);
|
|
assert(noOpsToRollbackColl.drop());
|
|
|
|
// This collection will not exist after rollback.
|
|
const tempColl = node.getCollection('test.a');
|
|
assert.commandWorked(mydb.createCollection(tempColl.getName()));
|
|
assert.commandWorked(tempColl.insert({_id: 100, y: 100}));
|
|
assert(tempColl.drop());
|
|
};
|
|
|
|
// Set up Rollback Test.
|
|
const rollbackTest = new RollbackTest();
|
|
CommonOps(rollbackTest.getPrimary());
|
|
|
|
const rollbackNode = rollbackTest.transitionToRollbackOperations();
|
|
RollbackOps(rollbackNode);
|
|
|
|
{
|
|
// Check collection drop oplog entry.
|
|
const replTest = rollbackTest.getTestFixture();
|
|
const ops = replTest.dumpOplog(rollbackNode, {ns: 'test.$cmd', 'o.drop': 't'});
|
|
assert.eq(1, ops.length);
|
|
const op = ops[0];
|
|
assert(op.hasOwnProperty('o2'), 'expected o2 field in drop oplog entry: ' + tojson(op));
|
|
assert(op.o2.hasOwnProperty('numRecords'), 'expected count in drop oplog entry: ' + tojson(op));
|
|
assert.eq(2, op.o2.numRecords, 'incorrect count in drop oplog entry: ' + tojson(op));
|
|
}
|
|
|
|
// Check collection rename oplog entry.
|
|
{
|
|
const replTest = rollbackTest.getTestFixture();
|
|
const ops = replTest.dumpOplog(
|
|
rollbackNode, {ns: 'test.$cmd', 'o.renameCollection': 'test.z', 'o.to': 'test.x'});
|
|
assert.eq(1, ops.length);
|
|
const op = ops[0];
|
|
assert(op.hasOwnProperty('o2'), 'expected o2 field in rename oplog entry: ' + tojson(op));
|
|
assert(op.o2.hasOwnProperty('numRecords'),
|
|
'expected count in rename oplog entry: ' + tojson(op));
|
|
assert.eq(4, op.o2.numRecords, 'incorrect count in rename oplog entry: ' + tojson(op));
|
|
}
|
|
|
|
// Wait for rollback to finish.
|
|
rollbackTest.transitionToSyncSourceOperationsBeforeRollback();
|
|
rollbackTest.transitionToSyncSourceOperationsDuringRollback();
|
|
rollbackTest.transitionToSteadyStateOperations();
|
|
|
|
// Check collection count.
|
|
const primary = rollbackTest.getPrimary();
|
|
const coll = primary.getCollection(collName);
|
|
assert.eq(1, coll.find().itcount());
|
|
assert.eq(1, coll.count());
|
|
const renameTargetColl = primary.getCollection(renameTargetCollName);
|
|
assert.eq(2, renameTargetColl.find().itcount());
|
|
assert.eq(2, renameTargetColl.count());
|
|
const noOpsToRollbackColl = primary.getCollection(noOpsToRollbackCollName);
|
|
assert.eq(2, noOpsToRollbackColl.find().itcount());
|
|
assert.eq(2, noOpsToRollbackColl.count());
|
|
|
|
rollbackTest.stop();
|
|
})();
|