Permalink
Browse files

SERVER-12035 Add "oplog" section to serverStatus output

  • Loading branch information...
1 parent 192f4bc commit 6105f6aa2408ff6f2f95e302e3e39adff51867c8 @stbrody stbrody committed Dec 30, 2013
View
@@ -0,0 +1,51 @@
+// Tests tracking of latestOptime and earliestOptime in serverStatus.oplog
+
+function optimesAreEqual(replTest) {
+ var prevStatus = replTest.nodes[0].getDB('admin').serverStatus({oplog:true}).oplog;
+ for (var i = 1; i < replTest.nodes.length; i++) {
+ var status = replTest.nodes[i].getDB('admin').serverStatus({oplog:true}).oplog;
+ if (!friendlyEqual(prevStatus.latestOptime, status.latestOptime) ||
+ !friendlyEqual(prevStatus.earliestOptime, status.earliestOptime)) {
+ return false;
+ }
+ prevStatus = status;
+ }
+ return true;
+}
+
+var replTest = new ReplSetTest( { name : "replStatus" , nodes: 3, oplogSize: 1 } );
+
+replTest.startSet();
+replTest.initiate();
+var master = replTest.getMaster();
+replTest.awaitReplication();
+replTest.awaitSecondaryNodes();
+
+// Check initial optimes
+assert(optimesAreEqual(replTest));
+var initialInfo = master.getDB('admin').serverStatus({oplog:true}).oplog;
+
+// Do an insert to increment optime, but without rolling the oplog
+// latestOptime should be updated, but earliestOptime should be unchanged
+master.getDB('test').foo.insert({a:1});
+master.getDB('test').getLastError(replTest.nodes.length);
+assert(optimesAreEqual(replTest));
+
+var info = master.getDB('admin').serverStatus({oplog:true}).oplog;
+assert.gt(info.latestOptime, initialInfo.latestOptime);
+assert.eq(info.earliestOptime, initialInfo.earliestOptime);
+
+// Insert some large documents to force the oplog to roll over
+var largeString = new Array(1024*100).toString();
+for (var i = 0; i < 15; i++) {
+ master.getDB('test').foo.insert({largeString: largeString});
+ master.getDB('test').getLastError(replTest.nodes.length);
+}
+assert(optimesAreEqual(replTest));
+
+// Test that earliestOptime was updated
+info = master.getDB('admin').serverStatus({oplog:true}).oplog;
+assert.gt(info.latestOptime, initialInfo.latestOptime);
+assert.gt(info.earliestOptime, initialInfo.earliestOptime);
+
+replTest.stopSet();
@@ -153,6 +153,24 @@ namespace mongo {
}
} replicationInfoServerStatus;
+ class OplogInfoServerStatus : public ServerStatusSection {
+ public:
+ OplogInfoServerStatus() : ServerStatusSection( "oplog" ){}
+ bool includeByDefault() const { return false; }
+
+ BSONObj generateSection(const BSONElement& configElement) const {
+ if (!theReplSet)
+ return BSONObj();
+
+ BSONObjBuilder result;
+ result.appendTimestamp("latestOptime", theReplSet->lastOpTimeWritten.asDate());
+ result.appendTimestamp("earliestOptime",
+ theReplSet->getEarliestOpTimeWritten().asDate());
+
+ return result.obj();
+ }
+ } oplogInfoServerStatus;
+
class CmdIsMaster : public Command {
public:
virtual bool requiresAuth() { return false; }
View
@@ -511,6 +511,13 @@ namespace {
}
}
+ OpTime ReplSetImpl::getEarliestOpTimeWritten() const {
+ Lock::DBRead lk(rsoplog);
+ BSONObj o;
+ uassert(17347, "Problem reading earliest entry from oplog", Helpers::getFirst(rsoplog, o));
+ return o["ts"]._opTime();
+ }
+
/* call after constructing to start - returns fairly quickly after launching its threads */
void ReplSetImpl::_go() {
{
View
@@ -367,6 +367,8 @@ namespace mongo {
SyncSourceFeedback syncSourceFeedback;
OpTime lastOpTimeWritten;
+ OpTime getEarliestOpTimeWritten() const;
+
long long lastH; // hash we use to make sure we are reading the right flow of ops and aren't on an out-of-date "fork"
bool forceSyncFrom(const string& host, string& errmsg, BSONObjBuilder& result);
// Check if the current sync target is suboptimal. This must be called while holding a mutex

0 comments on commit 6105f6a

Please sign in to comment.