mirror of
https://github.com/mongodb/mongo.git
synced 2024-12-01 09:32:32 +01:00
SERVER-44391 Preserve internal tables and temporary files when starting up after a clean shutdown
This commit is contained in:
parent
21075112a9
commit
08b190379b
@ -155,6 +155,7 @@
|
||||
#include "mongo/db/system_index.h"
|
||||
#include "mongo/db/transaction_participant.h"
|
||||
#include "mongo/db/ttl.h"
|
||||
#include "mongo/db/unclean_shutdown.h"
|
||||
#include "mongo/db/wire_version.h"
|
||||
#include "mongo/executor/network_connection_hook.h"
|
||||
#include "mongo/executor/network_interface_factory.h"
|
||||
@ -432,7 +433,9 @@ ExitCode _initAndListen(ServiceContext* serviceContext, int listenPort) {
|
||||
|
||||
startWatchdog(serviceContext);
|
||||
|
||||
if (!storageGlobalParams.readOnly) {
|
||||
// When starting up after an unclean shutdown, we do not attempt to use any of the temporary
|
||||
// files left from the previous run. Thus, we remove them in this case.
|
||||
if (!storageGlobalParams.readOnly && startingAfterUncleanShutdown(serviceContext)) {
|
||||
boost::filesystem::remove_all(storageGlobalParams.dbpath + "/_tmp/");
|
||||
}
|
||||
|
||||
@ -463,6 +466,14 @@ ExitCode _initAndListen(ServiceContext* serviceContext, int listenPort) {
|
||||
exitCleanly(EXIT_NEED_DOWNGRADE);
|
||||
}
|
||||
|
||||
// This flag is used during storage engine initialization to perform behavior that is specific
|
||||
// to recovering from an unclean shutdown. It is also used to determine whether temporary files
|
||||
// should be removed. The last of these uses is done by repairDatabasesAndCheckVersion() above,
|
||||
// so we reset the flag to false here. We reset the flag so that other users of these functions
|
||||
// outside of startup do not perform behavior that is specific to starting up after an unclean
|
||||
// shutdown.
|
||||
startingAfterUncleanShutdown(serviceContext) = false;
|
||||
|
||||
auto replProcess = repl::ReplicationProcess::get(serviceContext);
|
||||
invariant(replProcess);
|
||||
const bool initialSyncFlag =
|
||||
|
@ -136,6 +136,9 @@ TEST_F(StorageEngineTest, ReconcileDropsTemporary) {
|
||||
|
||||
ASSERT(identExists(opCtx.get(), ident));
|
||||
|
||||
// Reconcile will only drop temporary idents when starting up after an unclean shutdown.
|
||||
startingAfterUncleanShutdown(opCtx->getServiceContext()) = true;
|
||||
|
||||
auto reconcileResult = unittest::assertGet(reconcile(opCtx.get()));
|
||||
ASSERT_EQUALS(0UL, reconcileResult.indexesToRebuild.size());
|
||||
ASSERT_EQUALS(0UL, reconcileResult.indexBuildsToRestart.size());
|
||||
@ -146,6 +149,28 @@ TEST_F(StorageEngineTest, ReconcileDropsTemporary) {
|
||||
rs->finalizeTemporaryTable(opCtx.get(), TemporaryRecordStore::FinalizationAction::kDelete);
|
||||
}
|
||||
|
||||
TEST_F(StorageEngineTest, ReconcileKeepsTemporary) {
|
||||
auto opCtx = cc().makeOperationContext();
|
||||
|
||||
Lock::GlobalLock lk(&*opCtx, MODE_IS);
|
||||
|
||||
auto rs = makeTemporary(opCtx.get());
|
||||
ASSERT(rs.get());
|
||||
const std::string ident = rs->rs()->getIdent();
|
||||
|
||||
ASSERT(identExists(opCtx.get(), ident));
|
||||
|
||||
auto reconcileResult = unittest::assertGet(reconcile(opCtx.get()));
|
||||
ASSERT_EQUALS(0UL, reconcileResult.indexesToRebuild.size());
|
||||
ASSERT_EQUALS(0UL, reconcileResult.indexBuildsToRestart.size());
|
||||
|
||||
// The storage engine does not drop its temporary idents outside of starting up after an
|
||||
// unclean shutdown.
|
||||
ASSERT(identExists(opCtx.get(), ident));
|
||||
|
||||
rs->finalizeTemporaryTable(opCtx.get(), TemporaryRecordStore::FinalizationAction::kDelete);
|
||||
}
|
||||
|
||||
TEST_F(StorageEngineTest, TemporaryDropsItself) {
|
||||
auto opCtx = cc().makeOperationContext();
|
||||
|
||||
|
@ -243,10 +243,6 @@ void StorageEngineImpl::loadCatalog(OperationContext* opCtx) {
|
||||
|
||||
KVPrefix::setLargestPrefix(maxSeenPrefix);
|
||||
opCtx->recoveryUnit()->abandonSnapshot();
|
||||
|
||||
// Unset the unclean shutdown flag to avoid executing special behavior if this method is called
|
||||
// after startup.
|
||||
startingAfterUncleanShutdown(getGlobalServiceContext()) = false;
|
||||
}
|
||||
|
||||
void StorageEngineImpl::_initCollection(OperationContext* opCtx,
|
||||
@ -375,9 +371,10 @@ StatusWith<StorageEngine::ReconcileResult> StorageEngineImpl::reconcileCatalogAn
|
||||
continue;
|
||||
}
|
||||
|
||||
// Internal idents are dropped at the end after those left over from index builds are
|
||||
// identified.
|
||||
if (_catalog->isInternalIdent(it)) {
|
||||
// When starting up after an unclean shutdown, we do not attempt to recover any state from
|
||||
// the internal idents. Thus, we drop them in this case.
|
||||
if (startingAfterUncleanShutdown(opCtx->getServiceContext()) &&
|
||||
_catalog->isInternalIdent(it)) {
|
||||
internalIdentsToDrop.insert(it);
|
||||
continue;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user