summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAaron <aaron@10gen.com>2010-03-08 12:55:18 -0800
committerAaron <aaron@10gen.com>2010-03-09 10:00:18 -0800
commit447c9df927ded60e696086e98c1ca6a15b207756 (patch)
tree98b2ccc573da23b56cd8cbde729f128f15033bd2
parent063f651c6bcaa321ad2cb9bc534b724ce60aef6a (diff)
downloadmongo-447c9df927ded60e696086e98c1ca6a15b207756.tar.gz
SERVER-705 check for negative effects of large clock skews, seed last optime using oplog
-rw-r--r--db/db.cpp8
-rw-r--r--db/db.h2
-rw-r--r--db/instance.cpp3
-rw-r--r--db/repl.cpp8
-rw-r--r--stdafx.h1
-rw-r--r--util/optime.h21
6 files changed, 37 insertions, 6 deletions
diff --git a/db/db.cpp b/db/db.cpp
index f8f1d10bcfd..489287d2773 100644
--- a/db/db.cpp
+++ b/db/db.cpp
@@ -943,13 +943,13 @@ namespace mongo {
#undef out
- void exitCleanly() {
+ void exitCleanly( ExitCode code ) {
goingAway = true;
killCurrentOp = 1;
{
dblock lk;
log() << "now exiting" << endl;
- dbexit( EXIT_KILL );
+ dbexit( code );
}
}
@@ -995,7 +995,7 @@ namespace mongo {
int x;
sigwait( &asyncSignals, &x );
log() << "got kill or ctrl c signal " << x << " (" << strsignal( x ) << "), will terminate after current cmd ends" << endl;
- exitCleanly();
+ exitCleanly( EXIT_KILL );
}
void setupSignals() {
@@ -1018,7 +1018,7 @@ namespace mongo {
#else
void ctrlCTerminate() {
log() << "got kill or ctrl c signal, will terminate after current cmd ends" << endl;
- exitCleanly();
+ exitCleanly( EXIT_KILL );
}
BOOL CtrlHandler( DWORD fdwCtrlType )
{
diff --git a/db/db.h b/db/db.h
index b8369e9d795..ed0a6982148 100644
--- a/db/db.h
+++ b/db/db.h
@@ -129,6 +129,8 @@ namespace mongo {
}
};
+ void exitCleanly( ExitCode code );
+
} // namespace mongo
#include "dbinfo.h"
diff --git a/db/instance.cpp b/db/instance.cpp
index 6b83ba4a0ad..83cf0be4271 100644
--- a/db/instance.cpp
+++ b/db/instance.cpp
@@ -262,6 +262,9 @@ namespace mongo {
ss << " exception " + e.toString();
log = true;
}
+ catch ( ClockSkewException &e ) {
+ exitCleanly( EXIT_CLOCK_SKEW );
+ }
}
else if ( op == dbKillCursors ) {
OPREAD;
diff --git a/db/repl.cpp b/db/repl.cpp
index 331dd12fbcf..d6778f116fe 100644
--- a/db/repl.cpp
+++ b/db/repl.cpp
@@ -1644,8 +1644,14 @@ namespace mongo {
const char * ns = "local.oplog.$main";
setClient(ns);
- if ( nsdetails( ns ) )
+ if ( nsdetails( ns ) ) {
+ DBDirectClient c;
+ BSONObj lastOp = c.findOne( ns, Query().sort( BSON( "$natural" << -1 ) ) );
+ if ( !lastOp.isEmpty() ) {
+ OpTime::setLast( lastOp[ "ts" ].date() );
+ }
return;
+ }
/* create an oplog collection, if it doesn't yet exist. */
BSONObjBuilder b;
diff --git a/stdafx.h b/stdafx.h
index 5352c5e4d58..fb7a630e2fc 100644
--- a/stdafx.h
+++ b/stdafx.h
@@ -53,6 +53,7 @@ namespace mongo {
EXIT_OOM_MALLOC = 42 ,
EXIT_OOM_REALLOC = 43 ,
EXIT_FS = 45 ,
+ EXIT_CLOCK_SKEW = 47 ,
EXIT_POSSIBLE_CORRUPTION = 60 , // this means we detected a possible corruption situation, like a buf overflow
EXIT_UNCAUGHT = 100 , // top level exception that wasn't caught
EXIT_TEST = 101 ,
diff --git a/util/optime.h b/util/optime.h
index 4e523a6409c..de4465e2bbe 100644
--- a/util/optime.h
+++ b/util/optime.h
@@ -20,15 +20,24 @@
#include "../db/concurrency.h"
namespace mongo {
+ void exitCleanly( int code );
/* Operation sequence #. A combination of current second plus an ordinal value.
*/
+ struct ClockSkewException : public DBException {
+ virtual const char* what() const throw() { return "clock skew exception"; }
+ virtual int getCode(){ return 20001; }
+ };
+
#pragma pack(4)
class OpTime {
unsigned i;
unsigned secs;
static OpTime last;
public:
+ static void setLast(const Date_t &date) {
+ last = OpTime(date);
+ }
unsigned getSecs() const {
return secs;
}
@@ -47,7 +56,17 @@ namespace mongo {
unsigned t = (unsigned) time(0);
// DEV assertInWriteLock();
if ( t < last.secs ){
- log() << "clock skew detected prev: " << last.secs << " now: " << t << " trying to handle..." << endl;
+ bool toLog = false;
+ ONCE toLog = true;
+ RARELY toLog = true;
+ if ( last.i & 0x80000000 )
+ toLog = true;
+ if ( toLog )
+ log() << "clock skew detected prev: " << last.secs << " now: " << t << " trying to handle..." << endl;
+ if ( last.i & 0x80000000 ) {
+ log() << "ERROR Large clock skew detected, shutting down" << endl;
+ throw ClockSkewException();
+ }
t = last.secs;
}
if ( last.secs == t ) {