mirror of
https://github.com/mongodb/mongo.git
synced 2024-12-01 09:32:32 +01:00
checkpoitn a little sync work
This commit is contained in:
parent
fbda5ee9bf
commit
8a26ff4f8d
@ -13,8 +13,38 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <boost/thread/shared_mutex.hpp>
|
||||
|
||||
namespace mongo {
|
||||
|
||||
#if 0
|
||||
typedef boost::shared_mutex MongoMutex;
|
||||
#else
|
||||
/* this will be for old versions of boost */
|
||||
class MongoMutex {
|
||||
boost::recursive_mutex m;
|
||||
public:
|
||||
void lock() {
|
||||
#if BOOST_VERSION >= 103500
|
||||
m.lock();
|
||||
#else
|
||||
boost::detail::thread::lock_ops<boost::recursive_mutex>::lock(m);
|
||||
#endif
|
||||
}
|
||||
|
||||
void unlock() {
|
||||
#if BOOST_VERSION >= 103500
|
||||
m.unlock();
|
||||
#else
|
||||
boost::detail::thread::lock_ops<boost::recursive_mutex>::unlock(m);
|
||||
#endif
|
||||
}
|
||||
|
||||
void lock_shared() { lock(); }
|
||||
void unlock_shared() { unlock(); }
|
||||
};
|
||||
#endif
|
||||
|
||||
/* mutex time stats */
|
||||
class MutexInfo {
|
||||
unsigned long long start, enter, timeLocked; // all in microseconds
|
||||
@ -45,9 +75,10 @@ namespace mongo {
|
||||
}
|
||||
};
|
||||
|
||||
extern boost::recursive_mutex &dbMutex;
|
||||
extern MongoMutex &dbMutex;
|
||||
extern MutexInfo dbMutexInfo;
|
||||
|
||||
/*
|
||||
struct lock {
|
||||
recursive_boostlock bl_;
|
||||
MutexInfo& info_;
|
||||
@ -60,46 +91,43 @@ namespace mongo {
|
||||
info_.leaving();
|
||||
}
|
||||
};
|
||||
*/
|
||||
|
||||
void dbunlocking_write();
|
||||
void dbunlocking_read();
|
||||
|
||||
/* use writelock and readlock instead */
|
||||
struct dblock : public lock {
|
||||
dblock() :
|
||||
lock( dbMutex, dbMutexInfo ) {
|
||||
}
|
||||
~dblock() {
|
||||
dbunlocking_write();
|
||||
}
|
||||
};
|
||||
|
||||
struct writelock : public lock {
|
||||
writelock(const string& ns) :
|
||||
lock( dbMutex, dbMutexInfo ) {
|
||||
}
|
||||
writelock(const char * ns) :
|
||||
lock( dbMutex, dbMutexInfo ) {
|
||||
struct writelock {
|
||||
writelock(const string& ns) {
|
||||
dbMutex.lock();
|
||||
dbMutexInfo.entered();
|
||||
}
|
||||
~writelock() {
|
||||
dbunlocking_write();
|
||||
dbMutexInfo.leaving();
|
||||
dbMutex.unlock();
|
||||
}
|
||||
};
|
||||
|
||||
struct readlock : public lock {
|
||||
readlock(const string& ns) :
|
||||
lock( dbMutex, dbMutexInfo ) {
|
||||
}
|
||||
readlock(const char* ns) :
|
||||
lock( dbMutex, dbMutexInfo ) {
|
||||
struct readlock {
|
||||
readlock(const string& ns) {
|
||||
dbMutex.lock_shared();
|
||||
}
|
||||
~readlock() {
|
||||
dbunlocking_read();
|
||||
dbMutex.unlock_shared();
|
||||
}
|
||||
};
|
||||
|
||||
/* use writelock and readlock instead */
|
||||
struct dblock : public writelock {
|
||||
dblock() : writelock("") { }
|
||||
~dblock() {
|
||||
}
|
||||
};
|
||||
|
||||
/* a scoped release of a mutex temporarily -- like a scopedlock but reversed.
|
||||
*/
|
||||
/*
|
||||
struct temprelease {
|
||||
boost::mutex& m;
|
||||
temprelease(boost::mutex& _m) : m(_m) {
|
||||
@ -117,6 +145,7 @@ namespace mongo {
|
||||
#endif
|
||||
}
|
||||
};
|
||||
*/
|
||||
|
||||
inline void assertInWriteLock() {
|
||||
assert( dbMutexInfo.isLocked() );
|
||||
|
11
db/db.cpp
11
db/db.cpp
@ -388,7 +388,7 @@ namespace mongo {
|
||||
sleepsecs(5);
|
||||
continue;
|
||||
}
|
||||
sleepmillis( _sleepsecs * 1000 );
|
||||
sleepmillis( (int)(_sleepsecs * 1000) );
|
||||
MemoryMappedFile::flushAll( false );
|
||||
log(1) << "flushing mmmap" << endl;
|
||||
}
|
||||
@ -1043,7 +1043,16 @@ BOOL CtrlHandler( DWORD fdwCtrlType )
|
||||
}
|
||||
#endif
|
||||
|
||||
void temptestfoo() {
|
||||
MongoMutex m;
|
||||
m.lock();
|
||||
// m.lock_upgrade();
|
||||
m.lock_shared();
|
||||
}
|
||||
|
||||
|
||||
} // namespace mongo
|
||||
|
||||
#include "recstore.h"
|
||||
#include "reccache.h"
|
||||
|
||||
|
8
db/db.h
8
db/db.h
@ -120,18 +120,10 @@ namespace mongo {
|
||||
}
|
||||
client.top.clientStop();
|
||||
dbMutexInfo.leaving();
|
||||
#if BOOST_VERSION >= 103500
|
||||
dbMutex.unlock();
|
||||
#else
|
||||
boost::detail::thread::lock_ops<boost::recursive_mutex>::unlock(dbMutex);
|
||||
#endif
|
||||
}
|
||||
~dbtemprelease() {
|
||||
#if BOOST_VERSION >= 103500
|
||||
dbMutex.lock();
|
||||
#else
|
||||
boost::detail::thread::lock_ops<boost::recursive_mutex>::lock(dbMutex);
|
||||
#endif
|
||||
dbMutexInfo.entered();
|
||||
if ( clientname.empty() )
|
||||
cc().setns("", 0);
|
||||
|
@ -49,7 +49,7 @@ namespace mongo {
|
||||
bool autoresync = false;
|
||||
|
||||
/* we use new here so we don't have to worry about destructor orders at program shutdown */
|
||||
boost::recursive_mutex &dbMutex( *(new boost::recursive_mutex) );
|
||||
MongoMutex &dbMutex( *(new MongoMutex) );
|
||||
MutexInfo dbMutexInfo;
|
||||
|
||||
string dbExecCommand;
|
||||
|
23
db/repl.cpp
23
db/repl.cpp
@ -48,7 +48,6 @@
|
||||
|
||||
namespace mongo {
|
||||
|
||||
extern boost::recursive_mutex &dbMutex;
|
||||
void ensureHaveIdIndex(const char *ns);
|
||||
|
||||
/* if 1 sync() is running */
|
||||
@ -1213,17 +1212,17 @@ namespace mongo {
|
||||
time_t saveLast = time(0);
|
||||
while ( 1 ) {
|
||||
/* from a.s.:
|
||||
I think the idea here is that we can establish a sync point between the local op log and the remote log with the following steps:
|
||||
|
||||
1) identify most recent op in local log -- call it O
|
||||
2) ask "does nextOpTime reflect the tail of the remote op log?" (in other words, is more() false?) - If yes, all subsequent ops after nextOpTime in the remote log must have occurred after O. If no, we can't establish a sync point.
|
||||
|
||||
Note that we can't do step (2) followed by step (1) because if we do so ops may be added to both machines between steps (2) and (1) and we can't establish a sync point. (In particular, between (2) and (1) an op may be added to the remote log before a different op is added to the local log. In this case, the newest remote op will have occurred after nextOpTime but before O.)
|
||||
|
||||
Now, for performance reasons we don't want to have to identify the most recent op in the local log every time we call c->more() because in performance sensitive situations more() will be true most of the time. So we do:
|
||||
|
||||
0) more()?
|
||||
1) find most recent op in local log
|
||||
I think the idea here is that we can establish a sync point between the local op log and the remote log with the following steps:
|
||||
|
||||
1) identify most recent op in local log -- call it O
|
||||
2) ask "does nextOpTime reflect the tail of the remote op log?" (in other words, is more() false?) - If yes, all subsequent ops after nextOpTime in the remote log must have occurred after O. If no, we can't establish a sync point.
|
||||
|
||||
Note that we can't do step (2) followed by step (1) because if we do so ops may be added to both machines between steps (2) and (1) and we can't establish a sync point. (In particular, between (2) and (1) an op may be added to the remote log before a different op is added to the local log. In this case, the newest remote op will have occurred after nextOpTime but before O.)
|
||||
|
||||
Now, for performance reasons we don't want to have to identify the most recent op in the local log every time we call c->more() because in performance sensitive situations more() will be true most of the time. So we do:
|
||||
|
||||
0) more()?
|
||||
1) find most recent op in local log
|
||||
2) more()?
|
||||
*/
|
||||
if ( !c->more() ) {
|
||||
|
Loading…
Reference in New Issue
Block a user