summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordwight <dwight@Dwights-MacBook-2.local>2009-08-17 16:13:13 -0400
committerdwight <dwight@Dwights-MacBook-2.local>2009-08-17 16:13:13 -0400
commit4120dfc5684dca008c6c0cef64b2d9ff7ed3d158 (patch)
tree15554e60aa203b636261ddd9b7527863785a0057
parent8a145572a5b015825568a5705ddf9c78f1d04730 (diff)
downloadmongo-4120dfc5684dca008c6c0cef64b2d9ff7ed3d158.tar.gz
fix checks that operations cannot be performed on slaves; also, allow read operations on
--slave instances (but not repl pair nonmasters)
-rw-r--r--db/db.cpp4
-rw-r--r--db/dbcommands.cpp3
-rw-r--r--db/instance.cpp5
-rw-r--r--db/query.cpp8
-rw-r--r--db/repl.cpp7
-rw-r--r--db/repl.h4
-rw-r--r--db/replset.h2
-rw-r--r--shell/db.js1
8 files changed, 21 insertions, 13 deletions
diff --git a/db/db.cpp b/db/db.cpp
index 4ac096696ab..3fdfdbb2625 100644
--- a/db/db.cpp
+++ b/db/db.cpp
@@ -360,7 +360,7 @@ namespace mongo {
bool is32bit = sizeof(int*) == 4;
log() << "Mongo DB : starting : pid = " << pid << " port = " << port << " dbpath = " << dbpath
- << " master = " << master << " slave = " << slave << " " << ( is32bit ? "32" : "64" ) << "-bit " << endl;
+ << " master = " << master << " slave = " << (int) slave << " " << ( is32bit ? "32" : "64" ) << "-bit " << endl;
show_32_warning();
@@ -670,7 +670,7 @@ int main(int argc, char* argv[], char *envp[] )
master = true;
}
if (params.count("slave")) {
- slave = true;
+ slave = SimpleSlave;
}
if (params.count("source")) {
/* specifies what the source in local.sources should be */
diff --git a/db/dbcommands.cpp b/db/dbcommands.cpp
index 0c72bdf5319..0a57387e1c2 100644
--- a/db/dbcommands.cpp
+++ b/db/dbcommands.cpp
@@ -630,7 +630,8 @@ namespace mongo {
return false;
}
virtual bool slaveOk() {
- return false;
+ // ok on --slave setups, not ok for nonmaster of a repl pair (unless override)
+ return slave == SimpleSlave;
}
virtual bool slaveOverrideOk() {
return true;
diff --git a/db/instance.cpp b/db/instance.cpp
index a63799a8cbf..959460e0a7c 100644
--- a/db/instance.cpp
+++ b/db/instance.cpp
@@ -41,7 +41,7 @@ namespace mongo {
#define LOGSOME if( ++nloggedsome < 1000 || nloggedsome % 100 == 0 )
bool quota = false;
- bool slave = false;
+ SlaveTypes slave = NotSlave;
bool master = false; // true means keep an op log
extern int curOp;
bool autoresync = false;
@@ -377,9 +377,6 @@ namespace mongo {
}
}
- // Check before setClient() to avoid creating ns unnecessarily.
- uassert( "not master", isMasterNs( q.ns ) || (q.queryOptions & Option_SlaveOk) || strstr( q.ns, ".$cmd" ) );
-
setClient( q.ns );
Top::setRead();
strncpy(currentOp.ns, q.ns, Namespace::MaxNsLen);
diff --git a/db/query.cpp b/db/query.cpp
index 7051ad68fb3..7fdf3197bdd 100644
--- a/db/query.cpp
+++ b/db/query.cpp
@@ -1355,8 +1355,12 @@ namespace mongo {
AuthenticationInfo *ai = authInfo.get();
uassert("unauthorized", ai->isAuthorized(database->name.c_str()));
-
- uassert( "not master", isMaster() || (queryOptions & Option_SlaveOk) );
+
+ /* we allow queries to SimpleSlave's -- but not to the slave (nonmaster) member of a replica pair
+ so that queries to a pair are realtime consistent as much as possible. use setSlaveOk() to
+ query the nonmaster member of a replica pair.
+ */
+ uassert( "not master", isMaster() || (queryOptions & Option_SlaveOk) || slave == SimpleSlave );
BSONElement hint;
BSONObj min;
diff --git a/db/repl.cpp b/db/repl.cpp
index d00da01dd6a..05b8673cc70 100644
--- a/db/repl.cpp
+++ b/db/repl.cpp
@@ -1651,9 +1651,12 @@ namespace mongo {
}
if ( slave || replPair ) {
- if ( slave )
+ if ( slave ) {
+ assert( slave == SimpleSlave );
log(1) << "slave=true" << endl;
- slave = true;
+ }
+ else
+ slave = ReplPairSlave;
boost::thread repl_thread(replSlaveThread);
}
diff --git a/db/repl.h b/db/repl.h
index dfba8185670..10ebc67de85 100644
--- a/db/repl.h
+++ b/db/repl.h
@@ -41,7 +41,9 @@ namespace mongo {
class DBClientConnection;
class DBClientCursor;
- extern bool slave;
+ // --slave = SimpleSlave
+ typedef enum { NotSlave=0, SimpleSlave, ReplPairSlave } SlaveTypes;
+ extern SlaveTypes slave;
extern bool master;
extern int opIdMem;
diff --git a/db/replset.h b/db/replset.h
index 686c71157e2..71b94f33f8e 100644
--- a/db/replset.h
+++ b/db/replset.h
@@ -112,7 +112,7 @@ namespace mongo {
inline bool isMaster( const char *client = 0 ) {
if ( !client )
client = database->name.c_str();
- if ( replAllDead ) {
+ if ( replAllDead || slave ) {
return strcmp( client, "local" ) == 0;
}
diff --git a/shell/db.js b/shell/db.js
index be5150bdbb4..0272baf9dff 100644
--- a/shell/db.js
+++ b/shell/db.js
@@ -239,6 +239,7 @@ DB.prototype.help = function() {
print("DB methods:");
print("\tdb.auth(username, password)");
print("\tdb.getMongo() get the server connection object");
+ print("\tdb.getMongo().setSlaveOk() allow this connection to read from the nonmaster member of a replica pair");
print("\tdb.getSisterDB(name) get the db at the same server as this onew");
print("\tdb.getName()");
print("\tdb.getCollection(cname) same as db['cname'] or db.cname");