Skip to content

Commit

Permalink
SERVER-13498 Get rid of LockStatus
Browse files Browse the repository at this point in the history
This change removes all usages of LockStatus and pushes the lock
acquisitions to be inside the respective commands. This is a
refactoring on the way to per-document locking.
  • Loading branch information
kaloianm committed Apr 15, 2014
1 parent b3aaf2e commit 1249034
Show file tree
Hide file tree
Showing 81 changed files with 383 additions and 405 deletions.
1 change: 0 additions & 1 deletion src/mongo/SConscript
Expand Up @@ -419,7 +419,6 @@ env.Library("coredb", [
"db/commands/mr_common.cpp",
"db/commands/rename_collection_common.cpp",
"db/commands/server_status.cpp",
"db/commands/shutdown.cpp",
"db/commands/parameters.cpp",
"db/commands/user_management_commands.cpp",
"db/commands/write_commands/write_commands_common.cpp",
Expand Down
2 changes: 1 addition & 1 deletion src/mongo/db/client.cpp
Expand Up @@ -448,7 +448,7 @@ namespace mongo {
public:
void help(stringstream& h) const { h << "internal"; }
HandshakeCmd() : Command( "handshake" ) {}
virtual LockType locktype() const { return NONE; }
virtual bool isWriteCommandForConfigServer() const { return false; }
virtual bool slaveOk() const { return true; }
virtual bool adminOnly() const { return false; }
virtual void addRequiredPrivileges(const std::string& dbname,
Expand Down
2 changes: 1 addition & 1 deletion src/mongo/db/clientcursor.cpp
Expand Up @@ -336,7 +336,7 @@ namespace mongo {
virtual void help( stringstream& help ) const {
help << " example: { cursorInfo : 1 }, deprecated";
}
virtual LockType locktype() const { return NONE; }
virtual bool isWriteCommandForConfigServer() const { return false; }
virtual void addRequiredPrivileges(const std::string& dbname,
const BSONObj& cmdObj,
std::vector<Privilege>* out) {
Expand Down
10 changes: 6 additions & 4 deletions src/mongo/db/cloner.cpp
Expand Up @@ -539,7 +539,7 @@ namespace mongo {
virtual bool slaveOk() const {
return false;
}
virtual LockType locktype() const { return WRITE; }
virtual bool isWriteCommandForConfigServer() const { return true; }
virtual void help( stringstream &help ) const {
help << "clone this database from an instance of the db on another host\n";
help << "{ clone : \"host13\" }";
Expand Down Expand Up @@ -579,6 +579,8 @@ namespace mongo {
}

set<string> clonedColls;

Lock::DBWrite dbXLock(dbname);
Client::Context context( dbname );

Cloner cloner;
Expand All @@ -599,7 +601,7 @@ namespace mongo {
virtual bool slaveOk() const {
return false;
}
virtual LockType locktype() const { return NONE; }
virtual bool isWriteCommandForConfigServer() const { return false; }
CmdCloneCollection() : Command("cloneCollection") { }

virtual std::string parseNs(const std::string& dbname, const BSONObj& cmdObj) const {
Expand Down Expand Up @@ -685,7 +687,7 @@ namespace mongo {
virtual bool slaveOk() const {
return false;
}
virtual LockType locktype() const { return NONE; }
virtual bool isWriteCommandForConfigServer() const { return false; }
virtual void addRequiredPrivileges(const std::string& dbname,
const BSONObj& cmdObj,
std::vector<Privilege>* out) {} // No auth required
Expand Down Expand Up @@ -766,7 +768,7 @@ namespace mongo {
virtual bool slaveOk() const {
return false;
}
virtual LockType locktype() const { return NONE; }
virtual bool isWriteCommandForConfigServer() const { return false; }
virtual Status checkAuthForCommand(ClientBasic* client,
const std::string& dbname,
const BSONObj& cmdObj) {
Expand Down
23 changes: 8 additions & 15 deletions src/mongo/db/commands.cpp
Expand Up @@ -105,16 +105,16 @@ namespace mongo {
if( web ) ss << "</a>";
ss << "</td>\n";
ss << "<td>";
int l = locktype();
//if( l == NONE ) ss << "N ";
if( l == READ ) ss << "R ";
else if( l == WRITE ) ss << "W ";
if (isWriteCommandForConfigServer()) {
ss << "W ";
}
else {
ss << "R ";
}
if( slaveOk() )
ss << "S ";
if( adminOnly() )
ss << "A";
if( lockGlobally() )
ss << " lockGlobally ";
ss << "</td>";
ss << "<td>";
if( helpStr != "no help defined" ) {
Expand Down Expand Up @@ -197,13 +197,6 @@ namespace mongo {
return i->second;
}

Command::LockType Command::locktype( const string& name ) {
Command * c = findCommand( name );
if ( ! c )
return WRITE;
return c->locktype();
}

bool Command::appendCommandStatus(BSONObjBuilder& result, const Status& status) {
appendCommandStatus(result, status.isOK(), status.reason());
BSONObj tmp = result.asTempObj();
Expand Down Expand Up @@ -335,7 +328,7 @@ namespace mongo {
public:
PoolFlushCmd() : Command( "connPoolSync" , false , "connpoolsync" ) {}
virtual void help( stringstream &help ) const { help<<"internal"; }
virtual LockType locktype() const { return NONE; }
virtual bool isWriteCommandForConfigServer() const { return false; }
virtual void addRequiredPrivileges(const std::string& dbname,
const BSONObj& cmdObj,
std::vector<Privilege>* out) {
Expand All @@ -359,7 +352,7 @@ namespace mongo {
public:
PoolStats() : Command( "connPoolStats" ) {}
virtual void help( stringstream &help ) const { help<<"stats about connection pool"; }
virtual LockType locktype() const { return NONE; }
virtual bool isWriteCommandForConfigServer() const { return false; }
virtual void addRequiredPrivileges(const std::string& dbname,
const BSONObj& cmdObj,
std::vector<Privilege>* out) {
Expand Down
23 changes: 8 additions & 15 deletions src/mongo/db/commands.h
Expand Up @@ -61,10 +61,6 @@ namespace mutablebson {
ResourcePattern parseResourcePattern(const std::string& dbname,
const BSONObj& cmdObj) const;

// warning: isAuthorized uses the lockType() return values, and values are being passed
// around as ints so be careful as it isn't really typesafe and will need cleanup later
enum LockType { READ = -1 , NONE = 0 , WRITE = 1 };

const string name;

/* run the given command
Expand All @@ -77,17 +73,15 @@ namespace mutablebson {
*/
virtual bool run(const string& db, BSONObj& cmdObj, int options, string& errmsg, BSONObjBuilder& result, bool fromRepl = false ) = 0;

/*
note: logTheOp() MUST be false if READ
if NONE, can't use Client::Context setup
use with caution
/**
* This designation for the command is only used by the 'help' call and has nothing to do
* with lock acquisition. The reason we need to have it there is because
* SyncClusterConnection uses this to determine whether the command is update and needs to
* be sent to all three servers or just one.
*
* Eventually when SyncClusterConnection is refactored out, we can get rid of it.
*/
virtual LockType locktype() const = 0;

/** if true, lock globally instead of just the one database. by default only the one
database will be locked.
*/
virtual bool lockGlobally() const { return false; }
virtual bool isWriteCommandForConfigServer() const = 0;

/* Return true if only the admin ns has privileges to run this command. */
virtual bool adminOnly() const {
Expand Down Expand Up @@ -203,7 +197,6 @@ namespace mutablebson {
BSONObj& jsobj,
BSONObjBuilder& anObjBuilder,
int queryOptions = 0);
static LockType locktype( const string& name );
static Command * findCommand( const string& name );
// For mongod and webserver.
static void execCommand(Command* c,
Expand Down
7 changes: 5 additions & 2 deletions src/mongo/db/commands/apply_ops.cpp
Expand Up @@ -46,8 +46,8 @@ namespace mongo {
class ApplyOpsCmd : public Command {
public:
virtual bool slaveOk() const { return false; }
virtual LockType locktype() const { return WRITE; }
virtual bool lockGlobally() const { return true; } // SERVER-4328 todo : is global ok or does this take a long time? i believe multiple ns used so locking individually requires more analysis
virtual bool isWriteCommandForConfigServer() const { return true; }

ApplyOpsCmd() : Command( "applyOps" ) {}
virtual void help( stringstream &help ) const {
help << "internal (sharding)\n{ applyOps : [ ] , preCondition : [ { ns : ... , q : ... , res : ... } ] }";
Expand Down Expand Up @@ -105,6 +105,9 @@ namespace mongo {
BSONArrayBuilder ab;
const bool alwaysUpsert = cmdObj.hasField("alwaysUpsert") ?
cmdObj["alwaysUpsert"].trueValue() : true;

// SERVER-4328 todo : is global ok or does this take a long time? i believe multiple ns used so locking individually requires more analysis
Lock::GlobalWrite globalWriteLock;

while ( i.more() ) {
BSONElement e = i.next();
Expand Down
4 changes: 2 additions & 2 deletions src/mongo/db/commands/authentication_commands.cpp
Expand Up @@ -96,7 +96,7 @@ namespace mongo {
return true;
}
void help(stringstream& h) const { h << "internal"; }
virtual LockType locktype() const { return NONE; }
virtual bool isWriteCommandForConfigServer() const { return false; }
virtual void addRequiredPrivileges(const std::string& dbname,
const BSONObj& cmdObj,
std::vector<Privilege>* out) {} // No auth required
Expand Down Expand Up @@ -349,7 +349,7 @@ namespace mongo {
const BSONObj& cmdObj,
std::vector<Privilege>* out) {} // No auth required
void help(stringstream& h) const { h << "de-authenticate"; }
virtual LockType locktype() const { return NONE; }
virtual bool isWriteCommandForConfigServer() const { return false; }
CmdLogout() : Command("logout") {}
bool run(const string& dbname,
BSONObj& cmdObj,
Expand Down
2 changes: 1 addition & 1 deletion src/mongo/db/commands/authentication_commands.h
Expand Up @@ -46,7 +46,7 @@ namespace mongo {
virtual bool slaveOk() const {
return true;
}
virtual LockType locktype() const { return NONE; }
virtual bool isWriteCommandForConfigServer() const { return false; }
virtual void help(stringstream& ss) const { ss << "internal"; }
virtual void addRequiredPrivileges(const std::string& dbname,
const BSONObj& cmdObj,
Expand Down
2 changes: 1 addition & 1 deletion src/mongo/db/commands/cleanup_orphaned_cmd.cpp
Expand Up @@ -167,7 +167,7 @@ namespace mongo {
return Status::OK();
}

virtual LockType locktype() const { return NONE; }
virtual bool isWriteCommandForConfigServer() const { return false; }

// Input
static BSONField<string> nsField;
Expand Down
14 changes: 10 additions & 4 deletions src/mongo/db/commands/collection_to_capped.cpp
Expand Up @@ -117,7 +117,7 @@ namespace mongo {
public:
CmdCloneCollectionAsCapped() : Command( "cloneCollectionAsCapped" ) {}
virtual bool slaveOk() const { return false; }
virtual LockType locktype() const { return WRITE; }
virtual bool isWriteCommandForConfigServer() const { return true; }
virtual void help( stringstream &help ) const {
help << "{ cloneCollectionAsCapped:<fromName>, toCollection:<toName>, size:<sizeInBytes> }";
}
Expand Down Expand Up @@ -150,6 +150,9 @@ namespace mongo {
return false;
}

Lock::DBWrite dbXLock(dbname);
Client::Context ctx(dbname);

Status status = cloneCollectionAsCapped( cc().database(), from, to, size, temp, true );
return appendCommandStatus( result, status );
}
Expand All @@ -164,9 +167,7 @@ namespace mongo {
public:
CmdConvertToCapped() : Command( "convertToCapped" ) {}
virtual bool slaveOk() const { return false; }
virtual LockType locktype() const { return WRITE; }
// calls renamecollection which does a global lock, so we must too:
virtual bool lockGlobally() const { return true; }
virtual bool isWriteCommandForConfigServer() const { return true; }
virtual bool logTheOp() {
// see CmdRenameCollection::logTheOp as to why this is best
return true;
Expand All @@ -193,6 +194,11 @@ namespace mongo {
}

bool run(const string& dbname, BSONObj& jsobj, int, string& errmsg, BSONObjBuilder& result, bool fromRepl ) {
// calls renamecollection which does a global lock, so we must too:
//
Lock::GlobalWrite globalWriteLock;
Client::Context ctx(dbname);

Database* db = cc().database();

stopIndexBuilds(db, jsobj);
Expand Down
2 changes: 1 addition & 1 deletion src/mongo/db/commands/compact.cpp
Expand Up @@ -51,7 +51,7 @@ namespace mongo {

class CompactCmd : public Command {
public:
virtual LockType locktype() const { return NONE; }
virtual bool isWriteCommandForConfigServer() const { return false; }
virtual bool adminOnly() const { return false; }
virtual bool slaveOk() const { return true; }
virtual bool maintenanceMode() const { return true; }
Expand Down
2 changes: 1 addition & 1 deletion src/mongo/db/commands/connection_status.cpp
Expand Up @@ -38,7 +38,7 @@ namespace mongo {
CmdConnectionStatus() : Command("connectionStatus") {}
virtual bool logTheOp() { return false; }
virtual bool slaveOk() const { return true; }
virtual LockType locktype() const { return NONE; }
virtual bool isWriteCommandForConfigServer() const { return false; }
virtual void addRequiredPrivileges(const std::string& dbname,
const BSONObj& cmdObj,
std::vector<Privilege>* out) {} // No auth required
Expand Down
8 changes: 7 additions & 1 deletion src/mongo/db/commands/cpuprofile.cpp
Expand Up @@ -58,6 +58,7 @@
#include "mongo/db/auth/action_type.h"
#include "mongo/db/auth/authorization_manager.h"
#include "mongo/db/auth/privilege.h"
#include "mongo/db/client.h"
#include "mongo/db/commands.h"
#include "mongo/db/jsobj.h"

Expand Down Expand Up @@ -85,7 +86,7 @@ namespace mongo {
// This is an abuse of the global dbmutex. We only really need to
// ensure that only one cpuprofiler command runs at once; it would
// be fine for it to run concurrently with other operations.
virtual LockType locktype() const { return WRITE; }
virtual bool isWriteCommandForConfigServer() const { return true; }
};

/**
Expand Down Expand Up @@ -131,6 +132,8 @@ namespace mongo {
string &errmsg,
BSONObjBuilder &result,
bool fromRepl ) {
Lock::DBWrite dbXLock(db);
Client::Context ctx(db);

std::string profileFilename = cmdObj[commandName]["profileFilename"].String();
if ( ! ::ProfilerStart( profileFilename.c_str() ) ) {
Expand All @@ -146,6 +149,9 @@ namespace mongo {
string &errmsg,
BSONObjBuilder &result,
bool fromRepl ) {
Lock::DBWrite dbXLock(db);
Client::Context ctx(db);

::ProfilerStop();
return true;
}
Expand Down
2 changes: 1 addition & 1 deletion src/mongo/db/commands/create_indexes.cpp
Expand Up @@ -47,7 +47,7 @@ namespace mongo {
public:
CmdCreateIndex() : Command( "createIndexes" ){}

virtual LockType locktype() const { return NONE; }
virtual bool isWriteCommandForConfigServer() const { return false; }
virtual bool logTheOp() { return false; }
virtual bool slaveOk() const { return false; } // TODO: this could be made true...

Expand Down
3 changes: 3 additions & 0 deletions src/mongo/db/commands/dbhash.cpp
Expand Up @@ -146,6 +146,9 @@ namespace mongo {
}
}

const string ns = parseNs(dbname, cmdObj);
Client::ReadContext ctx(ns);

list<string> colls;
Database* db = cc().database();
if ( db )
Expand Down
2 changes: 1 addition & 1 deletion src/mongo/db/commands/dbhash.h
Expand Up @@ -46,7 +46,7 @@ namespace mongo {
DBHashCmd();

virtual bool slaveOk() const { return true; }
virtual LockType locktype() const { return READ; }
virtual bool isWriteCommandForConfigServer() const { return false; }
virtual void addRequiredPrivileges(const std::string& dbname,
const BSONObj& cmdObj,
std::vector<Privilege>* out);
Expand Down
4 changes: 3 additions & 1 deletion src/mongo/db/commands/distinct.cpp
Expand Up @@ -54,7 +54,7 @@ namespace mongo {

virtual bool slaveOk() const { return false; }
virtual bool slaveOverrideOk() const { return true; }
virtual LockType locktype() const { return READ; }
virtual bool isWriteCommandForConfigServer() const { return false; }

virtual void addRequiredPrivileges(const std::string& dbname,
const BSONObj& cmdObj,
Expand Down Expand Up @@ -90,6 +90,8 @@ namespace mongo {
long long nscannedObjects = 0; // full objects looked at
long long n = 0; // matches

Client::ReadContext ctx(ns);

Collection* collection = cc().database()->getCollection( ns );

if (!collection) {
Expand Down

0 comments on commit 1249034

Please sign in to comment.