0
0
mirror of https://github.com/mongodb/mongo.git synced 2024-12-01 09:32:32 +01:00

rs towards rollback

This commit is contained in:
dwight 2010-07-23 15:48:30 -04:00
parent 87b68a4ebe
commit 30d823b628
3 changed files with 50 additions and 10 deletions

View File

@ -25,6 +25,7 @@
namespace mongo {
/* lifespan is different than CurOp because of recursives with DBDirectClient */
class OpDebug {
public:
StringBuilder str;

View File

@ -99,8 +99,7 @@ namespace mongo {
static void putSingleton(const char *ns, BSONObj obj);
static void putSingletonGod(const char *ns, BSONObj obj, bool logTheOp);
static bool getFirst(const char *ns, BSONObj& result) { return getSingleton(ns, result); }
static bool getLast(const char *ns, BSONObj& result); // get last object int he collection; e.g. {$natural : -1}
static bool getLast(const char *ns, BSONObj& result); // get last object int he collection; e.g. {$natural : -1}
/**
* you have to lock
@ -122,7 +121,7 @@ namespace mongo {
virtual ~RemoveCallback(){}
virtual void goingToDelete( const BSONObj& o ) = 0;
};
/* removeRange: operation is oplog'd */
static long long removeRange( const string& ns , const BSONObj& min , const BSONObj& max , bool yield = false , bool maxInclusive = false , RemoveCallback * callback = 0 );
/* Remove all objects from a collection.

View File

@ -20,6 +20,7 @@
#include "../../client/dbclient.h"
#include "rs.h"
#include "../repl.h"
#include "../query.h"
/* Scenarios
@ -136,8 +137,15 @@ namespace mongo {
void ReplSetImpl::syncFixUp(HowToFixUp& h, DBClientConnection *them) {
// fetch all first so we aren't interrupted.
unsigned long long totSize = 0;
map</*the _id*/be,bo> items;
struct X {
const bo *op;
bo goodVersionOfObject;
};
map</*the _id field*/be,X> items;
for( list<bo>::iterator i = h.toRefetch.begin(); i != h.toRefetch.end(); i++ ) {
const bo& o = *i;
@ -146,6 +154,7 @@ namespace mongo {
be _id = o["_id"];
if( _id.eoo() ) {
/* todo1.6? */
log() << "replSet sync item in oplog has no _id; skipping. " << i->toString() << rsLog;
continue;
}
@ -153,24 +162,57 @@ namespace mongo {
continue;
{
/* TODO : slow. lots of round trips. */
string ns = o["ns"].String();
bo goodVersion = them->findOne(ns, bob().append(_id).done());
totSize += goodVersion.objsize();
X x;
x.op = &o;
x.goodVersionOfObject = them->findOne(ns, bob().append(_id).done()).getOwned();
totSize += x.goodVersionOfObject.objsize();
uassert( 13410, "replSet too much data to roll back", totSize < 200 * 1024 * 1024 );
// note result might be eoo, indicating we should delete.
items.insert(pair<be,bo>(_id, goodVersion.getOwned()));
items.insert(pair<be,X>(_id, x));
}
}
// update them
sethbmsg(str::stream() << "syncRollback 4 n:" << h.toRefetch.size());
for( map<be,bo>::iterator i = items.begin(); i != items.end(); i++ ) {
bool warn = false;
{
writelock lk("");
for( map<be,X>::iterator i = items.begin(); i != items.end(); i++ ) {
bo pattern = i->first.wrap(); // { _id : ... }
X& x = i->second;
const char *ns = x.op->getStringField("ns");
try {
assert( *ns );
// todo: lots of overhead in context, this can be faster
Client::Context c(ns, dbpath, 0, /*doauth*/false);
if( x.goodVersionOfObject.isEmpty() ) {
// wasn't on the primary; delete.
/* TODO1.6 : can't delete from a capped collection. need to handle that here. */
deleteObjects(ns, pattern, /*justone*/true, /*logop*/false, /*god*/true);
}
else {
// todo faster...
OpDebug debug;
_updateObjects(/*god*/true, ns, x.goodVersionOfObject, pattern, /*upsert=*/true, /*multi=*/false , /*logtheop=*/false , debug);
}
}
catch(DBException& e) {
log() << "replSet exception in rollback ns:" << ns << ' ' << pattern.toString() << ' ' << e.toString() << rsLog;
warn = true;
}
}
}
// clean up oplog
if( warn )
sethbmsg("issues during syncRollback, see log");
else
sethbmsg("syncRollback done");
}
void ReplSetImpl::syncRollback(OplogReader&r) {
@ -206,8 +248,6 @@ namespace mongo {
sethbmsg("replSet syncRollback 3");
syncFixUp(how, r.conn());
sethbmsg("replSet syncRollback FINISH");
}
}