Status Database::dropCollection( const StringData& fullns ) { LOG(1) << "dropCollection: " << fullns << endl; massertNamespaceNotIndex( fullns, "dropCollection" ); Collection* collection = getCollection( fullns ); if ( !collection ) { // collection doesn't exist return Status::OK(); } _initForWrites(); { NamespaceString s( fullns ); verify( s.db() == _name ); if( s.isSystem() ) { if( s.coll() == "system.profile" ) { if ( _profile != 0 ) return Status( ErrorCodes::IllegalOperation, "turn off profiling before dropping system.profile collection" ); } else { return Status( ErrorCodes::IllegalOperation, "can't drop system ns" ); } } } BackgroundOperation::assertNoBgOpInProgForNs( fullns ); audit::logDropCollection( currentClient.get(), fullns ); try { Status s = collection->getIndexCatalog()->dropAllIndexes( true ); if ( !s.isOK() ) { warning() << "could not drop collection, trying to drop indexes" << fullns << " because of " << s.toString(); return s; } } catch( DBException& e ) { stringstream ss; ss << "drop: dropIndexes for collection failed. cause: " << e.what(); ss << ". See http://dochub.mongodb.org/core/data-recovery"; warning() << ss.str() << endl; return Status( ErrorCodes::InternalError, ss.str() ); } verify( collection->_details->getTotalIndexCount() == 0 ); LOG(1) << "\t dropIndexes done" << endl; ClientCursor::invalidate( fullns ); Top::global.collectionDropped( fullns ); Status s = _dropNS( fullns ); _clearCollectionCache( fullns ); // we want to do this always if ( !s.isOK() ) return s; DEV { // check all index collection entries are gone string nstocheck = fullns.toString() + ".$"; scoped_lock lk( _collectionLock ); for ( CollectionMap::const_iterator i = _collections.begin(); i != _collections.end(); ++i ) { string temp = i->first; if ( temp.find( nstocheck ) != 0 ) continue; log() << "after drop, bad cache entries for: " << fullns << " have " << temp; verify(0); } } return Status::OK(); }
Status Database::dropCollection(OperationContext* txn, StringData fullns) { invariant(txn->lockState()->isDbLockedForMode(name(), MODE_X)); LOG(1) << "dropCollection: " << fullns; massertNamespaceNotIndex(fullns, "dropCollection"); Collection* collection = getCollection(fullns); if (!collection) { // collection doesn't exist return Status::OK(); } NamespaceString nss(fullns); { verify(nss.db() == _name); if (nss.isSystem()) { if (nss.isSystemDotProfile()) { if (_profile != 0) return Status(ErrorCodes::IllegalOperation, "turn off profiling before dropping system.profile collection"); } else if (nss.isSystemDotViews()) { if (serverGlobalParams.featureCompatibilityVersion.load() != ServerGlobalParams::FeatureCompatibilityVersion_32) { return Status(ErrorCodes::IllegalOperation, "The featureCompatibilityVersion must be 3.2 to drop the " "system.views collection. See " "http://dochub.mongodb.org/core/3.4-feature-compatibility."); } } else { return Status(ErrorCodes::IllegalOperation, "can't drop system ns"); } } } BackgroundOperation::assertNoBgOpInProgForNs(fullns); audit::logDropCollection(&cc(), fullns); Status s = collection->getIndexCatalog()->dropAllIndexes(txn, true); if (!s.isOK()) { warning() << "could not drop collection, trying to drop indexes" << fullns << " because of " << redact(s.toString()); return s; } verify(collection->_details->getTotalIndexCount(txn) == 0); LOG(1) << "\t dropIndexes done"; Top::get(txn->getClient()->getServiceContext()).collectionDropped(fullns); s = _dbEntry->dropCollection(txn, fullns); // we want to do this always _clearCollectionCache(txn, fullns, "collection dropped"); if (!s.isOK()) return s; DEV { // check all index collection entries are gone string nstocheck = fullns.toString() + ".$"; for (CollectionMap::const_iterator i = _collections.begin(); i != _collections.end(); ++i) { string temp = i->first; if (temp.find(nstocheck) != 0) continue; log() << "after drop, bad cache entries for: " << fullns << " have " << temp; verify(0); } } auto opObserver = getGlobalServiceContext()->getOpObserver(); if (opObserver) opObserver->onDropCollection(txn, nss); return Status::OK(); }
Status Database::dropCollection(OperationContext* txn, StringData fullns) { invariant(txn->lockState()->isDbLockedForMode(name(), MODE_X)); LOG(1) << "dropCollection: " << fullns; massertNamespaceNotIndex(fullns, "dropCollection"); Collection* collection = getCollection(fullns); if (!collection) { // collection doesn't exist return Status::OK(); } NamespaceString nss(fullns); { verify(nss.db() == _name); if (nss.isSystem()) { if (nss.isSystemDotProfile()) { if (_profile != 0) return Status(ErrorCodes::IllegalOperation, "turn off profiling before dropping system.profile collection"); } else if (!nss.isSystemDotViews()) { return Status(ErrorCodes::IllegalOperation, "can't drop system ns"); } } } BackgroundOperation::assertNoBgOpInProgForNs(fullns); audit::logDropCollection(&cc(), fullns); Status s = collection->getIndexCatalog()->dropAllIndexes(txn, true); if (!s.isOK()) { warning() << "could not drop collection, trying to drop indexes" << fullns << " because of " << redact(s.toString()); return s; } verify(collection->_details->getTotalIndexCount(txn) == 0); LOG(1) << "\t dropIndexes done"; Top::get(txn->getClient()->getServiceContext()).collectionDropped(fullns); // We want to destroy the Collection object before telling the StorageEngine to destroy the // RecordStore. _clearCollectionCache(txn, fullns, "collection dropped"); s = _dbEntry->dropCollection(txn, fullns); if (!s.isOK()) return s; DEV { // check all index collection entries are gone string nstocheck = fullns.toString() + ".$"; for (CollectionMap::const_iterator i = _collections.begin(); i != _collections.end(); ++i) { string temp = i->first; if (temp.find(nstocheck) != 0) continue; log() << "after drop, bad cache entries for: " << fullns << " have " << temp; verify(0); } } getGlobalServiceContext()->getOpObserver()->onDropCollection(txn, nss); return Status::OK(); }
Status Database::dropCollection( const StringData& fullns ) { LOG(1) << "dropCollection: " << fullns << endl; Collection* collection = getCollection( fullns ); if ( !collection ) { // collection doesn't exist return Status::OK(); } _initForWrites(); { NamespaceString s( fullns ); verify( s.db() == _name ); if( s.isSystem() ) { if( s.coll() == "system.profile" ) { if ( _profile != 0 ) return Status( ErrorCodes::IllegalOperation, "turn off profiling before dropping system.profile collection" ); } else { return Status( ErrorCodes::IllegalOperation, "can't drop system ns" ); } } } BackgroundOperation::assertNoBgOpInProgForNs( fullns ); if ( collection->_details->getTotalIndexCount() > 0 ) { try { string errmsg; BSONObjBuilder result; if ( !dropIndexes( collection->_details, fullns, "*", errmsg, result, true) ) { warning() << "could not drop collection: " << fullns << " because of " << errmsg << endl; return Status( ErrorCodes::InternalError, errmsg ); } } catch( DBException& e ) { stringstream ss; ss << "drop: dropIndexes for collection failed - consider trying repair "; ss << " cause: " << e.what(); warning() << ss.str() << endl; return Status( ErrorCodes::InternalError, ss.str() ); } verify( collection->_details->getTotalIndexCount() == 0 ); } LOG(1) << "\t dropIndexes done" << endl; ClientCursor::invalidate( fullns ); Top::global.collectionDropped( fullns ); NamespaceDetailsTransient::eraseCollection( fullns.toString() ); Status s = _dropNS( fullns ); _clearCollectionCache( fullns ); // we want to do this always if ( !s.isOK() ) return s; DEV { // check all index collection entries are gone string nstocheck = fullns.toString() + ".$"; scoped_lock lk( _collectionLock ); for ( CollectionMap::iterator i = _collections.begin(); i != _collections.end(); ++i ) { string temp = i->first; if ( temp.find( nstocheck ) != 0 ) continue; log() << "after drop, bad cache entries for: " << fullns << " have " << temp; verify(0); } } return Status::OK(); }