mongo/jstests/multiVersion/genericBinVersion/skip_level_upgrade.js

92 lines
4.0 KiB
JavaScript

/**
* Tests that skip level upgrades from old binary versions to the latest binary version are both
* not successful and do not corrupt anything to prevent correct binary version start up.
*
* For each binary version older than last-lts:
* - Start a clean node of that version
* - Create a new collection.
* - Insert a document into the new collection.
* - Create an index on the new collection.
* - Benignly fail to upgrade to the latest version.
* - Benignly fail to run --repair on the latest version.
* - Successfully restart the node in the original version.
* - Verify data files are intact.
*
* @tags: [requires_v4_0]
*/
import {IndexCatalogHelpers} from "jstests/libs/index_catalog_helpers.js";
const dbpath = MongoRunner.dataPath + "skip_level_upgrade";
resetDbpath(dbpath);
// We set noCleanData to true in order to preserve the data files within an iteration.
const defaultOptions = {
dbpath: dbpath,
noCleanData: true,
};
// This contains lists of LTS binary versions > 5.0 but < last-lts.
// TODO SERVER-76166: Generate this list programmatically.
//
// Note: To support PIT truncate functionality, the on-disk data format has been changed,
// which older versions (5.0 and below) cannot understand. This functionality is enabled
// for MongoDB from version 8.0 onwards. So, illegal skip-level upgrades from version 5.0 and older
// to version 8.0 or later would cause 8.0 (and later) to rewrite the older files to the newer
// format, which older versions don't understand. This requires manual intervention for the user to
// revert the database back to the older version. (See WT-12869 and WT-10307 for details). That's
// the reason this test will test from 6.0+.
const versions = [{binVersion: "6.0", testCollection: "six_zero"}];
// Iterate through versions specified in the versions list, and follow the steps outlined at
// the top of this test file.
for (let i = 0; i < versions.length; i++) {
let version = versions[i];
let mongodOptions = Object.extend({binVersion: version.binVersion}, defaultOptions);
// Start up an old binary version mongod.
let conn = MongoRunner.runMongod(mongodOptions);
let port = conn.port;
assert.neq(null, conn, "mongod was unable able to start with version " + tojson(version.binVersion));
// Set up a collection on an old binary version node with one document and an index, and
// then shut it down.
let testDB = conn.getDB("test");
assert.commandWorked(testDB.createCollection(version.testCollection));
assert.commandWorked(testDB[version.testCollection].insert({a: 1}));
assert.commandWorked(testDB[version.testCollection].createIndex({a: 1}));
MongoRunner.stopMongod(conn);
// Restart the mongod with the latest binary version on the old version's data files.
// Should fail due to being a skip level upgrade.
mongodOptions = Object.extend({binVersion: "latest"}, defaultOptions);
assert.throws(() => MongoRunner.runMongod(mongodOptions));
// Restart the mongod with the latest version with --repair. Should fail due to being a
// skip level upgrade.
let returnCode = runMongoProgram("mongod", "--port", port, "--repair", "--dbpath", dbpath);
assert.neq(returnCode, 0, "expected mongod --repair to fail with a skip level upgrade");
// Restart the mongod in the originally specified version. Should succeed.
mongodOptions = Object.extend({binVersion: version.binVersion}, defaultOptions);
conn = MongoRunner.runMongod(mongodOptions);
// Verify that the data and indices from previous iterations are still accessible.
testDB = conn.getDB("test");
assert.eq(
1,
testDB[version.testCollection].count(),
`data from ${version.testCollection} should be available; options: ` + tojson(mongodOptions),
);
assert.neq(
null,
IndexCatalogHelpers.findByKeyPattern(testDB[version.testCollection].getIndexes(), {a: 1}),
`index from ${version.testCollection} should be available; options: ` + tojson(mongodOptions),
);
MongoRunner.stopMongod(conn);
resetDbpath(dbpath);
}