diff options
author | Eliot Horowitz <eliot@10gen.com> | 2014-03-31 11:11:15 -0400 |
---|---|---|
committer | Eliot Horowitz <eliot@10gen.com> | 2014-04-03 13:31:49 -0400 |
commit | c50dcd3109d76d85c90e5786d5fe7aec73c4f8de (patch) | |
tree | bacd75f0e397e571800f45ca187f8a2b00d9cc56 /src/mongo/db | |
parent | 5234c5739a3dfbba1a831b6b818b29a1e9ec4f0d (diff) | |
download | mongo-c50dcd3109d76d85c90e5786d5fe7aec73c4f8de.tar.gz |
SERVER-13084: remove NamespaceDetails::emptyCappedCollection and replace with Collection::truncate
Diffstat (limited to 'src/mongo/db')
-rw-r--r-- | src/mongo/db/auth/role_graph_update.cpp | 2 | ||||
-rw-r--r-- | src/mongo/db/catalog/collection.cpp | 41 | ||||
-rw-r--r-- | src/mongo/db/catalog/collection.h | 6 | ||||
-rw-r--r-- | src/mongo/db/commands/test_commands.cpp | 4 | ||||
-rw-r--r-- | src/mongo/db/repl/rs_initialsync.cpp | 2 | ||||
-rw-r--r-- | src/mongo/db/repl/rs_rollback.cpp | 2 | ||||
-rw-r--r-- | src/mongo/db/structure/catalog/cap.cpp | 70 | ||||
-rw-r--r-- | src/mongo/db/structure/catalog/namespace_details.h | 2 | ||||
-rw-r--r-- | src/mongo/db/structure/record_store.h | 9 | ||||
-rw-r--r-- | src/mongo/db/structure/record_store_v1_capped.cpp | 40 | ||||
-rw-r--r-- | src/mongo/db/structure/record_store_v1_capped.h | 2 | ||||
-rw-r--r-- | src/mongo/db/structure/record_store_v1_simple.cpp | 4 | ||||
-rw-r--r-- | src/mongo/db/structure/record_store_v1_simple.h | 1 |
13 files changed, 109 insertions, 76 deletions
diff --git a/src/mongo/db/auth/role_graph_update.cpp b/src/mongo/db/auth/role_graph_update.cpp index c1f0e7c834f..873c36b54f2 100644 --- a/src/mongo/db/auth/role_graph_update.cpp +++ b/src/mongo/db/auth/role_graph_update.cpp @@ -261,7 +261,7 @@ namespace { if (cmdName == "dropIndexes" || cmdName == "deleteIndexes") { return Status::OK(); } - if ((cmdName == "collMod" || cmdName == "emptyCappedCollection") && + if ((cmdName == "collMod" || cmdName == "emptycapped") && cmdObj.firstElement().str() != rolesCollectionNamespace.coll()) { // We don't care about these if they're not on the roles collection. diff --git a/src/mongo/db/catalog/collection.cpp b/src/mongo/db/catalog/collection.cpp index 13dc154775a..d8a76819dd0 100644 --- a/src/mongo/db/catalog/collection.cpp +++ b/src/mongo/db/catalog/collection.cpp @@ -460,4 +460,45 @@ namespace mongo { return _details->dataSize(); } + /** + * order will be: + * 1) store index specs + * 2) drop indexes + * 3) truncate record store + * 4) re-write indexes + */ + Status Collection::truncate() { + massert( 17431, "index build in progress", _indexCatalog.numIndexesInProgress() == 0 ); + + // 1) store index specs + vector<BSONObj> indexSpecs; + { + IndexCatalog::IndexIterator ii = _indexCatalog.getIndexIterator( false ); + while ( ii.more() ) { + const IndexDescriptor* idx = ii.next(); + indexSpecs.push_back( idx->infoObj().getOwned() ); + } + } + + // 2) drop indexes + Status status = _indexCatalog.dropAllIndexes( true ); + if ( !status.isOK() ) + return status; + _cursorCache.invalidateAll( false ); + _infoCache.reset(); + + // 3) truncate record store + status = _recordStore->truncate(); + if ( !status.isOK() ) + return status; + + // 4) re-create indexes + for ( size_t i = 0; i < indexSpecs.size(); i++ ) { + status = _indexCatalog.createIndex( indexSpecs[i], false ); + if ( !status.isOK() ) + return status; + } + + return Status::OK(); + } } diff --git a/src/mongo/db/catalog/collection.h b/src/mongo/db/catalog/collection.h index fe0364bf15e..615ea282290 100644 --- a/src/mongo/db/catalog/collection.h +++ b/src/mongo/db/catalog/collection.h @@ -182,6 +182,12 @@ namespace mongo { StatusWith<CompactStats> compact( const CompactOptions* options ); + /** + * removes all documents as fast as possible + * indexes before and after will be the same + * as will other characteristics + */ + Status truncate(); // ----------- diff --git a/src/mongo/db/commands/test_commands.cpp b/src/mongo/db/commands/test_commands.cpp index 208f39619bd..ef4fc7c02c2 100644 --- a/src/mongo/db/commands/test_commands.cpp +++ b/src/mongo/db/commands/test_commands.cpp @@ -191,7 +191,9 @@ namespace mongo { std::vector<BSONObj> indexes = stopIndexBuilds(cc().database(), cmdObj); - collection->details()->emptyCappedCollection( nss.ns().c_str() ); + Status status = collection->truncate(); + if ( !status.isOK() ) + return appendCommandStatus( result, status ); IndexBuilder::restoreIndexes(indexes); diff --git a/src/mongo/db/repl/rs_initialsync.cpp b/src/mongo/db/repl/rs_initialsync.cpp index 0d7a92055b9..28066d1175a 100644 --- a/src/mongo/db/repl/rs_initialsync.cpp +++ b/src/mongo/db/repl/rs_initialsync.cpp @@ -133,7 +133,7 @@ namespace mongo { return; // already empty, ok. LOG(1) << "replSet empty oplog" << rsLog; - collection->details()->emptyCappedCollection(rsoplog); + uassertStatusOK( collection->truncate() ); } bool Member::syncable() const { diff --git a/src/mongo/db/repl/rs_rollback.cpp b/src/mongo/db/repl/rs_rollback.cpp index e63a326937d..d92e37fa213 100644 --- a/src/mongo/db/repl/rs_rollback.cpp +++ b/src/mongo/db/repl/rs_rollback.cpp @@ -529,7 +529,7 @@ namespace mongo { catch(DBException& e) { if( e.getCode() == 13415 ) { // hack: need to just make cappedTruncate do this... - nsd->emptyCappedCollection(d.ns); + uassertStatusOK( collection->truncate() ); } else { throw; diff --git a/src/mongo/db/structure/catalog/cap.cpp b/src/mongo/db/structure/catalog/cap.cpp index e62cce0edad..d103869f092 100644 --- a/src/mongo/db/structure/catalog/cap.cpp +++ b/src/mongo/db/structure/catalog/cap.cpp @@ -426,74 +426,4 @@ namespace mongo { } } - void NamespaceDetails::emptyCappedCollection( const char *ns ) { - massert( 13424, "collection must be capped", isCapped() ); - massert( 13425, "background index build in progress", !_indexBuildsInProgress ); - - vector<BSONObj> indexes = Helpers::findAll( NamespaceString(ns).getSystemIndexesCollection(), - BSON( "ns" << ns ) ); - for ( unsigned i=0; i<indexes.size(); i++ ) { - indexes[i] = indexes[i].copy(); - } - - if ( _nIndexes ) { - Collection* collection = cc().database()->getCollection( ns ); - verify( collection ); - Status status = collection->getIndexCatalog()->dropAllIndexes( true ); - massert( 13426, - str::stream() << "failed index drop: " << status.toString(), - status.isOK() ); - } - - // Clear all references to this namespace. - Collection* collection = cc().database()->getCollection( ns ); - collection->cursorCache()->invalidateAll( false ); - verify( collection->details() == this ); - collection->infoCache()->reset(); - - // Get a writeable reference to 'this' and reset all pertinent - // attributes. - NamespaceDetails *t = writingWithoutExtra(); - - t->cappedLastDelRecLastExtent() = DiskLoc(); - t->cappedListOfAllDeletedRecords() = DiskLoc(); - - // preserve firstExtent/lastExtent - t->_capExtent = _firstExtent; - t->_stats.datasize = _stats.nrecords = 0; - // lastExtentSize preserve - // nIndexes preserve 0 - // capped preserve true - // max preserve - t->_paddingFactor = 1.0; - t->_systemFlags = 0; - t->_capFirstNewRecord = DiskLoc(); - t->_capFirstNewRecord.setInvalid(); - t->cappedLastDelRecLastExtent().setInvalid(); - // dataFileVersion preserve - // indexFileVersion preserve - t->_multiKeyIndexBits = 0; - t->_reservedA = 0; - t->_extraOffset = 0; - // indexBuildInProgress preserve 0 - memset(t->_reserved, 0, sizeof(t->_reserved)); - - // Reset all existing extents and recreate the deleted list. - for( DiskLoc ext = _firstExtent; !ext.isNull(); ext = ext.ext()->xnext ) { - DiskLoc prev = ext.ext()->xprev; - DiskLoc next = ext.ext()->xnext; - DiskLoc empty = ext.ext()->reuse( ns, true ); - ext.ext()->xprev.writing() = prev; - ext.ext()->xnext.writing() = next; - addDeletedRec( empty.drec(), empty ); - } - - for ( unsigned i=0; i<indexes.size(); i++ ) { - IndexCatalog* ic = collection->getIndexCatalog(); - Status status = ic->createIndex( indexes[i], false ); - uassertStatusOK( status ); - } - - } - } diff --git a/src/mongo/db/structure/catalog/namespace_details.h b/src/mongo/db/structure/catalog/namespace_details.h index a294c784e19..10659d7803a 100644 --- a/src/mongo/db/structure/catalog/namespace_details.h +++ b/src/mongo/db/structure/catalog/namespace_details.h @@ -234,8 +234,6 @@ namespace mongo { * @param inclusive - Truncate 'end' as well iff true */ void cappedTruncateAfter(const char *ns, DiskLoc end, bool inclusive); - /** Remove all documents from the capped collection */ - void emptyCappedCollection(const char *ns); /* when a background index build is in progress, we don't count the index in nIndexes until complete, yet need to still use it in _indexRecord() - thus we use this function for that. diff --git a/src/mongo/db/structure/record_store.h b/src/mongo/db/structure/record_store.h index 6d8cb7c1001..6eca53d8a5d 100644 --- a/src/mongo/db/structure/record_store.h +++ b/src/mongo/db/structure/record_store.h @@ -48,6 +48,8 @@ namespace mongo { RecordStore( const StringData& ns ); virtual ~RecordStore(); + // CRUD related + virtual Record* recordFor( const DiskLoc& loc ) const = 0; virtual void deleteRecord( const DiskLoc& dl ) = 0; @@ -56,6 +58,13 @@ namespace mongo { virtual StatusWith<DiskLoc> insertRecord( const DocWriter* doc, int quotaMax ) = 0; + // higher level + + /** + * removes all Records + */ + virtual Status truncate() = 0; + // 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; diff --git a/src/mongo/db/structure/record_store_v1_capped.cpp b/src/mongo/db/structure/record_store_v1_capped.cpp index 183a6bfff98..36b29acb1c6 100644 --- a/src/mongo/db/structure/record_store_v1_capped.cpp +++ b/src/mongo/db/structure/record_store_v1_capped.cpp @@ -70,4 +70,44 @@ namespace mongo { "no space in capped collection" ); } + Status CappedRecordStoreV1::truncate() { + // Get a writeable reference to 'this' and reset all pertinent + // attributes. + NamespaceDetails* t = _details->writingWithoutExtra(); + + t->cappedLastDelRecLastExtent() = DiskLoc(); + t->cappedListOfAllDeletedRecords() = DiskLoc(); + + // preserve firstExtent/lastExtent + t->_capExtent = t->_firstExtent; + t->_stats.datasize = t->_stats.nrecords = 0; + // lastExtentSize preserve + // nIndexes preserve 0 + // capped preserve true + // max preserve + t->_paddingFactor = 1.0; + t->_systemFlags = 0; + t->_capFirstNewRecord = DiskLoc(); + t->_capFirstNewRecord.setInvalid(); + t->cappedLastDelRecLastExtent().setInvalid(); + // dataFileVersion preserve + // indexFileVersion preserve + t->_multiKeyIndexBits = 0; + t->_reservedA = 0; + t->_extraOffset = 0; + // indexBuildInProgress preserve 0 + memset(t->_reserved, 0, sizeof(t->_reserved)); + + // Reset all existing extents and recreate the deleted list. + for( DiskLoc ext = t->_firstExtent; !ext.isNull(); ext = ext.ext()->xnext ) { + DiskLoc prev = ext.ext()->xprev; + DiskLoc next = ext.ext()->xnext; + DiskLoc empty = ext.ext()->reuse( _ns, true ); + ext.ext()->xprev.writing() = prev; + ext.ext()->xnext.writing() = next; + _details->addDeletedRec( empty.drec(), empty ); + } + + return Status::OK(); + } } diff --git a/src/mongo/db/structure/record_store_v1_capped.h b/src/mongo/db/structure/record_store_v1_capped.h index 5b4e9fc056d..0ce454e6812 100644 --- a/src/mongo/db/structure/record_store_v1_capped.h +++ b/src/mongo/db/structure/record_store_v1_capped.h @@ -49,6 +49,8 @@ namespace mongo { virtual ~CappedRecordStoreV1(); + virtual Status truncate(); + protected: virtual StatusWith<DiskLoc> allocRecord( int lengthWithHeaders, int quotaMax ); diff --git a/src/mongo/db/structure/record_store_v1_simple.cpp b/src/mongo/db/structure/record_store_v1_simple.cpp index 37750c8759a..f9b987072f4 100644 --- a/src/mongo/db/structure/record_store_v1_simple.cpp +++ b/src/mongo/db/structure/record_store_v1_simple.cpp @@ -237,4 +237,8 @@ namespace mongo { return StatusWith<DiskLoc>( ErrorCodes::InternalError, "cannot allocate space" ); } + Status SimpleRecordStoreV1::truncate() { + return Status( ErrorCodes::InternalError, + "SimpleRecordStoreV1::truncate not implemented" ); + } } diff --git a/src/mongo/db/structure/record_store_v1_simple.h b/src/mongo/db/structure/record_store_v1_simple.h index 8173db053c0..f00ab8e7858 100644 --- a/src/mongo/db/structure/record_store_v1_simple.h +++ b/src/mongo/db/structure/record_store_v1_simple.h @@ -45,6 +45,7 @@ namespace mongo { virtual ~SimpleRecordStoreV1(); + virtual Status truncate(); protected: virtual StatusWith<DiskLoc> allocRecord( int lengthWithHeaders, int quotaMax ); |