summaryrefslogtreecommitdiff
path: root/src/mongo/db/catalog/database_holder.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/db/catalog/database_holder.cpp')
-rw-r--r--src/mongo/db/catalog/database_holder.cpp228
1 files changed, 109 insertions, 119 deletions
diff --git a/src/mongo/db/catalog/database_holder.cpp b/src/mongo/db/catalog/database_holder.cpp
index bf1238db95f..f4a2cf62970 100644
--- a/src/mongo/db/catalog/database_holder.cpp
+++ b/src/mongo/db/catalog/database_holder.cpp
@@ -46,169 +46,159 @@
namespace mongo {
- using std::set;
- using std::string;
- using std::stringstream;
+using std::set;
+using std::string;
+using std::stringstream;
namespace {
- StringData _todb(StringData ns) {
- size_t i = ns.find('.');
- if (i == std::string::npos) {
- uassert(13074, "db name can't be empty", ns.size());
- return ns;
- }
+StringData _todb(StringData ns) {
+ size_t i = ns.find('.');
+ if (i == std::string::npos) {
+ uassert(13074, "db name can't be empty", ns.size());
+ return ns;
+ }
- uassert(13075, "db name can't be empty", i > 0);
+ uassert(13075, "db name can't be empty", i > 0);
- const StringData d = ns.substr(0, i);
- uassert(13280, "invalid db name: " + ns.toString(), NamespaceString::validDBName(d));
+ const StringData d = ns.substr(0, i);
+ uassert(13280, "invalid db name: " + ns.toString(), NamespaceString::validDBName(d));
- return d;
- }
+ return d;
+}
- DatabaseHolder _dbHolder;
+DatabaseHolder _dbHolder;
-} // namespace
+} // namespace
- DatabaseHolder& dbHolder() {
- return _dbHolder;
- }
+DatabaseHolder& dbHolder() {
+ return _dbHolder;
+}
+
+Database* DatabaseHolder::get(OperationContext* txn, StringData ns) const {
+ const StringData db = _todb(ns);
+ invariant(txn->lockState()->isDbLockedForMode(db, MODE_IS));
- Database* DatabaseHolder::get(OperationContext* txn,
- StringData ns) const {
+ stdx::lock_guard<SimpleMutex> lk(_m);
+ DBs::const_iterator it = _dbs.find(db);
+ if (it != _dbs.end()) {
+ return it->second;
+ }
- const StringData db = _todb(ns);
- invariant(txn->lockState()->isDbLockedForMode(db, MODE_IS));
+ return NULL;
+}
- stdx::lock_guard<SimpleMutex> lk(_m);
- DBs::const_iterator it = _dbs.find(db);
- if (it != _dbs.end()) {
- return it->second;
+Database* DatabaseHolder::openDb(OperationContext* txn, StringData ns, bool* justCreated) {
+ const StringData dbname = _todb(ns);
+ invariant(txn->lockState()->isDbLockedForMode(dbname, MODE_X));
+
+ Database* db = get(txn, ns);
+ if (db) {
+ if (justCreated) {
+ *justCreated = false;
}
- return NULL;
+ return db;
}
- Database* DatabaseHolder::openDb(OperationContext* txn,
- StringData ns,
- bool* justCreated) {
+ // Check casing
+ const string duplicate = Database::duplicateUncasedName(dbname.toString());
+ if (!duplicate.empty()) {
+ stringstream ss;
+ ss << "db already exists with different case already have: [" << duplicate
+ << "] trying to create [" << dbname.toString() << "]";
+ uasserted(ErrorCodes::DatabaseDifferCase, ss.str());
+ }
- const StringData dbname = _todb(ns);
- invariant(txn->lockState()->isDbLockedForMode(dbname, MODE_X));
+ StorageEngine* storageEngine = getGlobalServiceContext()->getGlobalStorageEngine();
+ invariant(storageEngine);
- Database* db = get(txn, ns);
- if (db) {
- if (justCreated) {
- *justCreated = false;
- }
+ DatabaseCatalogEntry* entry = storageEngine->getDatabaseCatalogEntry(txn, dbname);
+ invariant(entry);
+ const bool exists = entry->exists();
+ if (!exists) {
+ audit::logCreateDatabase(&cc(), dbname);
+ }
- return db;
- }
+ if (justCreated) {
+ *justCreated = !exists;
+ }
- // Check casing
- const string duplicate = Database::duplicateUncasedName(dbname.toString());
- if (!duplicate.empty()) {
- stringstream ss;
- ss << "db already exists with different case already have: ["
- << duplicate
- << "] trying to create ["
- << dbname.toString()
- << "]";
- uasserted(ErrorCodes::DatabaseDifferCase, ss.str());
- }
+ // Do this outside of the scoped lock, because database creation does transactional
+ // operations which may block. Only one thread can be inside this method for the same DB
+ // name, because of the requirement for X-lock on the database when we enter. So there is
+ // no way we can insert two different databases for the same name.
+ db = new Database(txn, dbname, entry);
- StorageEngine* storageEngine = getGlobalServiceContext()->getGlobalStorageEngine();
- invariant(storageEngine);
+ stdx::lock_guard<SimpleMutex> lk(_m);
+ _dbs[dbname] = db;
- DatabaseCatalogEntry* entry = storageEngine->getDatabaseCatalogEntry(txn, dbname);
- invariant(entry);
- const bool exists = entry->exists();
- if (!exists) {
- audit::logCreateDatabase(&cc(), dbname);
- }
+ return db;
+}
- if (justCreated) {
- *justCreated = !exists;
- }
+void DatabaseHolder::close(OperationContext* txn, StringData ns) {
+ // TODO: This should be fine if only a DB X-lock
+ invariant(txn->lockState()->isW());
- // Do this outside of the scoped lock, because database creation does transactional
- // operations which may block. Only one thread can be inside this method for the same DB
- // name, because of the requirement for X-lock on the database when we enter. So there is
- // no way we can insert two different databases for the same name.
- db = new Database(txn, dbname, entry);
+ const StringData dbName = _todb(ns);
- stdx::lock_guard<SimpleMutex> lk(_m);
- _dbs[dbname] = db;
+ stdx::lock_guard<SimpleMutex> lk(_m);
- return db;
+ DBs::const_iterator it = _dbs.find(dbName);
+ if (it == _dbs.end()) {
+ return;
}
- void DatabaseHolder::close(OperationContext* txn,
- StringData ns) {
- // TODO: This should be fine if only a DB X-lock
- invariant(txn->lockState()->isW());
+ it->second->close(txn);
+ delete it->second;
+ _dbs.erase(it);
- const StringData dbName = _todb(ns);
-
- stdx::lock_guard<SimpleMutex> lk(_m);
+ getGlobalServiceContext()->getGlobalStorageEngine()->closeDatabase(txn, dbName.toString());
+}
- DBs::const_iterator it = _dbs.find(dbName);
- if (it == _dbs.end()) {
- return;
- }
+bool DatabaseHolder::closeAll(OperationContext* txn, BSONObjBuilder& result, bool force) {
+ invariant(txn->lockState()->isW());
- it->second->close( txn );
- delete it->second;
- _dbs.erase(it);
+ stdx::lock_guard<SimpleMutex> lk(_m);
- getGlobalServiceContext()->getGlobalStorageEngine()->closeDatabase(txn, dbName.toString());
+ set<string> dbs;
+ for (DBs::const_iterator i = _dbs.begin(); i != _dbs.end(); ++i) {
+ dbs.insert(i->first);
}
- bool DatabaseHolder::closeAll(OperationContext* txn, BSONObjBuilder& result, bool force) {
- invariant(txn->lockState()->isW());
+ BSONArrayBuilder bb(result.subarrayStart("dbs"));
+ int nNotClosed = 0;
+ for (set<string>::iterator i = dbs.begin(); i != dbs.end(); ++i) {
+ string name = *i;
- stdx::lock_guard<SimpleMutex> lk(_m);
+ LOG(2) << "DatabaseHolder::closeAll name:" << name;
- set< string > dbs;
- for ( DBs::const_iterator i = _dbs.begin(); i != _dbs.end(); ++i ) {
- dbs.insert( i->first );
+ if (!force && BackgroundOperation::inProgForDb(name)) {
+ log() << "WARNING: can't close database " << name
+ << " because a bg job is in progress - try killOp command";
+ nNotClosed++;
+ continue;
}
- BSONArrayBuilder bb( result.subarrayStart( "dbs" ) );
- int nNotClosed = 0;
- for( set< string >::iterator i = dbs.begin(); i != dbs.end(); ++i ) {
- string name = *i;
-
- LOG(2) << "DatabaseHolder::closeAll name:" << name;
+ Database* db = _dbs[name];
+ db->close(txn);
+ delete db;
- if( !force && BackgroundOperation::inProgForDb(name) ) {
- log() << "WARNING: can't close database "
- << name
- << " because a bg job is in progress - try killOp command";
- nNotClosed++;
- continue;
- }
+ _dbs.erase(name);
- Database* db = _dbs[name];
- db->close( txn );
- delete db;
+ getGlobalServiceContext()->getGlobalStorageEngine()->closeDatabase(txn, name);
- _dbs.erase( name );
-
- getGlobalServiceContext()->getGlobalStorageEngine()->closeDatabase( txn, name );
-
- bb.append( name );
- }
-
- bb.done();
- if( nNotClosed ) {
- result.append("nNotClosed", nNotClosed);
- }
+ bb.append(name);
+ }
- return true;
+ bb.done();
+ if (nNotClosed) {
+ result.append("nNotClosed", nNotClosed);
}
+
+ return true;
+}
}