SERVER-106596 Truncate spill table before drop (#37726)

GitOrigin-RevId: 5ee91802f8f84257f606817dd76cfaa18c894662
This commit is contained in:
Gregory Noma 2025-07-23 13:11:30 -04:00 committed by MongoDB Bot
parent 9e6366f4b7
commit 0288d3d9f0
4 changed files with 31 additions and 7 deletions

View File

@ -208,10 +208,12 @@ protected:
return ret;
}
std::unique_ptr<SpillTable> makeSpillTable(OperationContext* opCtx) {
std::unique_ptr<RecordStore> makeSpillTable(OperationContext* opCtx) {
Lock::GlobalLock lk{opCtx, MODE_IS};
auto spillTable = StorageEngineTest::makeSpillTable(opCtx, KeyFormat::Long, 1024);
ASSERT_TRUE(spillIdentExists(opCtx, spillTable->ident()));
auto spillEngine = opCtx->getServiceContext()->getStorageEngine()->getSpillEngine();
auto spillTable = spillEngine->makeTemporaryRecordStore(
*spillEngine->newRecoveryUnit(), ident::generateNewInternalIdent(), KeyFormat::Long);
ASSERT_TRUE(spillIdentExists(opCtx, spillTable->getIdent()));
return spillTable;
}
@ -345,7 +347,7 @@ TEST_F(StorageEngineReconcileTest, StartupRecoveryForUncleanShutdown) {
ASSERT_FALSE(identExists(opCtx.get(), irrelevantRs->rs()->getIdent()));
ASSERT_FALSE(identExists(opCtx.get(), resumableIndexRs->rs()->getIdent()));
ASSERT_FALSE(identExists(opCtx.get(), necessaryRs->rs()->getIdent()));
ASSERT_FALSE(spillIdentExists(opCtx.get(), spillTable->ident()));
ASSERT_FALSE(spillIdentExists(opCtx.get(), spillTable->getIdent()));
}
// Abort the two-phase index build since it hangs in vote submission, because we are not running

View File

@ -546,6 +546,9 @@ public:
/**
* Removes all Records.
*
* The operation context parameter is optional and, if non-null, will only be used to check the
* "read-only" flag.
*/
virtual Status truncate(OperationContext*, RecoveryUnit&) = 0;
@ -556,6 +559,9 @@ public:
* order to update numRecords and dataSize correctly. Implementations are free to ignore the
* hints if they have a way of obtaining the correct values without the help of external
* callers.
*
* The operation context parameter is optional and, if non-null, will only be used to check the
* "read-only" flag.
*/
virtual Status rangeTruncate(OperationContext*,
RecoveryUnit&,

View File

@ -38,7 +38,7 @@ namespace {
void validateWriteAllowed(OperationContext* opCtx) {
uassert(ErrorCodes::IllegalOperation,
"Cannot execute a write operation in read-only mode",
!opCtx->readOnly());
!opCtx || !opCtx->readOnly());
}
} // namespace

View File

@ -118,9 +118,25 @@ SpillTable::SpillTable(std::unique_ptr<RecoveryUnit> ru,
}
SpillTable::~SpillTable() {
if (_storageEngine) {
_storageEngine->dropSpillTable(*_ru, ident());
if (!_storageEngine) {
return;
}
// As an optimization, truncate the table before dropping it so that the checkpoint taken at
// shutdown never has to do the work to write the data to disk.
try {
_ru->setIsolation(RecoveryUnit::Isolation::snapshot);
StorageWriteTransaction txn{*_ru};
uassertStatusOK(_rs->truncate(nullptr, *_ru));
txn.commit();
} catch (...) {
LOGV2(10659600,
"Failed to truncate spill table, ignoring and continuing to drop",
"ident"_attr = ident(),
"error"_attr = exceptionToStatus());
}
_storageEngine->dropSpillTable(*_ru, ident());
}
StringData SpillTable::ident() const {