From f7089e3b12fc79adb583a031da87fed14cc6fc35 Mon Sep 17 00:00:00 2001 From: Benety Goh Date: Sun, 23 Dec 2018 12:16:32 -0500 Subject: SERVER-38604 two phase drop tests that use system.drop namespaces check serverStatus() for support before proceeding --- jstests/replsets/drop_collections_two_phase.js | 7 ++++ ...ctions_two_phase_apply_ops_convert_to_capped.js | 7 ++++ .../drop_collections_two_phase_apply_ops_create.js | 7 ++++ .../drop_collections_two_phase_apply_ops_drop.js | 7 ++++ .../drop_collections_two_phase_apply_ops_rename.js | 7 ++++ .../replsets/drop_collections_two_phase_dbhash.js | 8 +++++ .../drop_collections_two_phase_long_index_names.js | 7 ++++ ...rop_collections_two_phase_rename_drop_target.js | 7 ++++ .../drop_collections_two_phase_step_down.js | 7 ++++ .../drop_collections_two_phase_write_concern.js | 7 ++++ jstests/replsets/drop_databases_two_phase.js | 42 ++++++++++++++++------ .../replsets/initial_sync_update_missing_doc3.js | 8 +++++ jstests/replsets/libs/two_phase_drops.js | 21 +++++++++++ 13 files changed, 131 insertions(+), 11 deletions(-) diff --git a/jstests/replsets/drop_collections_two_phase.js b/jstests/replsets/drop_collections_two_phase.js index 7e5e2075e32..8b6b3bab79e 100644 --- a/jstests/replsets/drop_collections_two_phase.js +++ b/jstests/replsets/drop_collections_two_phase.js @@ -17,6 +17,13 @@ // Initialize replica set. let replTest = twoPhaseDropTest.initReplSet(); + // Check for 'system.drop' two phase drop support. + if (!twoPhaseDropTest.supportsDropPendingNamespaces()) { + jsTestLog('Drop pending namespaces not supported by storage engine. Skipping test.'); + twoPhaseDropTest.stop(); + return; + } + // Create the collection that will be dropped. twoPhaseDropTest.createCollection(collName); diff --git a/jstests/replsets/drop_collections_two_phase_apply_ops_convert_to_capped.js b/jstests/replsets/drop_collections_two_phase_apply_ops_convert_to_capped.js index 013f58afe0b..23992c17a21 100644 --- a/jstests/replsets/drop_collections_two_phase_apply_ops_convert_to_capped.js +++ b/jstests/replsets/drop_collections_two_phase_apply_ops_convert_to_capped.js @@ -16,6 +16,13 @@ // Initialize replica set. let replTest = twoPhaseDropTest.initReplSet(); + // Check for 'system.drop' two phase drop support. + if (!twoPhaseDropTest.supportsDropPendingNamespaces()) { + jsTestLog('Drop pending namespaces not supported by storage engine. Skipping test.'); + twoPhaseDropTest.stop(); + return; + } + // Create the collection that will be dropped. twoPhaseDropTest.createCollection(collName); diff --git a/jstests/replsets/drop_collections_two_phase_apply_ops_create.js b/jstests/replsets/drop_collections_two_phase_apply_ops_create.js index b70ca670cd5..792be894d8d 100644 --- a/jstests/replsets/drop_collections_two_phase_apply_ops_create.js +++ b/jstests/replsets/drop_collections_two_phase_apply_ops_create.js @@ -19,6 +19,13 @@ // Initialize replica set. let replTest = twoPhaseDropTest.initReplSet(); + // Check for 'system.drop' two phase drop support. + if (!twoPhaseDropTest.supportsDropPendingNamespaces()) { + jsTestLog('Drop pending namespaces not supported by storage engine. Skipping test.'); + twoPhaseDropTest.stop(); + return; + } + // Create the collection that will be dropped. twoPhaseDropTest.createCollection(collName); diff --git a/jstests/replsets/drop_collections_two_phase_apply_ops_drop.js b/jstests/replsets/drop_collections_two_phase_apply_ops_drop.js index fe05c05f18e..8cfbca31166 100644 --- a/jstests/replsets/drop_collections_two_phase_apply_ops_drop.js +++ b/jstests/replsets/drop_collections_two_phase_apply_ops_drop.js @@ -17,6 +17,13 @@ // Initialize replica set. let replTest = twoPhaseDropTest.initReplSet(); + // Check for 'system.drop' two phase drop support. + if (!twoPhaseDropTest.supportsDropPendingNamespaces()) { + jsTestLog('Drop pending namespaces not supported by storage engine. Skipping test.'); + twoPhaseDropTest.stop(); + return; + } + // Create the collection that will be dropped. twoPhaseDropTest.createCollection(collName); diff --git a/jstests/replsets/drop_collections_two_phase_apply_ops_rename.js b/jstests/replsets/drop_collections_two_phase_apply_ops_rename.js index 85c9bbab953..8db6ffaf42e 100644 --- a/jstests/replsets/drop_collections_two_phase_apply_ops_rename.js +++ b/jstests/replsets/drop_collections_two_phase_apply_ops_rename.js @@ -17,6 +17,13 @@ // Initialize replica set. let replTest = twoPhaseDropTest.initReplSet(); + // Check for 'system.drop' two phase drop support. + if (!twoPhaseDropTest.supportsDropPendingNamespaces()) { + jsTestLog('Drop pending namespaces not supported by storage engine. Skipping test.'); + twoPhaseDropTest.stop(); + return; + } + // Create the collection that will be dropped. twoPhaseDropTest.createCollection(collName); diff --git a/jstests/replsets/drop_collections_two_phase_dbhash.js b/jstests/replsets/drop_collections_two_phase_dbhash.js index b3b7af136b5..b04b631bc09 100644 --- a/jstests/replsets/drop_collections_two_phase_dbhash.js +++ b/jstests/replsets/drop_collections_two_phase_dbhash.js @@ -23,6 +23,14 @@ // Initialize replica set. let replTest = twoPhaseDropTest.initReplSet(); + + // Check for 'system.drop' two phase drop support. + if (!twoPhaseDropTest.supportsDropPendingNamespaces()) { + jsTestLog('Drop pending namespaces not supported by storage engine. Skipping test.'); + twoPhaseDropTest.stop(); + return; + } + let primaryDB = replTest.getPrimary().getDB(dbName); // Create the collection that will be dropped. diff --git a/jstests/replsets/drop_collections_two_phase_long_index_names.js b/jstests/replsets/drop_collections_two_phase_long_index_names.js index 46745a27427..561dfdaa491 100644 --- a/jstests/replsets/drop_collections_two_phase_long_index_names.js +++ b/jstests/replsets/drop_collections_two_phase_long_index_names.js @@ -28,6 +28,13 @@ // Initialize replica set. let replTest = twoPhaseDropTest.initReplSet(); + // Check for 'system.drop' two phase drop support. + if (!twoPhaseDropTest.supportsDropPendingNamespaces()) { + jsTestLog('Drop pending namespaces not supported by storage engine. Skipping test.'); + twoPhaseDropTest.stop(); + return; + } + // Create the collection that will be dropped. twoPhaseDropTest.createCollection(collName); diff --git a/jstests/replsets/drop_collections_two_phase_rename_drop_target.js b/jstests/replsets/drop_collections_two_phase_rename_drop_target.js index 5a646036fc8..4f989bf337a 100644 --- a/jstests/replsets/drop_collections_two_phase_rename_drop_target.js +++ b/jstests/replsets/drop_collections_two_phase_rename_drop_target.js @@ -30,6 +30,13 @@ // Initialize replica set. let replTest = twoPhaseDropTest.initReplSet(); + // Check for 'system.drop' two phase drop support. + if (!twoPhaseDropTest.supportsDropPendingNamespaces()) { + jsTestLog('Drop pending namespaces not supported by storage engine. Skipping test.'); + twoPhaseDropTest.stop(); + return; + } + // Create the collections that will be renamed and dropped. twoPhaseDropTest.createCollection(fromCollName); twoPhaseDropTest.createCollection(toCollName); diff --git a/jstests/replsets/drop_collections_two_phase_step_down.js b/jstests/replsets/drop_collections_two_phase_step_down.js index 1cd82f9c416..bc2f4c58909 100644 --- a/jstests/replsets/drop_collections_two_phase_step_down.js +++ b/jstests/replsets/drop_collections_two_phase_step_down.js @@ -26,6 +26,13 @@ // Initialize replica set. let replTest = twoPhaseDropTest.initReplSet(); + // Check for 'system.drop' two phase drop support. + if (!twoPhaseDropTest.supportsDropPendingNamespaces()) { + jsTestLog('Drop pending namespaces not supported by storage engine. Skipping test.'); + twoPhaseDropTest.stop(); + return; + } + // Create the collection that will be dropped. twoPhaseDropTest.createCollection(collName); diff --git a/jstests/replsets/drop_collections_two_phase_write_concern.js b/jstests/replsets/drop_collections_two_phase_write_concern.js index 49e98beb568..27b133cb915 100644 --- a/jstests/replsets/drop_collections_two_phase_write_concern.js +++ b/jstests/replsets/drop_collections_two_phase_write_concern.js @@ -30,6 +30,13 @@ // Initialize replica set. let replTest = twoPhaseDropTest.initReplSet(); + // Check for 'system.drop' two phase drop support. + if (!twoPhaseDropTest.supportsDropPendingNamespaces()) { + jsTestLog('Drop pending namespaces not supported by storage engine. Skipping test.'); + twoPhaseDropTest.stop(); + return; + } + // Create the collection that will be dropped. twoPhaseDropTest.createCollection(collName); diff --git a/jstests/replsets/drop_databases_two_phase.js b/jstests/replsets/drop_databases_two_phase.js index e4f4dac378c..8320e523adf 100644 --- a/jstests/replsets/drop_databases_two_phase.js +++ b/jstests/replsets/drop_databases_two_phase.js @@ -17,6 +17,8 @@ (function() { "use strict"; + load('jstests/replsets/libs/two_phase_drops.js'); // For TwoPhaseDropCollectionTest. + // Returns a list of all collections in a given database. Use 'args' as the // 'listCollections' command arguments. function listCollections(database, args) { @@ -103,13 +105,21 @@ }, 'Primary ' + primary.host + ' failed to prepare two phase drop of collection ' + collToDrop.getFullName()); - var dropPendingCollections = listDropPendingCollections(dbToDrop); - assert.eq(1, - dropPendingCollections.length, - "Collection was not found in the 'system.drop' namespace. " + - "Full drop-pending collection list: " + tojson(dropPendingCollections)); - jsTestLog('Primary ' + primary.host + ' successfully started two phase drop of collection ' + - collToDrop.getFullName()); + + // 'collToDrop' is no longer visible with its original name. If 'system.drop' two phase drops + // are supported by the storage engine, check for the drop-pending namespace using + // listCollections. + const supportsDropPendingNamespaces = + TwoPhaseDropCollectionTest.supportsDropPendingNamespaces(replTest); + if (supportsDropPendingNamespaces) { + var dropPendingCollections = listDropPendingCollections(dbToDrop); + assert.eq(1, + dropPendingCollections.length, + "Collection was not found in the 'system.drop' namespace. " + + "Full drop-pending collection list: " + tojson(dropPendingCollections)); + jsTestLog('Primary ' + primary.host + + ' successfully started two phase drop of collection ' + collToDrop.getFullName()); + } // Commands that manipulate the database being dropped or perform destructive catalog operations // should fail with the DatabaseDropPending error code while the database is in a drop-pending @@ -118,10 +128,20 @@ dbToDrop.createCollection('collectionToCreateWhileDroppingDatabase'), ErrorCodes.DatabaseDropPending, 'collection creation should fail while we are in the process of dropping the database'); - assert.commandFailedWithCode( - dbToDrop.adminCommand('restartCatalog'), - ErrorCodes.DatabaseDropPending, - 'restartCatalog should fail if any databases are marked drop-pending'); + + // restartCatalog can only detect that a database is in a drop-pending state when 'system.drop' + // namespaces are supported. Since 4.2, dropped collections are managed internally by the + // storage engine. See serverStatus(). + if (supportsDropPendingNamespaces) { + assert.commandFailedWithCode( + dbToDrop.adminCommand('restartCatalog'), + ErrorCodes.DatabaseDropPending, + 'restartCatalog should fail if any databases are marked drop-pending'); + } else { + // Drop-pending idents are known only to the storage engine and will be ignored by + // restartCatalog. + assert.commandWorked(dbToDrop.adminCommand('restartCatalog')); + } /** * DROP DATABASE 'Database' PHASE diff --git a/jstests/replsets/initial_sync_update_missing_doc3.js b/jstests/replsets/initial_sync_update_missing_doc3.js index 27f06953b9a..4018d437cd5 100644 --- a/jstests/replsets/initial_sync_update_missing_doc3.js +++ b/jstests/replsets/initial_sync_update_missing_doc3.js @@ -15,6 +15,7 @@ (function() { load("jstests/libs/check_log.js"); + load("jstests/replsets/libs/two_phase_drops.js"); // For TwoPhaseDropCollectionTest. var name = 'initial_sync_update_missing_doc3'; var replSet = new ReplSetTest({ @@ -26,6 +27,13 @@ replSet.initiate(); var primary = replSet.getPrimary(); + // Check for 'system.drop' two phase drop support. + if (!TwoPhaseDropCollectionTest.supportsDropPendingNamespaces(replSet)) { + jsTestLog('Drop pending namespaces not supported by storage engine. Skipping test.'); + replSet.stopSet(); + return; + } + var coll = primary.getDB('test').getCollection(name); assert.writeOK(coll.insert({_id: 0, x: 1})); diff --git a/jstests/replsets/libs/two_phase_drops.js b/jstests/replsets/libs/two_phase_drops.js index 757bf71ac92..46b30cb9ed5 100644 --- a/jstests/replsets/libs/two_phase_drops.js +++ b/jstests/replsets/libs/two_phase_drops.js @@ -35,6 +35,27 @@ class TwoPhaseDropCollectionTest { jsTestLog("[TwoPhaseDropCollectionTest] " + msg); } + /** + * Returns true if the replica set supports two phase drops that use 'system.drop' namespaces. + * Since 4.2, 'system.drop' drop pending collections will be disabled on storage engines that + * support drop pending idents natively. See serverStatus().storageEngine.supportsPendingDrops. + */ + static supportsDropPendingNamespaces(replSetTest) { + const primaryDB = replSetTest.getPrimary().getDB('admin'); + const serverStatus = assert.commandWorked(primaryDB.serverStatus()); + const storageEngineSection = serverStatus.storageEngine; + TwoPhaseDropCollectionTest._testLog('Storage engine features (from serverStatus()): ' + + tojson(storageEngineSection)); + return !storageEngineSection.supportsPendingDrops; + } + + /** + * Instance method version of supportsDropPendingNamespaces(). + */ + supportsDropPendingNamespaces() { + return TwoPhaseDropCollectionTest.supportsDropPendingNamespaces(this.replTest); + } + /** * Pause oplog application on a specified node. */ -- cgit v1.2.1