From 3a55bbd37a050841bc2791b13489dd66c9bc7c67 Mon Sep 17 00:00:00 2001 From: Gregory Wlodarek Date: Mon, 31 Aug 2020 22:59:54 -0400 Subject: SERVER-43664 Speedup WiredTiger storage engine startup for many tables by optimizing WiredTigerUtil::setTableLogging() (cherry picked from commit 8e64b07e3bb363347ee2c11a56aba873365ed74a) --- jstests/disk/wt_table_checks.js | 105 ++++++++++++++++++++++++++++++ jstests/disk/wt_table_checks_read_only.js | 51 +++++++++++++++ 2 files changed, 156 insertions(+) create mode 100644 jstests/disk/wt_table_checks.js create mode 100644 jstests/disk/wt_table_checks_read_only.js (limited to 'jstests/disk') diff --git a/jstests/disk/wt_table_checks.js b/jstests/disk/wt_table_checks.js new file mode 100644 index 00000000000..a97344a19df --- /dev/null +++ b/jstests/disk/wt_table_checks.js @@ -0,0 +1,105 @@ +/** + * Tests that MongoDB sets the WiredTiger table logging settings correctly under different + * circumstances. + * + * @tags: [requires_wiredtiger, requires_journaling] + */ +(function() { + +load('jstests/disk/libs/wt_file_helper.js'); + +// Create a bunch of collections under various database names. +let conn = MongoRunner.runMongod({}); +const dbpath = conn.dbpath; + +for (let i = 0; i < 10; i++) { + assert.commandWorked(conn.getDB(i.toString()).createCollection(i.toString())); +} + +MongoRunner.stopMongod(conn); + +/** + * Test 1. The regular case, where no table logging setting modifications are needed. + */ +jsTest.log("Test 1."); + +conn = startMongodOnExistingPath(dbpath, {}); +checkLog.contains( + conn, + "No table logging settings modifications are required for existing WiredTiger tables. Logging enabled? 1"); +MongoRunner.stopMongod(conn); + +/** + * Test 2. Repair checks all of the table logging settings. + */ +jsTest.log("Test 2."); + +assertRepairSucceeds(dbpath, conn.port, {}); + +// Cannot use checkLog here as the server is no longer running. +let logContents = rawMongoProgramOutput(); +assert( + logContents.indexOf( + "Modifying the table logging settings to 1 for all existing WiredTiger tables. Repair? 1, has previously incomplete table checks? 0") > + 0); + +/** + * Test 3. Explicitly create the '_wt_table_checks' file to force all of the table logging setting + * modifications to be made. + */ +jsTest.log("Test 3."); + +let files = listFiles(dbpath); +for (f in files) { + assert(!files[f].name.includes("_wt_table_checks")); +} + +writeFile(dbpath + "/_wt_table_checks", ""); + +conn = startMongodOnExistingPath(dbpath, {}); +checkLog.contains( + conn, + "Modifying the table logging settings to 1 for all existing WiredTiger tables. Repair? 0, has previously incomplete table checks? 1"); +MongoRunner.stopMongod(conn); + +/** + * Test 4. Change into a single replica set, which requires all of the table logging settings to be + * updated. But simulate an interruption/crash while starting up during the table logging check + * phase. + * + * The next start up will detect an unclean shutdown causing all of the table logging settings to be + * updated. + */ +jsTest.log("Test 4."); + +conn = startMongodOnExistingPath(dbpath, { + replSet: "mySet", + setParameter: + "failpoint.crashAfterUpdatingFirstTableLoggingSettings=" + tojson({"mode": "alwaysOn"}) +}); +assert(!conn); + +// Cannot use checkLog here as the server is no longer running. +logContents = rawMongoProgramOutput(); +assert(logContents.indexOf( + "Crashing due to 'crashAfterUpdatingFirstTableLoggingSettings' fail point") > 0); + +// The '_wt_table_checks' still exists, so all table logging settings should be modified. +conn = startMongodOnExistingPath(dbpath, {}); +checkLog.contains( + conn, + "Modifying the table logging settings to 1 for all existing WiredTiger tables. Repair? 0, has previously incomplete table checks? 1"); +MongoRunner.stopMongod(conn); + +/** + * Test 5. Change into a single node replica set, which requires all of the table logging settings + * to be updated as the node was successfully started up as a standalone the last time. + */ +jsTest.log("Test 5."); + +conn = startMongodOnExistingPath(dbpath, {replSet: "mySet"}); +checkLog.contains( + conn, + "Modifying the table logging settings for all existing WiredTiger tables. Logging enabled? 0"); +MongoRunner.stopMongod(conn); +}()); diff --git a/jstests/disk/wt_table_checks_read_only.js b/jstests/disk/wt_table_checks_read_only.js new file mode 100644 index 00000000000..6d6519f2c85 --- /dev/null +++ b/jstests/disk/wt_table_checks_read_only.js @@ -0,0 +1,51 @@ +/** + * Tests that the table logging settings are not changed during read only mode. + * + * @tags: [requires_wiredtiger] + */ +(function() { + +load('jstests/disk/libs/wt_file_helper.js'); + +// Create a bunch of collections under various database names. +let conn = MongoRunner.runMongod({}); +const dbpath = conn.dbpath; + +for (let i = 0; i < 10; i++) { + assert.commandWorked(conn.getDB(i.toString()).createCollection(i.toString())); +} + +MongoRunner.stopMongod(conn); + +// Option for read only mode. +let options = {queryableBackupMode: ""}; + +// Verifies that setTableLogging() does not get called in read only mode, otherwise the invariant +// would fire. +conn = startMongodOnExistingPath(dbpath, options); +assert(conn); +MongoRunner.stopMongod(conn); + +// Create the '_wt_table_checks' file in the dbpath and ensure it doesn't get removed while in read +// only mode. +let files = listFiles(dbpath); +for (f in files) { + assert(!files[f].name.includes("_wt_table_checks")); +} + +writeFile(dbpath + "/_wt_table_checks", ""); + +conn = startMongodOnExistingPath(dbpath, options); +assert(conn); +MongoRunner.stopMongod(conn); + +let hasWTTableChecksFile = false; +files = listFiles(dbpath); +for (f in files) { + if (files[f].name.includes("_wt_table_checks")) { + hasWTTableChecksFile = true; + } +} + +assert(hasWTTableChecksFile); +}()); -- cgit v1.2.1