diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/mongo/db/catalog/collection.cpp | 45 | ||||
-rw-r--r-- | src/mongo/db/catalog/index_catalog.cpp | 5 | ||||
-rw-r--r-- | src/mongo/db/index/btree_based_bulk_access_method.cpp | 4 | ||||
-rw-r--r-- | src/mongo/db/storage/mmap_v1/dur_transaction.cpp | 4 | ||||
-rw-r--r-- | src/mongo/db/storage/mmap_v1/dur_transaction.h | 2 | ||||
-rw-r--r-- | src/mongo/db/storage/transaction.h | 19 | ||||
-rw-r--r-- | src/mongo/db/structure/btree/btree_logic.cpp | 8 | ||||
-rw-r--r-- | src/mongo/db/structure/catalog/namespace_details_rsv1_metadata.h | 27 | ||||
-rw-r--r-- | src/mongo/db/structure/collection_compact.cpp | 4 | ||||
-rw-r--r-- | src/mongo/db/structure/record_store.h | 19 | ||||
-rw-r--r-- | src/mongo/db/structure/record_store_v1_base.cpp | 75 | ||||
-rw-r--r-- | src/mongo/db/structure/record_store_v1_base.h | 49 | ||||
-rw-r--r-- | src/mongo/db/structure/record_store_v1_capped.cpp | 163 | ||||
-rw-r--r-- | src/mongo/db/structure/record_store_v1_capped.h | 37 | ||||
-rw-r--r-- | src/mongo/db/structure/record_store_v1_simple.cpp | 83 | ||||
-rw-r--r-- | src/mongo/db/structure/record_store_v1_simple.h | 22 | ||||
-rw-r--r-- | src/mongo/dbtests/namespacetests.cpp | 19 |
17 files changed, 352 insertions, 233 deletions
diff --git a/src/mongo/db/catalog/collection.cpp b/src/mongo/db/catalog/collection.cpp index 2e6ce4f8b77..8d40633297c 100644 --- a/src/mongo/db/catalog/collection.cpp +++ b/src/mongo/db/catalog/collection.cpp @@ -47,6 +47,7 @@ #include "mongo/db/repl/rs.h" #include "mongo/db/storage/extent.h" #include "mongo/db/storage/extent_manager.h" +#include "mongo/db/storage/mmap_v1/dur_transaction.h" #include "mongo/db/auth/user_document_parser.h" // XXX-ANDY @@ -80,18 +81,22 @@ namespace mongo { _infoCache( this ), _indexCatalog( this, details ), _cursorCache( fullNS ) { + DurTransaction txn[1]; + _details = details; _database = database; if ( details->isCapped() ) { - _recordStore.reset( new CappedRecordStoreV1( this, + _recordStore.reset( new CappedRecordStoreV1( txn, + this, _ns.ns(), new NamespaceDetailsRSV1MetaData( details ), &database->getExtentManager(), _ns.coll() == "system.indexes" ) ); } else { - _recordStore.reset( new SimpleRecordStoreV1( _ns.ns(), + _recordStore.reset( new SimpleRecordStoreV1( txn, + _ns.ns(), new NamespaceDetailsRSV1MetaData( details ), &database->getExtentManager(), _ns.coll() == "system.indexes" ) ); @@ -163,10 +168,14 @@ namespace mongo { } StatusWith<DiskLoc> Collection::insertDocument( const DocWriter* doc, bool enforceQuota ) { + DurTransaction txn[1]; verify( _indexCatalog.numIndexesTotal() == 0 ); // eventually can implement, just not done - StatusWith<DiskLoc> loc = _recordStore->insertRecord( doc, - enforceQuota ? largestFileNumberInQuota() : 0 ); + StatusWith<DiskLoc> loc = _recordStore->insertRecord( txn, + doc, + enforceQuota + ? largestFileNumberInQuota() + : 0 ); if ( !loc.isOK() ) return loc; @@ -199,7 +208,9 @@ namespace mongo { StatusWith<DiskLoc> Collection::insertDocument( const BSONObj& doc, MultiIndexBlock& indexBlock ) { - StatusWith<DiskLoc> loc = _recordStore->insertRecord( doc.objdata(), + DurTransaction txn[1]; + StatusWith<DiskLoc> loc = _recordStore->insertRecord( txn, + doc.objdata(), doc.objsize(), 0 ); @@ -225,7 +236,9 @@ namespace mongo { // under the RecordStore, this feels broken since that should be a // collection access method probably - StatusWith<DiskLoc> loc = _recordStore->insertRecord( docToInsert.objdata(), + DurTransaction txn[1]; + StatusWith<DiskLoc> loc = _recordStore->insertRecord( txn, + docToInsert.objdata(), docToInsert.objsize(), enforceQuota ? largestFileNumberInQuota() : 0 ); if ( !loc.isOK() ) @@ -246,7 +259,7 @@ namespace mongo { // indexRecord takes care of rolling back indexes // so we just have to delete the main storage - _recordStore->deleteRecord( loc.getValue() ); + _recordStore->deleteRecord( txn, loc.getValue() ); return StatusWith<DiskLoc>( e.toStatus( "insertDocument" ) ); } @@ -255,6 +268,7 @@ namespace mongo { void Collection::deleteDocument( const DiskLoc& loc, bool cappedOK, bool noWarn, BSONObj* deletedId ) { + DurTransaction txn[1]; if ( _details->isCapped() && !cappedOK ) { log() << "failing remove on a capped ns " << _ns << endl; uasserted( 10089, "cannot remove from a capped collection" ); @@ -275,7 +289,7 @@ namespace mongo { _indexCatalog.unindexRecord( doc, loc, noWarn); - _recordStore->deleteRecord( loc ); + _recordStore->deleteRecord( txn, loc ); _infoCache.notifyOfWriteOp(); } @@ -287,6 +301,7 @@ namespace mongo { const BSONObj& objNew, bool enforceQuota, OpDebug* debug ) { + DurTransaction txn[1]; Record* oldRecord = _recordStore->recordFor( oldLocation ); BSONObj objOld( oldRecord->accessed()->data() ); @@ -358,7 +373,7 @@ namespace mongo { if ( loc.isOK() ) { // insert successful, now lets deallocate the old location // remember its already unindexed - _recordStore->deleteRecord( oldLocation ); + _recordStore->deleteRecord( txn, oldLocation ); } else { // new doc insert failed, so lets re-index the old document and location @@ -392,7 +407,7 @@ namespace mongo { // update in place int sz = objNew.objsize(); - memcpy(getDur().writingPtr(oldRecord->data(), sz), objNew.objdata(), sz); + memcpy(txn->writingPtr(oldRecord->data(), sz), objNew.objdata(), sz); return StatusWith<DiskLoc>( oldLocation ); } @@ -460,7 +475,8 @@ namespace mongo { } void Collection::increaseStorageSize( int size, bool enforceQuota ) { - _recordStore->increaseStorageSize( size, enforceQuota ? largestFileNumberInQuota() : 0 ); + DurTransaction txn[1]; + _recordStore->increaseStorageSize(txn, size, enforceQuota ? largestFileNumberInQuota() : 0); } int Collection::largestFileNumberInQuota() const { @@ -496,6 +512,7 @@ namespace mongo { * 4) re-write indexes */ Status Collection::truncate() { + DurTransaction txn[1]; massert( 17445, "index build in progress", _indexCatalog.numIndexesInProgress() == 0 ); // 1) store index specs @@ -516,7 +533,7 @@ namespace mongo { _infoCache.reset(); // 3) truncate record store - status = _recordStore->truncate(); + status = _recordStore->truncate(txn); if ( !status.isOK() ) return status; @@ -531,8 +548,10 @@ namespace mongo { } void Collection::temp_cappedTruncateAfter( DiskLoc end, bool inclusive) { + DurTransaction txn[1]; invariant( isCapped() ); - reinterpret_cast<CappedRecordStoreV1*>(_recordStore.get())->temp_cappedTruncateAfter( end, inclusive ); + reinterpret_cast<CappedRecordStoreV1*>( + _recordStore.get())->temp_cappedTruncateAfter( txn, end, inclusive ); } namespace { diff --git a/src/mongo/db/catalog/index_catalog.cpp b/src/mongo/db/catalog/index_catalog.cpp index f1c09a07d1e..2c907eb735d 100644 --- a/src/mongo/db/catalog/index_catalog.cpp +++ b/src/mongo/db/catalog/index_catalog.cpp @@ -61,6 +61,7 @@ #include "mongo/db/repl/rs.h" // this is ugly #include "mongo/db/storage/data_file.h" #include "mongo/db/storage/extent_manager.h" +#include "mongo/db/storage/mmap_v1/dur_transaction.h" #include "mongo/db/structure/catalog/namespace_details.h" #include "mongo/db/structure/catalog/namespace_details_rsv1_metadata.h" #include "mongo/db/structure/record_store_v1_simple.h" @@ -125,6 +126,7 @@ namespace mongo { } IndexCatalogEntry* IndexCatalog::_setupInMemoryStructures( IndexDescriptor* descriptor ) { + DurTransaction txn[1]; auto_ptr<IndexDescriptor> descriptorCleanup( descriptor ); NamespaceDetails* indexMetadata = @@ -134,7 +136,8 @@ namespace mongo { str::stream() << "no NamespaceDetails for index: " << descriptor->toString(), indexMetadata ); - auto_ptr<RecordStore> recordStore( new SimpleRecordStoreV1( descriptor->indexNamespace(), + auto_ptr<RecordStore> recordStore( new SimpleRecordStoreV1( txn, + descriptor->indexNamespace(), new NamespaceDetailsRSV1MetaData( indexMetadata ), _collection->getExtentManager(), false ) ); diff --git a/src/mongo/db/index/btree_based_bulk_access_method.cpp b/src/mongo/db/index/btree_based_bulk_access_method.cpp index bae9d245e92..2725a967c19 100644 --- a/src/mongo/db/index/btree_based_bulk_access_method.cpp +++ b/src/mongo/db/index/btree_based_bulk_access_method.cpp @@ -31,6 +31,7 @@ #include "mongo/db/kill_current_op.h" #include "mongo/db/pdfile_private.h" // This is for inDBRepair. #include "mongo/db/repl/rs.h" // This is for ignoreUniqueIndex. +#include "mongo/db/storage/mmap_v1/dur_transaction.h" #include "mongo/util/progress_meter.h" namespace mongo { @@ -131,11 +132,12 @@ namespace mongo { } Status BtreeBasedBulkAccessMethod::commit(set<DiskLoc>* dupsToDrop, CurOp* op, bool mayInterrupt) { + DurTransaction txn[1]; DiskLoc oldHead = _real->_btreeState->head(); // XXX: do we expect the tree to be empty but have a head set? Looks like so from old code. invariant(!oldHead.isNull()); _real->_btreeState->setHead(DiskLoc()); - _real->_btreeState->recordStore()->deleteRecord(oldHead); + _real->_btreeState->recordStore()->deleteRecord(txn, oldHead); if (_isMultiKey) { _real->_btreeState->setMultikey(); diff --git a/src/mongo/db/storage/mmap_v1/dur_transaction.cpp b/src/mongo/db/storage/mmap_v1/dur_transaction.cpp index 17a50a7dc6b..2e416bd9708 100644 --- a/src/mongo/db/storage/mmap_v1/dur_transaction.cpp +++ b/src/mongo/db/storage/mmap_v1/dur_transaction.cpp @@ -40,8 +40,8 @@ namespace mongo { return getDur().isCommitNeeded(); } - void DurTransaction::writingPtr(void* data, size_t len) { - getDur().writingPtr(data, len); + void* DurTransaction::writingPtr(void* data, size_t len) { + return getDur().writingPtr(data, len); } } // namespace mongo diff --git a/src/mongo/db/storage/mmap_v1/dur_transaction.h b/src/mongo/db/storage/mmap_v1/dur_transaction.h index c9cbf207969..55412e83bb6 100644 --- a/src/mongo/db/storage/mmap_v1/dur_transaction.h +++ b/src/mongo/db/storage/mmap_v1/dur_transaction.h @@ -45,7 +45,7 @@ namespace mongo { virtual bool isCommitNeeded() const; - virtual void writingPtr(void* data, size_t len); + virtual void* writingPtr(void* data, size_t len); }; } // namespace mongo diff --git a/src/mongo/db/storage/transaction.h b/src/mongo/db/storage/transaction.h index 5cfff966c67..2799ae2df09 100644 --- a/src/mongo/db/storage/transaction.h +++ b/src/mongo/db/storage/transaction.h @@ -40,7 +40,6 @@ namespace mongo { class TransactionExperiment { MONGO_DISALLOW_COPYING(TransactionExperiment); public: - TransactionExperiment() { } virtual ~TransactionExperiment() { } /** @@ -55,17 +54,29 @@ namespace mongo { /** * Declare that the data at [x, x + len) is being written. - */ - virtual void writingPtr(void* data, size_t len) = 0; + */ + virtual void* writingPtr(void* data, size_t len) = 0; + + // + // Sugar methods + // + + /** + * Declare write intent for an int + */ + inline int& writingInt(int& d) { return *writing( &d ); } /** * A templated helper for writingPtr. */ template <typename T> inline T* writing(T* x) { - writingPtr(static_cast<void*>(x), sizeof(T)); + writingPtr(x, sizeof(T)); return x; } + + protected: + TransactionExperiment() {} }; } // namespace mongo diff --git a/src/mongo/db/structure/btree/btree_logic.cpp b/src/mongo/db/structure/btree/btree_logic.cpp index 213f5cb66b4..c06016dd74a 100644 --- a/src/mongo/db/structure/btree/btree_logic.cpp +++ b/src/mongo/db/structure/btree/btree_logic.cpp @@ -31,6 +31,9 @@ #include "mongo/db/index/btree_index_cursor.h" // for aboutToDeleteBucket #include "mongo/db/jsobj.h" #include "mongo/db/kill_current_op.h" +#include "mongo/db/storage/mmap_v1/dur.h" +#include "mongo/db/storage/mmap_v1/dur_commitjob.h" +#include "mongo/db/storage/mmap_v1/dur_transaction.h" #include "mongo/db/storage/record.h" #include "mongo/db/storage/transaction.h" #include "mongo/db/structure/btree/btree_logic.h" @@ -1274,9 +1277,10 @@ namespace mongo { template <class BtreeLayout> void BtreeLogic<BtreeLayout>::deallocBucket(BucketType* bucket, const DiskLoc bucketLoc) { + DurTransaction txn[1]; bucket->n = BtreeLayout::INVALID_N_SENTINEL; bucket->parent.Null(); - _recordStore->deleteRecord(bucketLoc); + _recordStore->deleteRecord(txn, bucketLoc); } template <class BtreeLayout> @@ -2008,7 +2012,7 @@ namespace mongo { template <class BtreeLayout> DiskLoc BtreeLogic<BtreeLayout>::addBucket(TransactionExperiment* trans) { DummyDocWriter docWriter(BtreeLayout::BucketSize); - StatusWith<DiskLoc> loc = _recordStore->insertRecord(&docWriter, 0); + StatusWith<DiskLoc> loc = _recordStore->insertRecord(trans, &docWriter, 0); // XXX: remove this(?) or turn into massert or sanely bubble it back up. uassertStatusOK(loc.getStatus()); BucketType* b = btreemod(trans, getBucket(loc.getValue())); diff --git a/src/mongo/db/structure/catalog/namespace_details_rsv1_metadata.h b/src/mongo/db/structure/catalog/namespace_details_rsv1_metadata.h index bbd1c29ba14..dcb86f3f096 100644 --- a/src/mongo/db/structure/catalog/namespace_details_rsv1_metadata.h +++ b/src/mongo/db/structure/catalog/namespace_details_rsv1_metadata.h @@ -30,6 +30,7 @@ #pragma once +#include "mongo/db/structure/catalog/namespace_details.h" #include "mongo/db/structure/record_store_v1_base.h" namespace mongo { @@ -54,7 +55,7 @@ namespace mongo { return _details->capExtent(); } - virtual void setCapExtent( const DiskLoc& loc ) { + virtual void setCapExtent( TransactionExperiment* txn, const DiskLoc& loc ) { _details->setCapExtent( loc ); } @@ -62,7 +63,7 @@ namespace mongo { return _details->capFirstNewRecord(); } - virtual void setCapFirstNewRecord( const DiskLoc& loc ) { + virtual void setCapFirstNewRecord( TransactionExperiment* txn, const DiskLoc& loc ) { _details->setCapFirstNewRecord( loc ); } @@ -70,7 +71,7 @@ namespace mongo { return _details->capLooped(); } - virtual void clearSystemFlags() { + virtual void clearSystemFlags(TransactionExperiment* txn) { _details->clearSystemFlags(); } @@ -81,12 +82,14 @@ namespace mongo { return _details->numRecords(); } - virtual void incrementStats( long long dataSizeIncrement, + virtual void incrementStats( TransactionExperiment* txn, + long long dataSizeIncrement, long long numRecordsIncrement ) { _details->incrementStats( dataSizeIncrement, numRecordsIncrement ); } - virtual void setStats( long long dataSizeIncrement, + virtual void setStats( TransactionExperiment* txn, + long long dataSizeIncrement, long long numRecordsIncrement ) { _details->setStats( dataSizeIncrement, numRecordsIncrement ); @@ -96,11 +99,13 @@ namespace mongo { return _details->deletedListEntry( bucket ); } - virtual void setDeletedListEntry( int bucket, const DiskLoc& loc ) { + virtual void setDeletedListEntry( TransactionExperiment* txn, + int bucket, + const DiskLoc& loc ) { _details->setDeletedListEntry( bucket, loc ); } - virtual void orphanDeletedList() { + virtual void orphanDeletedList(TransactionExperiment* txn) { _details->orphanDeletedList(); } @@ -108,7 +113,7 @@ namespace mongo { return _details->firstExtent(); } - virtual void setFirstExtent( const DiskLoc& loc ) { + virtual void setFirstExtent( TransactionExperiment* txn, const DiskLoc& loc ) { _details->setFirstExtent( loc ); } @@ -116,7 +121,7 @@ namespace mongo { return _details->lastExtent(); } - virtual void setLastExtent( const DiskLoc& loc ) { + virtual void setLastExtent( TransactionExperiment* txn, const DiskLoc& loc ) { _details->setLastExtent( loc ); } @@ -132,7 +137,7 @@ namespace mongo { return _details->lastExtentSize(); } - virtual void setLastExtentSize( int newMax ) { + virtual void setLastExtentSize( TransactionExperiment* txn, int newMax ) { _details->setLastExtentSize( newMax ); } @@ -144,7 +149,7 @@ namespace mongo { return _details->paddingFactor(); } - virtual void setPaddingFactor( double paddingFactor ) { + virtual void setPaddingFactor( TransactionExperiment* txn, double paddingFactor ) { _details->setPaddingFactor( paddingFactor ); } diff --git a/src/mongo/db/structure/collection_compact.cpp b/src/mongo/db/structure/collection_compact.cpp index 92a0002567f..e1f20e272a3 100644 --- a/src/mongo/db/structure/collection_compact.cpp +++ b/src/mongo/db/structure/collection_compact.cpp @@ -43,6 +43,7 @@ #include "mongo/db/structure/catalog/namespace_details.h" #include "mongo/db/storage/extent.h" #include "mongo/db/storage/extent_manager.h" +#include "mongo/db/storage/mmap_v1/dur_transaction.h" #include "mongo/util/touch_pages.h" namespace mongo { @@ -101,6 +102,7 @@ namespace mongo { StatusWith<CompactStats> Collection::compact( const CompactOptions* compactOptions ) { + DurTransaction txn[1]; if ( !_recordStore->compactSupported() ) return StatusWith<CompactStats>( ErrorCodes::BadValue, @@ -155,7 +157,7 @@ namespace mongo { MyCompactAdaptor adaptor( this, &multiIndexBlock ); - _recordStore->compact( &adaptor, compactOptions, &stats ); + _recordStore->compact( txn, &adaptor, compactOptions, &stats ); log() << "starting index commits"; status = multiIndexBlock.commit(); diff --git a/src/mongo/db/structure/record_store.h b/src/mongo/db/structure/record_store.h index 41a1d3dd600..4aece12f0fa 100644 --- a/src/mongo/db/structure/record_store.h +++ b/src/mongo/db/structure/record_store.h @@ -44,6 +44,7 @@ namespace mongo { class MAdvise; class NamespaceDetails; class Record; + class TransactionExperiment; class RecordStoreCompactAdaptor; class RecordStore; @@ -100,11 +101,16 @@ namespace mongo { virtual Record* recordFor( const DiskLoc& loc ) const = 0; - virtual void deleteRecord( const DiskLoc& dl ) = 0; + virtual void deleteRecord( TransactionExperiment* txn, const DiskLoc& dl ) = 0; - virtual StatusWith<DiskLoc> insertRecord( const char* data, int len, int quotaMax ) = 0; + virtual StatusWith<DiskLoc> insertRecord( TransactionExperiment* txn, + const char* data, + int len, + int quotaMax ) = 0; - virtual StatusWith<DiskLoc> insertRecord( const DocWriter* doc, int quotaMax ) = 0; + virtual StatusWith<DiskLoc> insertRecord( TransactionExperiment* txn, + const DocWriter* doc, + int quotaMax ) = 0; /** * returned iterator owned by caller @@ -133,11 +139,12 @@ namespace mongo { /** * removes all Records */ - virtual Status truncate() = 0; + virtual Status truncate( TransactionExperiment* txn ) = 0; // does this RecordStore support the compact operation virtual bool compactSupported() const = 0; - virtual Status compact( RecordStoreCompactAdaptor* adaptor, + virtual Status compact( TransactionExperiment* txn, + RecordStoreCompactAdaptor* adaptor, const CompactOptions* options, CompactStats* stats ) = 0; @@ -154,7 +161,7 @@ namespace mongo { // TODO: this makes me sad, it shouldn't be in the interface // do not use this anymore - virtual void increaseStorageSize( int size, int quotaMax ) = 0; + virtual void increaseStorageSize( TransactionExperiment* txn, int size, int quotaMax ) = 0; // TODO: another sad one virtual const DeletedRecord* deletedRecordFor( const DiskLoc& loc ) const = 0; diff --git a/src/mongo/db/structure/record_store_v1_base.cpp b/src/mongo/db/structure/record_store_v1_base.cpp index 8ba91a349d1..d220d483195 100644 --- a/src/mongo/db/structure/record_store_v1_base.cpp +++ b/src/mongo/db/structure/record_store_v1_base.cpp @@ -31,11 +31,11 @@ #include "mongo/db/structure/record_store_v1_base.h" #include "mongo/db/catalog/collection.h" -#include "mongo/db/storage/mmap_v1/dur.h" #include "mongo/db/kill_current_op.h" #include "mongo/db/storage/extent.h" #include "mongo/db/storage/extent_manager.h" #include "mongo/db/storage/record.h" +#include "mongo/db/storage/transaction.h" #include "mongo/db/structure/catalog/namespace_details.h" #include "mongo/db/structure/record_store_v1_repair_iterator.h" @@ -138,34 +138,39 @@ namespace mongo { } - StatusWith<DiskLoc> RecordStoreV1Base::insertRecord( const DocWriter* doc, int quotaMax ) { + StatusWith<DiskLoc> RecordStoreV1Base::insertRecord( TransactionExperiment* txn, + const DocWriter* doc, + int quotaMax ) { int lenWHdr = doc->documentSize() + Record::HeaderSize; if ( doc->addPadding() ) lenWHdr = getRecordAllocationSize( lenWHdr ); - StatusWith<DiskLoc> loc = allocRecord( lenWHdr, quotaMax ); + StatusWith<DiskLoc> loc = allocRecord( txn, lenWHdr, quotaMax ); if ( !loc.isOK() ) return loc; Record *r = recordFor( loc.getValue() ); fassert( 17319, r->lengthWithHeaders() >= lenWHdr ); - r = reinterpret_cast<Record*>( getDur().writingPtr(r, lenWHdr) ); + r = reinterpret_cast<Record*>( txn->writingPtr(r, lenWHdr) ); doc->writeDocument( r->data() ); - _addRecordToRecListInExtent(r, loc.getValue()); + _addRecordToRecListInExtent(txn, r, loc.getValue()); - _details->incrementStats( r->netLength(), 1 ); + _details->incrementStats( txn, r->netLength(), 1 ); return loc; } - StatusWith<DiskLoc> RecordStoreV1Base::insertRecord( const char* data, int len, int quotaMax ) { + StatusWith<DiskLoc> RecordStoreV1Base::insertRecord( TransactionExperiment* txn, + const char* data, + int len, + int quotaMax ) { int lenWHdr = getRecordAllocationSize( len + Record::HeaderSize ); fassert( 17208, lenWHdr >= ( len + Record::HeaderSize ) ); - StatusWith<DiskLoc> loc = allocRecord( lenWHdr, quotaMax ); + StatusWith<DiskLoc> loc = allocRecord( txn, lenWHdr, quotaMax ); if ( !loc.isOK() ) return loc; @@ -173,17 +178,17 @@ namespace mongo { fassert( 17210, r->lengthWithHeaders() >= lenWHdr ); // copy the data - r = reinterpret_cast<Record*>( getDur().writingPtr(r, lenWHdr) ); + r = reinterpret_cast<Record*>( txn->writingPtr(r, lenWHdr) ); memcpy( r->data(), data, len ); - _addRecordToRecListInExtent(r, loc.getValue()); + _addRecordToRecListInExtent(txn, r, loc.getValue()); - _details->incrementStats( r->netLength(), 1 ); + _details->incrementStats( txn, r->netLength(), 1 ); return loc; } - void RecordStoreV1Base::deleteRecord( const DiskLoc& dl ) { + void RecordStoreV1Base::deleteRecord( TransactionExperiment* txn, const DiskLoc& dl ) { Record* todelete = recordFor( dl ); @@ -192,19 +197,19 @@ namespace mongo { if ( todelete->prevOfs() != DiskLoc::NullOfs ) { DiskLoc prev = getPrevRecordInExtent( dl ); Record* prevRecord = recordFor( prev ); - getDur().writingInt( prevRecord->nextOfs() ) = todelete->nextOfs(); + txn->writingInt( prevRecord->nextOfs() ) = todelete->nextOfs(); } if ( todelete->nextOfs() != DiskLoc::NullOfs ) { DiskLoc next = getNextRecord( dl ); Record* nextRecord = recordFor( next ); - getDur().writingInt( nextRecord->prevOfs() ) = todelete->prevOfs(); + txn->writingInt( nextRecord->prevOfs() ) = todelete->prevOfs(); } } /* remove ourself from extent pointers */ { - Extent *e = getDur().writing( _getExtent( _getExtentLocForRecord( dl ) ) ); + Extent *e = txn->writing( _getExtent( _getExtentLocForRecord( dl ) ) ); if ( e->firstRecord == dl ) { if ( todelete->nextOfs() == DiskLoc::NullOfs ) e->firstRecord.Null(); @@ -221,7 +226,7 @@ namespace mongo { /* add to the free list */ { - _details->incrementStats( -1 * todelete->netLength(), -1 ); + _details->incrementStats( txn, -1 * todelete->netLength(), -1 ); if ( _isSystemIndexes ) { /* temp: if in system.indexes, don't reuse, and zero out: we want to be @@ -229,15 +234,15 @@ namespace mongo { to this disk location. so an incorrectly done remove would cause a lot of problems. */ - memset( getDur().writingPtr(todelete, todelete->lengthWithHeaders() ), + memset( txn->writingPtr(todelete, todelete->lengthWithHeaders() ), 0, todelete->lengthWithHeaders() ); } else { DEV { unsigned long long *p = reinterpret_cast<unsigned long long *>( todelete->data() ); - *getDur().writing(p) = 0; + *txn->writing(p) = 0; } - addDeletedRec(dl); + addDeletedRec(txn, dl); } } @@ -247,11 +252,13 @@ namespace mongo { return new RecordStoreV1RepairIterator(this); } - void RecordStoreV1Base::_addRecordToRecListInExtent(Record *r, DiskLoc loc) { + void RecordStoreV1Base::_addRecordToRecListInExtent(TransactionExperiment* txn, + Record *r, + DiskLoc loc) { dassert( recordFor(loc) == r ); Extent *e = _getExtent( _getExtentLocForRecord( loc ) ); if ( e->lastRecord.isNull() ) { - Extent::FL *fl = getDur().writing(e->fl()); + Extent::FL *fl = txn->writing(e->fl()); fl->firstRecord = fl->lastRecord = loc; r->prevOfs() = r->nextOfs() = DiskLoc::NullOfs; } @@ -259,12 +266,14 @@ namespace mongo { Record *oldlast = recordFor(e->lastRecord); r->prevOfs() = e->lastRecord.getOfs(); r->nextOfs() = DiskLoc::NullOfs; - getDur().writingInt(oldlast->nextOfs()) = loc.getOfs(); - *getDur().writing(&e->lastRecord) = loc; + txn->writingInt(oldlast->nextOfs()) = loc.getOfs(); + *txn->writing(&e->lastRecord) = loc; } } - void RecordStoreV1Base::increaseStorageSize( int size, int quotaMax ) { + void RecordStoreV1Base::increaseStorageSize( TransactionExperiment* txn, + int size, + int quotaMax ) { DiskLoc eloc = _extentManager->allocateExtent( _ns, isCapped(), size, @@ -274,26 +283,26 @@ namespace mongo { invariant( e ); - DiskLoc emptyLoc = getDur().writing(e)->reuse( _ns, isCapped() ); + DiskLoc emptyLoc = txn->writing(e)->reuse( _ns, isCapped() ); if ( _details->lastExtent().isNull() ) { verify( _details->firstExtent().isNull() ); - _details->setFirstExtent( eloc ); - _details->setLastExtent( eloc ); - _details->setCapExtent( eloc ); + _details->setFirstExtent( txn, eloc ); + _details->setLastExtent( txn, eloc ); + _details->setCapExtent( txn, eloc ); verify( e->xprev.isNull() ); verify( e->xnext.isNull() ); } else { verify( !_details->firstExtent().isNull() ); - *getDur().writing(&e->xprev) = _details->lastExtent(); - *getDur().writing(&_extentManager->getExtent(_details->lastExtent())->xnext) = eloc; - _details->setLastExtent( eloc ); + *txn->writing(&e->xprev) = _details->lastExtent(); + *txn->writing(&_extentManager->getExtent(_details->lastExtent())->xnext) = eloc; + _details->setLastExtent( txn, eloc ); } - _details->setLastExtentSize( e->length ); + _details->setLastExtentSize( txn, e->length ); - addDeletedRec(emptyLoc); + addDeletedRec(txn, emptyLoc); } Status RecordStoreV1Base::validate( bool full, bool scanData, diff --git a/src/mongo/db/structure/record_store_v1_base.h b/src/mongo/db/structure/record_store_v1_base.h index f170f7fe6be..c066446835a 100644 --- a/src/mongo/db/structure/record_store_v1_base.h +++ b/src/mongo/db/structure/record_store_v1_base.h @@ -38,6 +38,7 @@ namespace mongo { class DocWriter; class ExtentManager; class Record; + class TransactionExperiment; class RecordStoreV1MetaData { public: @@ -46,45 +47,49 @@ namespace mongo { virtual int bucket(int size) const = 0; virtual const DiskLoc& capExtent() const = 0; - virtual void setCapExtent( const DiskLoc& loc ) = 0; + virtual void setCapExtent( TransactionExperiment* txn, const DiskLoc& loc ) = 0; virtual const DiskLoc& capFirstNewRecord() const = 0; - virtual void setCapFirstNewRecord( const DiskLoc& loc ) = 0; + virtual void setCapFirstNewRecord( TransactionExperiment* txn, const DiskLoc& loc ) = 0; virtual bool capLooped() const = 0; - virtual void clearSystemFlags() = 0; + virtual void clearSystemFlags(TransactionExperiment* txn) = 0; virtual long long dataSize() const = 0; virtual long long numRecords() const = 0; - virtual void incrementStats( long long dataSizeIncrement, + virtual void incrementStats( TransactionExperiment* txn, + long long dataSizeIncrement, long long numRecordsIncrement ) = 0; - virtual void setStats( long long dataSizeIncrement, + virtual void setStats( TransactionExperiment* txn, + long long dataSizeIncrement, long long numRecordsIncrement ) = 0; virtual const DiskLoc& deletedListEntry( int bucket ) const = 0; - virtual void setDeletedListEntry( int bucket, const DiskLoc& loc ) = 0; - virtual void orphanDeletedList() = 0; + virtual void setDeletedListEntry( TransactionExperiment* txn, + int bucket, + const DiskLoc& loc ) = 0; + virtual void orphanDeletedList(TransactionExperiment* txn) = 0; virtual const DiskLoc& firstExtent() const = 0; - virtual void setFirstExtent( const DiskLoc& loc ) = 0; + virtual void setFirstExtent( TransactionExperiment* txn, const DiskLoc& loc ) = 0; virtual const DiskLoc& lastExtent() const = 0; - virtual void setLastExtent( const DiskLoc& loc ) = 0; + virtual void setLastExtent( TransactionExperiment* txn, const DiskLoc& loc ) = 0; virtual bool isCapped() const = 0; virtual bool isUserFlagSet( int flag ) const = 0; virtual int lastExtentSize() const = 0; - virtual void setLastExtentSize( int newMax ) = 0; + virtual void setLastExtentSize( TransactionExperiment* txn, int newMax ) = 0; virtual long long maxCappedDocs() const = 0; virtual double paddingFactor() const = 0; - virtual void setPaddingFactor( double paddingFactor ) = 0; + virtual void setPaddingFactor( TransactionExperiment* txn, double paddingFactor ) = 0; virtual int quantizePowerOf2AllocationSpace(int allocSize) const = 0; @@ -103,15 +108,21 @@ namespace mongo { Record* recordFor( const DiskLoc& loc ) const; - void deleteRecord( const DiskLoc& dl ); + void deleteRecord( TransactionExperiment* txn, + const DiskLoc& dl ); - StatusWith<DiskLoc> insertRecord( const char* data, int len, int quotaMax ); + StatusWith<DiskLoc> insertRecord( TransactionExperiment* txn, + const char* data, + int len, + int quotaMax ); - StatusWith<DiskLoc> insertRecord( const DocWriter* doc, int quotaMax ); + StatusWith<DiskLoc> insertRecord( TransactionExperiment* txn, + const DocWriter* doc, + int quotaMax ); virtual RecordIterator* getIteratorForRepair() const; - void increaseStorageSize( int size, int quotaMax ); + void increaseStorageSize( TransactionExperiment* txn, int size, int quotaMax ); virtual Status validate( bool full, bool scanData, ValidateAdaptor* adaptor, @@ -141,10 +152,12 @@ namespace mongo { virtual bool isCapped() const = 0; - virtual StatusWith<DiskLoc> allocRecord( int lengthWithHeaders, int quotaMax ) = 0; + virtual StatusWith<DiskLoc> allocRecord( TransactionExperiment* txn, + int lengthWithHeaders, + int quotaMax ) = 0; // TODO: document, remove, what have you - virtual void addDeletedRec( const DiskLoc& dloc) = 0; + virtual void addDeletedRec( TransactionExperiment* txn, const DiskLoc& dloc) = 0; // TODO: another sad one virtual DeletedRecord* drec( const DiskLoc& loc ) const; @@ -163,7 +176,7 @@ namespace mongo { /** add a record to the end of the linked list chain within this extent. require: you must have already declared write intent for the record header. */ - void _addRecordToRecListInExtent(Record* r, DiskLoc loc); + void _addRecordToRecListInExtent(TransactionExperiment* txn, Record* r, DiskLoc loc); scoped_ptr<RecordStoreV1MetaData> _details; ExtentManager* _extentManager; diff --git a/src/mongo/db/structure/record_store_v1_capped.cpp b/src/mongo/db/structure/record_store_v1_capped.cpp index f27f62eabf5..10484496b6a 100644 --- a/src/mongo/db/structure/record_store_v1_capped.cpp +++ b/src/mongo/db/structure/record_store_v1_capped.cpp @@ -31,9 +31,9 @@ #include "mongo/db/structure/record_store_v1_capped.h" #include "mongo/db/catalog/collection.h" -#include "mongo/db/storage/mmap_v1/dur.h" #include "mongo/db/storage/extent.h" #include "mongo/db/storage/extent_manager.h" +#include "mongo/db/storage/mmap_v1/dur_transaction.h" #include "mongo/db/storage/record.h" #include "mongo/db/structure/catalog/namespace_details.h" #include "mongo/db/structure/record_store_v1_capped_iterator.h" @@ -58,7 +58,8 @@ namespace mongo { - CappedRecordStoreV1::CappedRecordStoreV1( Collection* collection, + CappedRecordStoreV1::CappedRecordStoreV1( TransactionExperiment* txn, + Collection* collection, const StringData& ns, RecordStoreV1MetaData* details, ExtentManager* em, @@ -77,13 +78,15 @@ namespace mongo { } // this is for VERY VERY old versions of capped collections - cappedCheckMigrate(); + cappedCheckMigrate(txn); } CappedRecordStoreV1::~CappedRecordStoreV1() { } - StatusWith<DiskLoc> CappedRecordStoreV1::allocRecord( int lenToAlloc, int quotaMax ) { + StatusWith<DiskLoc> CappedRecordStoreV1::allocRecord( TransactionExperiment* txn, + int lenToAlloc, + int quotaMax ) { { // align very slightly. lenToAlloc = (lenToAlloc + 3) & 0xfffffffc; @@ -106,7 +109,7 @@ namespace mongo { // signal done allocating new extents. if ( !cappedLastDelRecLastExtent().isValid() ) - setLastDelRecLastExtent( DiskLoc() ); + setLastDelRecLastExtent( txn, DiskLoc() ); invariant( lenToAlloc < 400000000 ); int passes = 0; @@ -125,17 +128,17 @@ namespace mongo { DiskLoc firstEmptyExtent; while ( 1 ) { if ( _details->numRecords() < _details->maxCappedDocs() ) { - loc = __capAlloc( lenToAlloc ); + loc = __capAlloc( txn, lenToAlloc ); if ( !loc.isNull() ) break; } // If on first iteration through extents, don't delete anything. if ( !_details->capFirstNewRecord().isValid() ) { - advanceCapExtent( _ns ); + advanceCapExtent( txn, _ns ); if ( _details->capExtent() != _details->firstExtent() ) - _details->setCapFirstNewRecord( DiskLoc().setInvalid() ); + _details->setCapFirstNewRecord( txn, DiskLoc().setInvalid() ); // else signal done with first iteration through extents. continue; } @@ -144,14 +147,14 @@ namespace mongo { theCapExtent()->firstRecord == _details->capFirstNewRecord() ) { // We've deleted all records that were allocated on the previous // iteration through this extent. - advanceCapExtent( _ns ); + advanceCapExtent( txn, _ns ); continue; } if ( theCapExtent()->firstRecord.isNull() ) { if ( firstEmptyExtent.isNull() ) firstEmptyExtent = _details->capExtent(); - advanceCapExtent( _ns ); + advanceCapExtent( txn, _ns ); if ( firstEmptyExtent == _details->capExtent() ) { _maybeComplain( lenToAlloc ); return StatusWith<DiskLoc>( ErrorCodes::InternalError, @@ -162,7 +165,7 @@ namespace mongo { DiskLoc fr = theCapExtent()->firstRecord; _collection->deleteDocument( fr, true ); - compact(); + compact(txn); if( ++passes > maxPasses ) { StringBuilder sb; sb << "passes >= maxPasses in CappedRecordStoreV1::cappedAlloc: ns: " << _ns @@ -178,7 +181,7 @@ namespace mongo { // Remember first record allocated on this iteration through capExtent. if ( _details->capFirstNewRecord().isValid() && _details->capFirstNewRecord().isNull() ) - _details->setCapFirstNewRecord( loc ); + _details->setCapFirstNewRecord( txn, loc ); } invariant( !loc.isNull() ); @@ -195,35 +198,35 @@ namespace mongo { int left = regionlen - lenToAlloc; /* split off some for further use. */ - getDur().writingInt(r->lengthWithHeaders()) = lenToAlloc; + txn->writingInt(r->lengthWithHeaders()) = lenToAlloc; DiskLoc newDelLoc = loc; newDelLoc.inc(lenToAlloc); DeletedRecord* newDel = drec( newDelLoc ); - DeletedRecord* newDelW = getDur().writing(newDel); + DeletedRecord* newDelW = txn->writing(newDel); newDelW->extentOfs() = r->extentOfs(); newDelW->lengthWithHeaders() = left; newDelW->nextDeleted().Null(); - addDeletedRec(newDelLoc); + addDeletedRec(txn, newDelLoc); return StatusWith<DiskLoc>( loc ); } - Status CappedRecordStoreV1::truncate() { - setLastDelRecLastExtent( DiskLoc() ); - setListOfAllDeletedRecords( DiskLoc() ); + Status CappedRecordStoreV1::truncate(TransactionExperiment* txn) { + setLastDelRecLastExtent( txn, DiskLoc() ); + setListOfAllDeletedRecords( txn, DiskLoc() ); // preserve firstExtent/lastExtent - _details->setCapExtent( _details->firstExtent() ); - _details->setStats( 0, 0 ); + _details->setCapExtent( txn, _details->firstExtent() ); + _details->setStats( txn, 0, 0 ); // preserve lastExtentSize // nIndexes preserve 0 // capped preserve true // max preserve - _details->setPaddingFactor( 1.0 ); - _details->clearSystemFlags(); - _details->setCapFirstNewRecord( DiskLoc().setInvalid() ); - setLastDelRecLastExtent( DiskLoc().setInvalid() ); + _details->setPaddingFactor( txn, 1.0 ); + _details->clearSystemFlags(txn); + _details->setCapFirstNewRecord( txn, DiskLoc().setInvalid() ); + setLastDelRecLastExtent( txn, DiskLoc().setInvalid() ); // dataFileVersion preserve // indexFileVersion preserve @@ -235,16 +238,18 @@ namespace mongo { DiskLoc prev = _extentManager->getExtent(ext)->xprev; DiskLoc next = _extentManager->getExtent(ext)->xnext; DiskLoc empty = _extentManager->getExtent(ext)->reuse( _ns, true ); - *getDur().writing(&_extentManager->getExtent(ext)->xprev) = prev; - *getDur().writing(&_extentManager->getExtent(ext)->xnext) = next; - addDeletedRec( empty ); + *txn->writing(&_extentManager->getExtent(ext)->xprev) = prev; + *txn->writing(&_extentManager->getExtent(ext)->xnext) = next; + addDeletedRec( txn, empty ); } return Status::OK(); } - void CappedRecordStoreV1::temp_cappedTruncateAfter( DiskLoc end, bool inclusive ) { - cappedTruncateAfter( _ns.c_str(), end, inclusive ); + void CappedRecordStoreV1::temp_cappedTruncateAfter( TransactionExperiment* txn, + DiskLoc end, + bool inclusive ) { + cappedTruncateAfter( txn, _ns.c_str(), end, inclusive ); } /* combine adjacent deleted records *for the current extent* of the capped collection @@ -252,7 +257,7 @@ namespace mongo { this is O(n^2) but we call it for capped tables where typically n==1 or 2! (or 3...there will be a little unused sliver at the end of the extent.) */ - void CappedRecordStoreV1::compact() { + void CappedRecordStoreV1::compact(TransactionExperiment* txn) { DDD( "CappedRecordStoreV1::compact enter" ); vector<DiskLoc> drecs; @@ -264,7 +269,7 @@ namespace mongo { drecs.push_back( i ); } - setFirstDeletedInCurExtent( i ); + setFirstDeletedInCurExtent( txn, i ); std::sort( drecs.begin(), drecs.end() ); DDD( "\t drecs.size(): " << drecs.size() ); @@ -276,7 +281,7 @@ namespace mongo { j++; if ( j == drecs.end() ) { DDD( "\t compact adddelrec" ); - addDeletedRec( a); + addDeletedRec(txn, a); break; } DiskLoc b = *j; @@ -284,17 +289,17 @@ namespace mongo { a.getOfs() + drec( a )->lengthWithHeaders() == b.getOfs() ) { // a & b are adjacent. merge. - getDur().writingInt( drec(a)->lengthWithHeaders() ) += drec(b)->lengthWithHeaders(); + txn->writingInt( drec(a)->lengthWithHeaders() ) += drec(b)->lengthWithHeaders(); j++; if ( j == drecs.end() ) { DDD( "\t compact adddelrec2" ); - addDeletedRec(a); + addDeletedRec(txn, a); return; } b = *j; } DDD( "\t compact adddelrec3" ); - addDeletedRec(a); + addDeletedRec(txn, a); a = b; } @@ -307,17 +312,18 @@ namespace mongo { return drec(cappedLastDelRecLastExtent())->nextDeleted(); } - void CappedRecordStoreV1::setFirstDeletedInCurExtent( const DiskLoc& loc ) const { + void CappedRecordStoreV1::setFirstDeletedInCurExtent( TransactionExperiment* txn, + const DiskLoc& loc ) { if ( cappedLastDelRecLastExtent().isNull() ) - setListOfAllDeletedRecords( loc ); + setListOfAllDeletedRecords( txn, loc ); else - *getDur().writing( &drec(cappedLastDelRecLastExtent())->nextDeleted() ) = loc; + *txn->writing( &drec(cappedLastDelRecLastExtent())->nextDeleted() ) = loc; } - void CappedRecordStoreV1::cappedCheckMigrate() { + void CappedRecordStoreV1::cappedCheckMigrate(TransactionExperiment* txn) { // migrate old RecordStoreV1MetaData format if ( _details->capExtent().a() == 0 && _details->capExtent().getOfs() == 0 ) { - _details->setCapFirstNewRecord( DiskLoc().setInvalid() ); + _details->setCapFirstNewRecord( txn, DiskLoc().setInvalid() ); // put all the DeletedRecords in cappedListOfAllDeletedRecords() for ( int i = 1; i < Buckets; ++i ) { DiskLoc first = _details->deletedListEntry( i ); @@ -325,14 +331,14 @@ namespace mongo { continue; DiskLoc last = first; for (; !drec(last)->nextDeleted().isNull(); last = drec(last)->nextDeleted() ); - *getDur().writing(&drec(last)->nextDeleted()) = cappedListOfAllDeletedRecords(); - setListOfAllDeletedRecords( first ); - _details->setDeletedListEntry(i,DiskLoc()); + *txn->writing(&drec(last)->nextDeleted()) = cappedListOfAllDeletedRecords(); + setListOfAllDeletedRecords( txn, first ); + _details->setDeletedListEntry(txn, i, DiskLoc()); } // NOTE cappedLastDelRecLastExtent() set to DiskLoc() in above // Last, in case we're killed before getting here - _details->setCapExtent( _details->firstExtent() ); + _details->setCapExtent( txn, _details->firstExtent() ); } } @@ -358,28 +364,29 @@ namespace mongo { return inCapExtent( next ); } - void CappedRecordStoreV1::advanceCapExtent( const StringData& ns ) { + void CappedRecordStoreV1::advanceCapExtent( TransactionExperiment* txn, const StringData& ns ) { // We want cappedLastDelRecLastExtent() to be the last DeletedRecord of the prev cap extent // (or DiskLoc() if new capExtent == firstExtent) if ( _details->capExtent() == _details->lastExtent() ) - setLastDelRecLastExtent( DiskLoc() ); + setLastDelRecLastExtent( txn, DiskLoc() ); else { DiskLoc i = cappedFirstDeletedInCurExtent(); for (; !i.isNull() && nextIsInCapExtent( i ); i = drec(i)->nextDeleted() ); - setLastDelRecLastExtent( i ); + setLastDelRecLastExtent( txn, i ); } - _details->setCapExtent( theCapExtent()->xnext.isNull() ? - _details->firstExtent() : theCapExtent()->xnext ); + _details->setCapExtent( txn, + theCapExtent()->xnext.isNull() ? _details->firstExtent() + : theCapExtent()->xnext ); /* this isn't true if a collection has been renamed...that is ok just used for diagnostics */ //dassert( theCapExtent()->ns == ns ); theCapExtent()->assertOk(); - _details->setCapFirstNewRecord( DiskLoc() ); + _details->setCapFirstNewRecord( txn, DiskLoc() ); } - DiskLoc CappedRecordStoreV1::__capAlloc( int len ) { + DiskLoc CappedRecordStoreV1::__capAlloc( TransactionExperiment* txn, int len ) { DiskLoc prev = cappedLastDelRecLastExtent(); DiskLoc i = cappedFirstDeletedInCurExtent(); DiskLoc ret; @@ -395,22 +402,22 @@ namespace mongo { /* unlink ourself from the deleted list */ if ( !ret.isNull() ) { if ( prev.isNull() ) - setListOfAllDeletedRecords( drec(ret)->nextDeleted() ); + setListOfAllDeletedRecords( txn, drec(ret)->nextDeleted() ); else - *getDur().writing(&drec(prev)->nextDeleted()) = drec(ret)->nextDeleted(); - *getDur().writing(&drec(ret)->nextDeleted()) = DiskLoc().setInvalid(); // defensive. + *txn->writing(&drec(prev)->nextDeleted()) = drec(ret)->nextDeleted(); + *txn->writing(&drec(ret)->nextDeleted()) = DiskLoc().setInvalid(); // defensive. invariant( drec(ret)->extentOfs() < ret.getOfs() ); } return ret; } - void CappedRecordStoreV1::cappedTruncateLastDelUpdate() { + void CappedRecordStoreV1::cappedTruncateLastDelUpdate(TransactionExperiment* txn) { if ( _details->capExtent() == _details->firstExtent() ) { // Only one extent of the collection is in use, so there // is no deleted record in a previous extent, so nullify // cappedLastDelRecLastExtent(). - setLastDelRecLastExtent( DiskLoc() ); + setLastDelRecLastExtent( txn, DiskLoc() ); } else { // Scan through all deleted records in the collection @@ -427,11 +434,14 @@ namespace mongo { // record. (We expect that there will be deleted records in the new // capExtent as well.) invariant( !drec(i)->nextDeleted().isNull() ); - setLastDelRecLastExtent( i ); + setLastDelRecLastExtent( txn, i ); } } - void CappedRecordStoreV1::cappedTruncateAfter(const char *ns, DiskLoc end, bool inclusive) { + void CappedRecordStoreV1::cappedTruncateAfter(TransactionExperiment* txn, + const char* ns, + DiskLoc end, + bool inclusive) { invariant( cappedLastDelRecLastExtent().isValid() ); // We iteratively remove the newest document until the newest document @@ -442,7 +452,7 @@ namespace mongo { // 'end' has been found and removed, so break. break; } - getDur().commitIfNeeded(); + txn->commitIfNeeded(); // 'curr' will point to the newest document in the collection. DiskLoc curr = theCapExtent()->lastRecord; invariant( !curr.isNull() ); @@ -465,7 +475,7 @@ namespace mongo { // Delete the newest record, and coalesce the new deleted // record with existing deleted records. _collection->deleteDocument( curr, true ); - compact(); + compact(txn); // This is the case where we have not yet had to remove any // documents to make room for other documents, and we are allocating @@ -481,11 +491,11 @@ namespace mongo { // NOTE Because we didn't delete the last document, and // capLooped() is false, capExtent is not the first extent // so xprev will be nonnull. - _details->setCapExtent( theCapExtent()->xprev ); + _details->setCapExtent( txn, theCapExtent()->xprev ); theCapExtent()->assertOk(); // update cappedLastDelRecLastExtent() - cappedTruncateLastDelUpdate(); + cappedTruncateLastDelUpdate(txn); } continue; } @@ -514,15 +524,15 @@ namespace mongo { _extentManager->getExtent(newCapExtent)->assertOk(); } while ( _extentManager->getExtent(newCapExtent)->firstRecord.isNull() ); - _details->setCapExtent( newCapExtent ); + _details->setCapExtent( txn, newCapExtent ); // Place all documents in the new capExtent on the fresh side // of the capExtent by setting capFirstNewRecord to the first // document in the new capExtent. - _details->setCapFirstNewRecord( theCapExtent()->firstRecord ); + _details->setCapFirstNewRecord( txn, theCapExtent()->firstRecord ); // update cappedLastDelRecLastExtent() - cappedTruncateLastDelUpdate(); + cappedTruncateLastDelUpdate(txn); } } } @@ -531,16 +541,18 @@ namespace mongo { return _details->deletedListEntry(0); } - void CappedRecordStoreV1::setListOfAllDeletedRecords( const DiskLoc& loc ) const { - return _details->setDeletedListEntry(0,loc); + void CappedRecordStoreV1::setListOfAllDeletedRecords( TransactionExperiment* txn, + const DiskLoc& loc ) { + return _details->setDeletedListEntry(txn, 0, loc); } const DiskLoc& CappedRecordStoreV1::cappedLastDelRecLastExtent() const { return _details->deletedListEntry(1); } - void CappedRecordStoreV1::setLastDelRecLastExtent( const DiskLoc& loc ) const { - return _details->setDeletedListEntry(1,loc); + void CappedRecordStoreV1::setLastDelRecLastExtent( TransactionExperiment* txn, + const DiskLoc& loc ) { + return _details->setDeletedListEntry(txn, 1, loc); } bool CappedRecordStoreV1::capLooped() const { @@ -551,11 +563,11 @@ namespace mongo { return _extentManager->getExtent(_details->capExtent()); } - void CappedRecordStoreV1::addDeletedRec( const DiskLoc& dloc ) { + void CappedRecordStoreV1::addDeletedRec( TransactionExperiment* txn, const DiskLoc& dloc ) { DeletedRecord* d = drec( dloc ); { - Record *r = (Record *) getDur().writingPtr(d, sizeof(Record)); + Record *r = (Record *) txn->writingPtr(d, sizeof(Record)); d = &r->asDeleted(); // defensive code: try to make us notice if we reference a deleted record reinterpret_cast<unsigned*>( r->data() )[0] = 0xeeeeeeee; @@ -565,17 +577,17 @@ namespace mongo { // Initial extent allocation. Insert at end. d->nextDeleted() = DiskLoc(); if ( cappedListOfAllDeletedRecords().isNull() ) - setListOfAllDeletedRecords( dloc ); + setListOfAllDeletedRecords( txn, dloc ); else { DiskLoc i = cappedListOfAllDeletedRecords(); for (; !drec(i)->nextDeleted().isNull(); i = drec(i)->nextDeleted() ) ; - *getDur().writing(&drec(i)->nextDeleted()) = dloc; + *txn->writing(&drec(i)->nextDeleted()) = dloc; } } else { d->nextDeleted() = cappedFirstDeletedInCurExtent(); - setFirstDeletedInCurExtent( dloc ); + setFirstDeletedInCurExtent( txn, dloc ); // always compact() after this so order doesn't matter } } @@ -637,7 +649,8 @@ namespace mongo { return iterators.release(); } - Status CappedRecordStoreV1::compact( RecordStoreCompactAdaptor* adaptor, + Status CappedRecordStoreV1::compact( TransactionExperiment* txn, + RecordStoreCompactAdaptor* adaptor, const CompactOptions* options, CompactStats* stats ) { invariant(false); diff --git a/src/mongo/db/structure/record_store_v1_capped.h b/src/mongo/db/structure/record_store_v1_capped.h index c70d34f9881..8209dc1a3cd 100644 --- a/src/mongo/db/structure/record_store_v1_capped.h +++ b/src/mongo/db/structure/record_store_v1_capped.h @@ -41,7 +41,8 @@ namespace mongo { class CappedRecordStoreV1 : public RecordStoreV1Base { public: - CappedRecordStoreV1( Collection* collection, + CappedRecordStoreV1( TransactionExperiment* txn, + Collection* collection, const StringData& ns, RecordStoreV1MetaData* details, ExtentManager* em, @@ -51,7 +52,7 @@ namespace mongo { const char* name() const { return "CappedRecordStoreV1"; } - virtual Status truncate(); + virtual Status truncate(TransactionExperiment* txn); /** * Truncate documents newer than the document at 'end' from the capped @@ -60,7 +61,7 @@ namespace mongo { * @param inclusive - Truncate 'end' as well iff true * XXX: this will go away soon, just needed to move for now */ - void temp_cappedTruncateAfter( DiskLoc end, bool inclusive ); + void temp_cappedTruncateAfter( TransactionExperiment* txn, DiskLoc end, bool inclusive ); virtual RecordIterator* getIterator( const DiskLoc& start, bool tailable, const CollectionScanParams::Direction& dir) const; @@ -69,7 +70,8 @@ namespace mongo { virtual bool compactSupported() const { return false; } - virtual Status compact( RecordStoreCompactAdaptor* adaptor, + virtual Status compact( TransactionExperiment* txn, + RecordStoreCompactAdaptor* adaptor, const CompactOptions* options, CompactStats* stats ); @@ -82,27 +84,29 @@ namespace mongo { virtual bool isCapped() const { return true; } - virtual StatusWith<DiskLoc> allocRecord( int lengthWithHeaders, int quotaMax ); + virtual StatusWith<DiskLoc> allocRecord( TransactionExperiment* txn, + int lengthWithHeaders, + int quotaMax ); - virtual void addDeletedRec(const DiskLoc& dloc); + virtual void addDeletedRec(TransactionExperiment* txn, const DiskLoc& dloc); private: // -- start copy from cap.cpp -- - void compact(); + void compact(TransactionExperiment* txn); const DiskLoc& cappedFirstDeletedInCurExtent() const; - void setFirstDeletedInCurExtent( const DiskLoc& loc ) const; - void cappedCheckMigrate(); - DiskLoc __capAlloc( int len ); + void setFirstDeletedInCurExtent( TransactionExperiment* txn, const DiskLoc& loc ); + void cappedCheckMigrate(TransactionExperiment* txn); + DiskLoc __capAlloc( TransactionExperiment* txn, int len ); bool inCapExtent( const DiskLoc &dl ) const; const DiskLoc& cappedListOfAllDeletedRecords() const; const DiskLoc& cappedLastDelRecLastExtent() const; - void setListOfAllDeletedRecords( const DiskLoc& loc ) const; - void setLastDelRecLastExtent( const DiskLoc& loc ) const; + void setListOfAllDeletedRecords( TransactionExperiment* txn, const DiskLoc& loc ); + void setLastDelRecLastExtent( TransactionExperiment* txn, const DiskLoc& loc ); bool capLooped() const; Extent *theCapExtent() const; bool nextIsInCapExtent( const DiskLoc &dl ) const; - void advanceCapExtent( const StringData& ns ); - void cappedTruncateLastDelUpdate(); + void advanceCapExtent( TransactionExperiment* txn, const StringData& ns ); + void cappedTruncateLastDelUpdate(TransactionExperiment* txn); /** * Truncate documents newer than the document at 'end' from the capped @@ -110,7 +114,10 @@ namespace mongo { * function. An assertion will be thrown if that is attempted. * @param inclusive - Truncate 'end' as well iff true */ - void cappedTruncateAfter(const char *ns, DiskLoc end, bool inclusive); + void cappedTruncateAfter(TransactionExperiment* txn, + const char* ns, + DiskLoc end, + bool inclusive); void _maybeComplain( int len ) const; diff --git a/src/mongo/db/structure/record_store_v1_simple.cpp b/src/mongo/db/structure/record_store_v1_simple.cpp index e89ee23e999..32a5729b72f 100644 --- a/src/mongo/db/structure/record_store_v1_simple.cpp +++ b/src/mongo/db/structure/record_store_v1_simple.cpp @@ -35,11 +35,11 @@ #include "mongo/db/client.h" #include "mongo/db/commands/server_status.h" #include "mongo/db/curop.h" -#include "mongo/db/storage/mmap_v1/dur.h" #include "mongo/db/kill_current_op.h" #include "mongo/db/storage/extent.h" #include "mongo/db/storage/extent_manager.h" #include "mongo/db/storage/record.h" +#include "mongo/db/storage/transaction.h" #include "mongo/db/structure/catalog/namespace_details.h" #include "mongo/db/structure/record_store_v1_simple_iterator.h" #include "mongo/util/progress_meter.h" @@ -60,7 +60,8 @@ namespace mongo { static ServerStatusMetricField<Counter64> dFreelist3( "storage.freelist.search.scanned", &freelistIterations ); - SimpleRecordStoreV1::SimpleRecordStoreV1( const StringData& ns, + SimpleRecordStoreV1::SimpleRecordStoreV1( TransactionExperiment* txn, + const StringData& ns, RecordStoreV1MetaData* details, ExtentManager* em, bool isSystemIndexes ) @@ -70,7 +71,7 @@ namespace mongo { _normalCollection = NamespaceString::normal( ns ); if ( _details->paddingFactor() == 0 ) { warning() << "implicit updgrade of paddingFactor of very old collection" << endl; - _details->setPaddingFactor(1.0); + _details->setPaddingFactor(txn, 1.0); } } @@ -78,7 +79,8 @@ namespace mongo { SimpleRecordStoreV1::~SimpleRecordStoreV1() { } - DiskLoc SimpleRecordStoreV1::_allocFromExistingExtents( int lenToAlloc ) { + DiskLoc SimpleRecordStoreV1::_allocFromExistingExtents( TransactionExperiment* txn, + int lenToAlloc ) { // align very slightly. lenToAlloc = (lenToAlloc + 3) & 0xfffffffc; @@ -155,15 +157,15 @@ namespace mongo { // unlink ourself from the deleted list DeletedRecord *bmr = drec(bestmatch); if ( bestprev ) { - *getDur().writing(bestprev) = bmr->nextDeleted(); + *txn->writing(bestprev) = bmr->nextDeleted(); } else { // should be the front of a free-list int bucket = _details->bucket(bmr->lengthWithHeaders()); invariant( _details->deletedListEntry(bucket) == bestmatch ); - _details->setDeletedListEntry(bucket, bmr->nextDeleted()); + _details->setDeletedListEntry(txn, bucket, bmr->nextDeleted()); } - *getDur().writing(&bmr->nextDeleted()) = DiskLoc().setInvalid(); // defensive. + *txn->writing(&bmr->nextDeleted()) = DiskLoc().setInvalid(); // defensive. invariant(bmr->extentOfs() < bestmatch.getOfs()); freelistIterations.increment( 1 + chain ); @@ -204,33 +206,36 @@ namespace mongo { } /* split off some for further use. */ - getDur().writingInt(r->lengthWithHeaders()) = lenToAlloc; + txn->writingInt(r->lengthWithHeaders()) = lenToAlloc; DiskLoc newDelLoc = loc; newDelLoc.inc(lenToAlloc); DeletedRecord* newDel = drec(newDelLoc); - DeletedRecord* newDelW = getDur().writing(newDel); + DeletedRecord* newDelW = txn->writing(newDel); newDelW->extentOfs() = r->extentOfs(); newDelW->lengthWithHeaders() = left; newDelW->nextDeleted().Null(); - addDeletedRec( newDelLoc ); + addDeletedRec( txn, newDelLoc ); return loc; } - StatusWith<DiskLoc> SimpleRecordStoreV1::allocRecord( int lengthWithHeaders, int quotaMax ) { - DiskLoc loc = _allocFromExistingExtents( lengthWithHeaders ); + StatusWith<DiskLoc> SimpleRecordStoreV1::allocRecord( TransactionExperiment* txn, + int lengthWithHeaders, + int quotaMax ) { + DiskLoc loc = _allocFromExistingExtents( txn, lengthWithHeaders ); if ( !loc.isNull() ) return StatusWith<DiskLoc>( loc ); LOG(1) << "allocating new extent"; - increaseStorageSize( Extent::followupSize( lengthWithHeaders, + increaseStorageSize( txn, + Extent::followupSize( lengthWithHeaders, _details->lastExtentSize()), quotaMax ); - loc = _allocFromExistingExtents( lengthWithHeaders ); + loc = _allocFromExistingExtents( txn, lengthWithHeaders ); if ( !loc.isNull() ) { // got on first try return StatusWith<DiskLoc>( loc ); @@ -243,11 +248,12 @@ namespace mongo { for ( int z = 0; z < 10 && lengthWithHeaders > _details->lastExtentSize(); z++ ) { log() << "try #" << z << endl; - increaseStorageSize( Extent::followupSize( lengthWithHeaders, + increaseStorageSize( txn, + Extent::followupSize( lengthWithHeaders, _details->lastExtentSize()), quotaMax ); - loc = _allocFromExistingExtents( lengthWithHeaders ); + loc = _allocFromExistingExtents( txn, lengthWithHeaders ); if ( ! loc.isNull() ) return StatusWith<DiskLoc>( loc ); } @@ -255,16 +261,16 @@ namespace mongo { return StatusWith<DiskLoc>( ErrorCodes::InternalError, "cannot allocate space" ); } - Status SimpleRecordStoreV1::truncate() { + Status SimpleRecordStoreV1::truncate(TransactionExperiment* txn) { return Status( ErrorCodes::InternalError, "SimpleRecordStoreV1::truncate not implemented" ); } - void SimpleRecordStoreV1::addDeletedRec( const DiskLoc& dloc ) { + void SimpleRecordStoreV1::addDeletedRec( TransactionExperiment* txn, const DiskLoc& dloc ) { DeletedRecord* d = drec( dloc ); { - Record *r = (Record *) getDur().writingPtr(d, sizeof(Record)); + Record *r = (Record *) txn->writingPtr(d, sizeof(Record)); d = &r->asDeleted(); // defensive code: try to make us notice if we reference a deleted record reinterpret_cast<unsigned*>( r->data() )[0] = 0xeeeeeeee; @@ -273,7 +279,7 @@ namespace mongo { int b = _details->bucket(d->lengthWithHeaders()); d->nextDeleted() = _details->deletedListEntry(b); - _details->setDeletedListEntry(b, dloc); + _details->setDeletedListEntry(txn, b, dloc); } RecordIterator* SimpleRecordStoreV1::getIterator( const DiskLoc& start, bool tailable, @@ -326,7 +332,9 @@ namespace mongo { size_t _allocationSize; }; - void SimpleRecordStoreV1::_compactExtent(const DiskLoc diskloc, int extentNumber, + void SimpleRecordStoreV1::_compactExtent(TransactionExperiment* txn, + const DiskLoc diskloc, + int extentNumber, RecordStoreCompactAdaptor* adaptor, const CompactOptions* compactOptions, CompactStats* stats ) { @@ -399,7 +407,7 @@ namespace mongo { } CompactDocWriter writer( recOld, dataSize, lenWPadding ); - StatusWith<DiskLoc> status = insertRecord( &writer, 0 ); + StatusWith<DiskLoc> status = insertRecord( txn, &writer, 0 ); uassertStatusOK( status.getStatus() ); datasize += recordFor( status.getValue() )->netLength(); @@ -415,11 +423,11 @@ namespace mongo { // remove the old records (orphan them) periodically so our commit block doesn't get too large bool stopping = false; RARELY stopping = *killCurrentOp.checkForInterruptNoAssert() != 0; - if( stopping || getDur().isCommitNeeded() ) { - *getDur().writing(&e->firstRecord) = L; + if( stopping || txn->isCommitNeeded() ) { + *txn->writing(&e->firstRecord) = L; Record *r = recordFor(L); - getDur().writingInt(r->prevOfs()) = DiskLoc::NullOfs; - getDur().commitIfNeeded(); + txn->writingInt(r->prevOfs()) = DiskLoc::NullOfs; + txn->commitIfNeeded(); killCurrentOp.checkForInterrupt(); } } @@ -428,12 +436,12 @@ namespace mongo { invariant( _details->firstExtent() == diskloc ); invariant( _details->lastExtent() != diskloc ); DiskLoc newFirst = e->xnext; - _details->setFirstExtent( newFirst ); - *getDur().writing(&_extentManager->getExtent( newFirst )->xprev) = DiskLoc(); - getDur().writing(e)->markEmpty(); + _details->setFirstExtent( txn, newFirst ); + *txn->writing(&_extentManager->getExtent( newFirst )->xprev) = DiskLoc(); + txn->writing(e)->markEmpty(); _extentManager->freeExtents( diskloc, diskloc ); - getDur().commitIfNeeded(); + txn->commitIfNeeded(); { double op = 1.0; @@ -447,12 +455,13 @@ namespace mongo { } - Status SimpleRecordStoreV1::compact( RecordStoreCompactAdaptor* adaptor, + Status SimpleRecordStoreV1::compact( TransactionExperiment* txn, + RecordStoreCompactAdaptor* adaptor, const CompactOptions* options, CompactStats* stats ) { // this is a big job, so might as well make things tidy before we start just to be nice. - getDur().commitIfNeeded(); + txn->commitIfNeeded(); list<DiskLoc> extents; for( DiskLoc extLocation = _details->firstExtent(); @@ -463,17 +472,17 @@ namespace mongo { log() << "compact " << extents.size() << " extents"; log() << "compact orphan deleted lists" << endl; - _details->orphanDeletedList(); + _details->orphanDeletedList(txn); // Start over from scratch with our extent sizing and growth - _details->setLastExtentSize( 0 ); + _details->setLastExtentSize( txn, 0 ); // create a new extent so new records go there - increaseStorageSize( _details->lastExtentSize(), true ); + increaseStorageSize( txn, _details->lastExtentSize(), true ); // reset data size and record counts to 0 for this namespace // as we're about to tally them up again for each new extent - _details->setStats( 0, 0 ); + _details->setStats( txn, 0, 0 ); ProgressMeterHolder pm(cc().curop()->setMessage("compact extent", "Extent Compacting Progress", @@ -481,7 +490,7 @@ namespace mongo { int extentNumber = 0; for( list<DiskLoc>::iterator i = extents.begin(); i != extents.end(); i++ ) { - _compactExtent(*i, extentNumber++, adaptor, options, stats ); + _compactExtent(txn, *i, extentNumber++, adaptor, options, stats ); pm.hit(); } diff --git a/src/mongo/db/structure/record_store_v1_simple.h b/src/mongo/db/structure/record_store_v1_simple.h index c100a294a5a..79139d93437 100644 --- a/src/mongo/db/structure/record_store_v1_simple.h +++ b/src/mongo/db/structure/record_store_v1_simple.h @@ -40,7 +40,8 @@ namespace mongo { // used by index and original collections class SimpleRecordStoreV1 : public RecordStoreV1Base { public: - SimpleRecordStoreV1( const StringData& ns, + SimpleRecordStoreV1( TransactionExperiment* txn, + const StringData& ns, RecordStoreV1MetaData* details, ExtentManager* em, bool isSystemIndexes ); @@ -54,23 +55,30 @@ namespace mongo { virtual std::vector<RecordIterator*> getManyIterators() const; - virtual Status truncate(); + virtual Status truncate(TransactionExperiment* txn); virtual bool compactSupported() const { return true; } - virtual Status compact( RecordStoreCompactAdaptor* adaptor, + virtual Status compact( TransactionExperiment* txn, + RecordStoreCompactAdaptor* adaptor, const CompactOptions* options, CompactStats* stats ); protected: virtual bool isCapped() const { return false; } - virtual StatusWith<DiskLoc> allocRecord( int lengthWithHeaders, int quotaMax ); + virtual StatusWith<DiskLoc> allocRecord( TransactionExperiment* txn, + int lengthWithHeaders, + int quotaMax ); - virtual void addDeletedRec(const DiskLoc& dloc); + virtual void addDeletedRec(TransactionExperiment* txn, + const DiskLoc& dloc); private: - DiskLoc _allocFromExistingExtents( int lengthWithHeaders ); + DiskLoc _allocFromExistingExtents( TransactionExperiment* txn, + int lengthWithHeaders ); - void _compactExtent(const DiskLoc diskloc, int extentNumber, + void _compactExtent(TransactionExperiment* txn, + const DiskLoc diskloc, + int extentNumber, RecordStoreCompactAdaptor* adaptor, const CompactOptions* compactOptions, CompactStats* stats ); diff --git a/src/mongo/dbtests/namespacetests.cpp b/src/mongo/dbtests/namespacetests.cpp index 42349286cdf..cc5cc892fd6 100644 --- a/src/mongo/dbtests/namespacetests.cpp +++ b/src/mongo/dbtests/namespacetests.cpp @@ -41,6 +41,7 @@ #include "mongo/db/queryutil.h" #include "mongo/db/storage/extent.h" #include "mongo/db/storage/extent_manager.h" +#include "mongo/db/storage/mmap_v1/dur_transaction.h" #include "mongo/db/structure/record_store_v1_capped.h" #include "mongo/db/structure/record_store_v1_simple.h" #include "mongo/db/structure/catalog/namespace.h" @@ -546,16 +547,18 @@ namespace NamespaceTests { class AllocQuantized : public Base { public: void run() { + DurTransaction txn[1]; string myns = (string)ns() + "AllocQuantized"; db()->namespaceIndex().add_ns( myns, DiskLoc(), false ); - SimpleRecordStoreV1 rs( myns, + SimpleRecordStoreV1 rs( txn, + myns, new NamespaceDetailsRSV1MetaData( db()->namespaceIndex().details( myns ) ), &db()->getExtentManager(), false ); BSONObj obj = docForRecordSize( 300 ); - StatusWith<DiskLoc> result = rs.insertRecord( obj.objdata(), obj.objsize(), 0 ); + StatusWith<DiskLoc> result = rs.insertRecord( txn, obj.objdata(), obj.objsize(), 0 ); ASSERT( result.isOK() ); // The length of the allocated record is quantized. @@ -589,16 +592,18 @@ namespace NamespaceTests { class AllocIndexNamespaceNotQuantized : public Base { public: void run() { + DurTransaction txn[1]; string myns = (string)ns() + "AllocIndexNamespaceNotQuantized"; db()->namespaceIndex().add_ns( myns, DiskLoc(), false ); - SimpleRecordStoreV1 rs( myns + ".$x", + SimpleRecordStoreV1 rs( txn, + myns + ".$x", new NamespaceDetailsRSV1MetaData( db()->namespaceIndex().details( myns ) ), &db()->getExtentManager(), false ); BSONObj obj = docForRecordSize( 300 ); - StatusWith<DiskLoc> result = rs.insertRecord( obj.objdata(), obj.objsize(), 0 ); + StatusWith<DiskLoc> result = rs.insertRecord(txn, obj.objdata(), obj.objsize(), 0 ); ASSERT( result.isOK() ); // The length of the allocated record is not quantized. @@ -611,16 +616,18 @@ namespace NamespaceTests { class AllocIndexNamespaceSlightlyQuantized : public Base { public: void run() { + DurTransaction txn[1]; string myns = (string)ns() + "AllocIndexNamespaceNotQuantized"; db()->namespaceIndex().add_ns( myns, DiskLoc(), false ); - SimpleRecordStoreV1 rs( myns + ".$x", + SimpleRecordStoreV1 rs( txn, + myns + ".$x", new NamespaceDetailsRSV1MetaData( db()->namespaceIndex().details( myns ) ), &db()->getExtentManager(), true ); BSONObj obj = docForRecordSize( 298 ); - StatusWith<DiskLoc> result = rs.insertRecord( obj.objdata(), obj.objsize(), 0 ); + StatusWith<DiskLoc> result = rs.insertRecord( txn, obj.objdata(), obj.objsize(), 0 ); ASSERT( result.isOK() ); ASSERT_EQUALS( 300, rs.recordFor( result.getValue() )->lengthWithHeaders() ); |