summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGregory Wlodarek <gregory.wlodarek@mongodb.com>2020-01-13 15:43:49 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2020-02-25 22:26:41 +0000
commit8cbd99de29d6c610dec8540f4ddbda36fc9990e3 (patch)
treea70d98e4f549da0b00d324ed79059be73dd70ad0
parent85931b81d116cdcbb845075cb915001c96ffa251 (diff)
downloadmongo-8cbd99de29d6c610dec8540f4ddbda36fc9990e3.tar.gz
SERVER-44406 Add $backupCursor API to forcefully disable incremental backups
(cherry picked from commit 936b4dbc75574b090970db2d43baf397e569865f)
-rw-r--r--src/mongo/db/catalog/catalog_control_test.cpp8
-rw-r--r--src/mongo/db/pipeline/mongo_process_interface.h5
-rw-r--r--src/mongo/db/pipeline/mongos_process_interface.h4
-rw-r--r--src/mongo/db/pipeline/process_interface_standalone.cpp10
-rw-r--r--src/mongo/db/pipeline/process_interface_standalone.h5
-rw-r--r--src/mongo/db/pipeline/stub_mongo_process_interface.h4
-rw-r--r--src/mongo/db/storage/backup_cursor_hooks.cpp4
-rw-r--r--src/mongo/db/storage/backup_cursor_hooks.h11
-rw-r--r--src/mongo/db/storage/kv/kv_engine.h4
-rw-r--r--src/mongo/db/storage/storage_engine.h8
-rw-r--r--src/mongo/db/storage/storage_engine_impl.cpp4
-rw-r--r--src/mongo/db/storage/storage_engine_impl.h2
-rw-r--r--src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.cpp21
-rw-r--r--src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.h2
14 files changed, 64 insertions, 28 deletions
diff --git a/src/mongo/db/catalog/catalog_control_test.cpp b/src/mongo/db/catalog/catalog_control_test.cpp
index 58e345ac8a3..2c25e41b047 100644
--- a/src/mongo/db/catalog/catalog_control_test.cpp
+++ b/src/mongo/db/catalog/catalog_control_test.cpp
@@ -74,18 +74,22 @@ public:
"The current storage engine doesn't support backup mode");
}
void endBackup(OperationContext* opCtx) final {}
+ Status disableIncrementalBackup(OperationContext* opCtx) {
+ return Status(ErrorCodes::CommandNotSupported,
+ "The current storage engine doesn't support backup mode");
+ }
StatusWith<std::vector<StorageEngine::BackupBlock>> beginNonBlockingBackup(
OperationContext* opCtx,
bool incrementalBackup,
boost::optional<std::string> thisBackupName,
boost::optional<std::string> srcBackupName) final {
return Status(ErrorCodes::CommandNotSupported,
- "The current storage engine does not support a concurrent mode.");
+ "The current storage engine doesn't support backup mode");
}
void endNonBlockingBackup(OperationContext* opCtx) final {}
StatusWith<std::vector<std::string>> extendBackupCursor(OperationContext* opCtx) final {
return Status(ErrorCodes::CommandNotSupported,
- "The current storage engine does not support a concurrent mode.");
+ "The current storage engine doesn't support backup mode");
}
Status repairRecordStore(OperationContext* opCtx, const NamespaceString& ns) final {
return Status::OK();
diff --git a/src/mongo/db/pipeline/mongo_process_interface.h b/src/mongo/db/pipeline/mongo_process_interface.h
index 1b2a091b79b..4d2a6062bc8 100644
--- a/src/mongo/db/pipeline/mongo_process_interface.h
+++ b/src/mongo/db/pipeline/mongo_process_interface.h
@@ -51,6 +51,7 @@
#include "mongo/db/query/explain_options.h"
#include "mongo/db/repl/oplog_entry.h"
#include "mongo/db/resource_yielder.h"
+#include "mongo/db/storage/backup_cursor_hooks.h"
#include "mongo/db/storage/backup_cursor_state.h"
#include "mongo/s/chunk_version.h"
@@ -351,9 +352,7 @@ public:
* The following methods forward to the BackupCursorHooks decorating the ServiceContext.
*/
virtual BackupCursorState openBackupCursor(OperationContext* opCtx,
- bool incrementalBackup,
- boost::optional<std::string> thisBackupName,
- boost::optional<std::string> srcBackupName) = 0;
+ const BackupOptions& options) = 0;
virtual void closeBackupCursor(OperationContext* opCtx, const UUID& backupId) = 0;
diff --git a/src/mongo/db/pipeline/mongos_process_interface.h b/src/mongo/db/pipeline/mongos_process_interface.h
index 75f0f2ab1ab..6cfe9067494 100644
--- a/src/mongo/db/pipeline/mongos_process_interface.h
+++ b/src/mongo/db/pipeline/mongos_process_interface.h
@@ -191,9 +191,7 @@ public:
* a mongos.
*/
BackupCursorState openBackupCursor(OperationContext* opCtx,
- bool incrementalBackup,
- boost::optional<std::string> thisBackupName,
- boost::optional<std::string> srcBackupName) final {
+ const BackupOptions& options) final {
MONGO_UNREACHABLE;
}
diff --git a/src/mongo/db/pipeline/process_interface_standalone.cpp b/src/mongo/db/pipeline/process_interface_standalone.cpp
index 66671287ce4..8e60bbe57de 100644
--- a/src/mongo/db/pipeline/process_interface_standalone.cpp
+++ b/src/mongo/db/pipeline/process_interface_standalone.cpp
@@ -496,15 +496,11 @@ boost::optional<Document> MongoInterfaceStandalone::lookupSingleDocument(
return lookedUpDocument;
}
-BackupCursorState MongoInterfaceStandalone::openBackupCursor(
- OperationContext* opCtx,
- bool incrementalBackup,
- boost::optional<std::string> thisBackupName,
- boost::optional<std::string> srcBackupName) {
+BackupCursorState MongoInterfaceStandalone::openBackupCursor(OperationContext* opCtx,
+ const BackupOptions& options) {
auto backupCursorHooks = BackupCursorHooks::get(opCtx->getServiceContext());
if (backupCursorHooks->enabled()) {
- return backupCursorHooks->openBackupCursor(
- opCtx, incrementalBackup, thisBackupName, srcBackupName);
+ return backupCursorHooks->openBackupCursor(opCtx, options);
} else {
uasserted(50956, "Backup cursors are an enterprise only feature.");
}
diff --git a/src/mongo/db/pipeline/process_interface_standalone.h b/src/mongo/db/pipeline/process_interface_standalone.h
index dbfb7261f1f..f25650cc247 100644
--- a/src/mongo/db/pipeline/process_interface_standalone.h
+++ b/src/mongo/db/pipeline/process_interface_standalone.h
@@ -125,10 +125,7 @@ public:
bool allowSpeculativeMajorityRead = false) final;
std::vector<GenericCursor> getIdleCursors(const boost::intrusive_ptr<ExpressionContext>& expCtx,
CurrentOpUserMode userMode) const final;
- BackupCursorState openBackupCursor(OperationContext* opCtx,
- bool incrementalBackup,
- boost::optional<std::string> thisBackupName,
- boost::optional<std::string> srcBackupName) final;
+ BackupCursorState openBackupCursor(OperationContext* opCtx, const BackupOptions& options) final;
void closeBackupCursor(OperationContext* opCtx, const UUID& backupId) final;
BackupCursorExtendState extendBackupCursor(OperationContext* opCtx,
const UUID& backupId,
diff --git a/src/mongo/db/pipeline/stub_mongo_process_interface.h b/src/mongo/db/pipeline/stub_mongo_process_interface.h
index b2bf93560dd..389524d1151 100644
--- a/src/mongo/db/pipeline/stub_mongo_process_interface.h
+++ b/src/mongo/db/pipeline/stub_mongo_process_interface.h
@@ -183,9 +183,7 @@ public:
}
BackupCursorState openBackupCursor(OperationContext* opCtx,
- bool incrementalBackup,
- boost::optional<std::string> thisBackupName,
- boost::optional<std::string> srcBackupName) final {
+ const BackupOptions& options) final {
return BackupCursorState{UUID::gen(), boost::none, {}};
}
diff --git a/src/mongo/db/storage/backup_cursor_hooks.cpp b/src/mongo/db/storage/backup_cursor_hooks.cpp
index 0c86bec06f1..6f5bd8ee830 100644
--- a/src/mongo/db/storage/backup_cursor_hooks.cpp
+++ b/src/mongo/db/storage/backup_cursor_hooks.cpp
@@ -78,9 +78,7 @@ void BackupCursorHooks::fsyncUnlock(OperationContext* opCtx) {
}
BackupCursorState BackupCursorHooks::openBackupCursor(OperationContext* opCtx,
- bool incrementalBackup,
- boost::optional<std::string> thisBackupName,
- boost::optional<std::string> srcBackupName) {
+ const BackupOptions& options) {
MONGO_UNREACHABLE;
}
diff --git a/src/mongo/db/storage/backup_cursor_hooks.h b/src/mongo/db/storage/backup_cursor_hooks.h
index c78110a3e90..ef40a9a23b9 100644
--- a/src/mongo/db/storage/backup_cursor_hooks.h
+++ b/src/mongo/db/storage/backup_cursor_hooks.h
@@ -39,6 +39,13 @@ class OperationContext;
class ServiceContext;
class StorageEngine;
+struct BackupOptions {
+ bool disableIncrementalBackup = false;
+ bool incrementalBackup = false;
+ boost::optional<std::string> thisBackupName;
+ boost::optional<std::string> srcBackupName;
+};
+
class BackupCursorHooks {
public:
using InitializerFunction = std::function<std::unique_ptr<BackupCursorHooks>(StorageEngine*)>;
@@ -62,9 +69,7 @@ public:
virtual void fsyncUnlock(OperationContext* opCtx);
virtual BackupCursorState openBackupCursor(OperationContext* opCtx,
- bool incrementalBackup,
- boost::optional<std::string> thisBackupName,
- boost::optional<std::string> srcBackupName);
+ const BackupOptions& options);
virtual void closeBackupCursor(OperationContext* opCtx, const UUID& backupId);
diff --git a/src/mongo/db/storage/kv/kv_engine.h b/src/mongo/db/storage/kv/kv_engine.h
index 16513516b7e..abce2f51311 100644
--- a/src/mongo/db/storage/kv/kv_engine.h
+++ b/src/mongo/db/storage/kv/kv_engine.h
@@ -223,6 +223,10 @@ public:
MONGO_UNREACHABLE;
}
+ virtual Status disableIncrementalBackup(OperationContext* opCtx) {
+ MONGO_UNREACHABLE;
+ }
+
virtual StatusWith<std::vector<StorageEngine::BackupBlock>> beginNonBlockingBackup(
OperationContext* opCtx,
bool incrementalBackup,
diff --git a/src/mongo/db/storage/storage_engine.h b/src/mongo/db/storage/storage_engine.h
index e1429a91f09..01ea4aaa5e5 100644
--- a/src/mongo/db/storage/storage_engine.h
+++ b/src/mongo/db/storage/storage_engine.h
@@ -274,6 +274,14 @@ public:
}
/**
+ * Disables the storage of incremental backup history until a subsequent incremental backup
+ * cursor is requested.
+ *
+ * The storage engine must release all incremental backup information and resources.
+ */
+ virtual Status disableIncrementalBackup(OperationContext* opCtx) = 0;
+
+ /**
* When performing an incremental backup, we first need a basis for future incremental backups.
* The basis will be a full backup called 'thisBackupName'. For future incremental backups, the
* storage engine will take a backup called 'thisBackupName' which will contain the changes made
diff --git a/src/mongo/db/storage/storage_engine_impl.cpp b/src/mongo/db/storage/storage_engine_impl.cpp
index 1035ced7874..0ec1f6f3392 100644
--- a/src/mongo/db/storage/storage_engine_impl.cpp
+++ b/src/mongo/db/storage/storage_engine_impl.cpp
@@ -647,6 +647,10 @@ void StorageEngineImpl::endBackup(OperationContext* opCtx) {
_inBackupMode = false;
}
+Status StorageEngineImpl::disableIncrementalBackup(OperationContext* opCtx) {
+ return _engine->disableIncrementalBackup(opCtx);
+}
+
StatusWith<std::vector<StorageEngine::BackupBlock>> StorageEngineImpl::beginNonBlockingBackup(
OperationContext* opCtx,
bool incrementalBackup,
diff --git a/src/mongo/db/storage/storage_engine_impl.h b/src/mongo/db/storage/storage_engine_impl.h
index 4b99211c55d..53a807ae04c 100644
--- a/src/mongo/db/storage/storage_engine_impl.h
+++ b/src/mongo/db/storage/storage_engine_impl.h
@@ -97,6 +97,8 @@ public:
virtual void endBackup(OperationContext* opCtx);
+ virtual Status disableIncrementalBackup(OperationContext* opCtx) override;
+
virtual StatusWith<std::vector<BackupBlock>> beginNonBlockingBackup(
OperationContext* opCtx,
bool incrementalBackup,
diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.cpp b/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.cpp
index 3d90af240b4..e08cd46dca9 100644
--- a/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.cpp
+++ b/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.cpp
@@ -1046,6 +1046,27 @@ void WiredTigerKVEngine::endBackup(OperationContext* opCtx) {
_backupSession.reset();
}
+Status WiredTigerKVEngine::disableIncrementalBackup(OperationContext* opCtx) {
+ // Opening an incremental backup cursor with the "force_stop=true" configuration option then
+ // closing the cursor will set a flag in WiredTiger that causes it to release all incremental
+ // information and resources.
+ // Opening a subsequent incremental backup cursor will reset the flag in WiredTiger and
+ // reinstate incremental backup history.
+ uassert(31401, "Cannot open backup cursor with in-memory storage engine.", !isEphemeral());
+
+ auto sessionRaii = std::make_unique<WiredTigerSession>(_conn);
+ WT_CURSOR* cursor = nullptr;
+ WT_SESSION* session = sessionRaii->getSession();
+ int wtRet =
+ session->open_cursor(session, "backup:", nullptr, "incremental=(force_stop=true)", &cursor);
+ if (wtRet != 0) {
+ error() << "Could not open a backup cursor to disable incremental backups";
+ return wtRCToStatus(wtRet);
+ }
+
+ return Status::OK();
+}
+
StatusWith<std::vector<StorageEngine::BackupBlock>> WiredTigerKVEngine::beginNonBlockingBackup(
OperationContext* opCtx,
bool incrementalBackup,
diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.h b/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.h
index 9c40d5874b5..81a1cead276 100644
--- a/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.h
+++ b/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.h
@@ -174,6 +174,8 @@ public:
void endBackup(OperationContext* opCtx) override;
+ Status disableIncrementalBackup(OperationContext* opCtx) override;
+
StatusWith<std::vector<StorageEngine::BackupBlock>> beginNonBlockingBackup(
OperationContext* opCtx,
bool incrementalBackup,