Skip to content

Commit 447c9df

Browse files
committed
SERVER-705 check for negative effects of large clock skews, seed last optime using oplog
1 parent 063f651 commit 447c9df

File tree

6 files changed

+37
-6
lines changed

6 files changed

+37
-6
lines changed

db/db.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -943,13 +943,13 @@ namespace mongo {
943943

944944
#undef out
945945

946-
void exitCleanly() {
946+
void exitCleanly( ExitCode code ) {
947947
goingAway = true;
948948
killCurrentOp = 1;
949949
{
950950
dblock lk;
951951
log() << "now exiting" << endl;
952-
dbexit( EXIT_KILL );
952+
dbexit( code );
953953
}
954954
}
955955

@@ -995,7 +995,7 @@ namespace mongo {
995995
int x;
996996
sigwait( &asyncSignals, &x );
997997
log() << "got kill or ctrl c signal " << x << " (" << strsignal( x ) << "), will terminate after current cmd ends" << endl;
998-
exitCleanly();
998+
exitCleanly( EXIT_KILL );
999999
}
10001000

10011001
void setupSignals() {
@@ -1018,7 +1018,7 @@ namespace mongo {
10181018
#else
10191019
void ctrlCTerminate() {
10201020
log() << "got kill or ctrl c signal, will terminate after current cmd ends" << endl;
1021-
exitCleanly();
1021+
exitCleanly( EXIT_KILL );
10221022
}
10231023
BOOL CtrlHandler( DWORD fdwCtrlType )
10241024
{

db/db.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,8 @@ namespace mongo {
129129
}
130130
};
131131

132+
void exitCleanly( ExitCode code );
133+
132134
} // namespace mongo
133135

134136
#include "dbinfo.h"

db/instance.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,9 @@ namespace mongo {
262262
ss << " exception " + e.toString();
263263
log = true;
264264
}
265+
catch ( ClockSkewException &e ) {
266+
exitCleanly( EXIT_CLOCK_SKEW );
267+
}
265268
}
266269
else if ( op == dbKillCursors ) {
267270
OPREAD;

db/repl.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1644,8 +1644,14 @@ namespace mongo {
16441644
const char * ns = "local.oplog.$main";
16451645
setClient(ns);
16461646

1647-
if ( nsdetails( ns ) )
1647+
if ( nsdetails( ns ) ) {
1648+
DBDirectClient c;
1649+
BSONObj lastOp = c.findOne( ns, Query().sort( BSON( "$natural" << -1 ) ) );
1650+
if ( !lastOp.isEmpty() ) {
1651+
OpTime::setLast( lastOp[ "ts" ].date() );
1652+
}
16481653
return;
1654+
}
16491655

16501656
/* create an oplog collection, if it doesn't yet exist. */
16511657
BSONObjBuilder b;

stdafx.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ namespace mongo {
5353
EXIT_OOM_MALLOC = 42 ,
5454
EXIT_OOM_REALLOC = 43 ,
5555
EXIT_FS = 45 ,
56+
EXIT_CLOCK_SKEW = 47 ,
5657
EXIT_POSSIBLE_CORRUPTION = 60 , // this means we detected a possible corruption situation, like a buf overflow
5758
EXIT_UNCAUGHT = 100 , // top level exception that wasn't caught
5859
EXIT_TEST = 101 ,

util/optime.h

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,24 @@
2020
#include "../db/concurrency.h"
2121

2222
namespace mongo {
23+
void exitCleanly( int code );
2324

2425
/* Operation sequence #. A combination of current second plus an ordinal value.
2526
*/
27+
struct ClockSkewException : public DBException {
28+
virtual const char* what() const throw() { return "clock skew exception"; }
29+
virtual int getCode(){ return 20001; }
30+
};
31+
2632
#pragma pack(4)
2733
class OpTime {
2834
unsigned i;
2935
unsigned secs;
3036
static OpTime last;
3137
public:
38+
static void setLast(const Date_t &date) {
39+
last = OpTime(date);
40+
}
3241
unsigned getSecs() const {
3342
return secs;
3443
}
@@ -47,7 +56,17 @@ namespace mongo {
4756
unsigned t = (unsigned) time(0);
4857
// DEV assertInWriteLock();
4958
if ( t < last.secs ){
50-
log() << "clock skew detected prev: " << last.secs << " now: " << t << " trying to handle..." << endl;
59+
bool toLog = false;
60+
ONCE toLog = true;
61+
RARELY toLog = true;
62+
if ( last.i & 0x80000000 )
63+
toLog = true;
64+
if ( toLog )
65+
log() << "clock skew detected prev: " << last.secs << " now: " << t << " trying to handle..." << endl;
66+
if ( last.i & 0x80000000 ) {
67+
log() << "ERROR Large clock skew detected, shutting down" << endl;
68+
throw ClockSkewException();
69+
}
5170
t = last.secs;
5271
}
5372
if ( last.secs == t ) {

0 commit comments

Comments
 (0)