summaryrefslogtreecommitdiff
path: root/src/mongo/db
diff options
context:
space:
mode:
authorEliot Horowitz <eliot@10gen.com>2014-03-31 11:11:15 -0400
committerEliot Horowitz <eliot@10gen.com>2014-04-03 13:31:49 -0400
commitc50dcd3109d76d85c90e5786d5fe7aec73c4f8de (patch)
treebacd75f0e397e571800f45ca187f8a2b00d9cc56 /src/mongo/db
parent5234c5739a3dfbba1a831b6b818b29a1e9ec4f0d (diff)
downloadmongo-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.cpp2
-rw-r--r--src/mongo/db/catalog/collection.cpp41
-rw-r--r--src/mongo/db/catalog/collection.h6
-rw-r--r--src/mongo/db/commands/test_commands.cpp4
-rw-r--r--src/mongo/db/repl/rs_initialsync.cpp2
-rw-r--r--src/mongo/db/repl/rs_rollback.cpp2
-rw-r--r--src/mongo/db/structure/catalog/cap.cpp70
-rw-r--r--src/mongo/db/structure/catalog/namespace_details.h2
-rw-r--r--src/mongo/db/structure/record_store.h9
-rw-r--r--src/mongo/db/structure/record_store_v1_capped.cpp40
-rw-r--r--src/mongo/db/structure/record_store_v1_capped.h2
-rw-r--r--src/mongo/db/structure/record_store_v1_simple.cpp4
-rw-r--r--src/mongo/db/structure/record_store_v1_simple.h1
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 );