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:
parent
87b68a4ebe
commit
30d823b628
@ -25,6 +25,7 @@
|
||||
|
||||
namespace mongo {
|
||||
|
||||
/* lifespan is different than CurOp because of recursives with DBDirectClient */
|
||||
class OpDebug {
|
||||
public:
|
||||
StringBuilder str;
|
||||
|
@ -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.
|
||||
|
@ -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");
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user