Compare commits

...

13 Commits

Author SHA1 Message Date
Ernie Hershey
0958c93e36 post 2.2.7 2014-01-16 13:46:01 -05:00
Ernie Hershey
6c2023ca35 BUMP 2.2.7 2014-01-12 16:19:10 -05:00
Ernie Hershey
80f87a4de2 post 2.2.7-rc0 2014-01-09 17:30:09 -05:00
Dan Pasette
4f10984648 BUMP 2.2.7-rc0 2014-01-06 23:11:09 -05:00
Dan Pasette
307fb42c66 SERVER-12146 do not check writebacks if calling gle from wbl 2014-01-06 10:29:47 -05:00
matt dannenberg
9c9bbd9eeb SERVER-10538 SERVER-11731 change segfault to uassert on improper use of $where 2013-12-09 14:37:37 -05:00
Eric Milkie
be66f1b8fc SERVER-9339 do not query a node that is not in PRIMARY or SECONDARY state 2013-08-29 16:02:29 -04:00
Eric Milkie
0364ef4bdd SERVER-9339 ensure all rollback update/delete paths are recorded
Conflicts:
	src/mongo/db/ops/update.cpp
2013-08-29 16:02:08 -04:00
Ernie Hershey
e62a094fd0 post 2.2.6 2013-08-20 16:03:23 -04:00
Dan Pasette
d626379119 BUMP 2.2.6 2013-08-18 14:42:54 -04:00
Greg Studer
300a2288f2 SERVER-10498 gle_error_message.js sleep 2 secs for reconnect threshold to reset 2013-08-15 18:50:56 -04:00
Ernie Hershey
10a0a5b2e6 post 2.2.6-rc0 2013-08-13 17:50:00 -04:00
Greg Studer
6a896217f9 SERVER-10498 print conn pool stats and ensure migration succeeds before testing error 2013-08-13 15:20:15 -04:00
12 changed files with 170 additions and 44 deletions

View File

@@ -3,7 +3,7 @@
#---------------------------------------------------------------------------
DOXYFILE_ENCODING = UTF-8
PROJECT_NAME = MongoDB
PROJECT_NUMBER = 2.2.6-rc0
PROJECT_NUMBER = 2.2.8-pre-
OUTPUT_DIRECTORY = docs/doxygen
CREATE_SUBDIRS = NO
OUTPUT_LANGUAGE = English

View File

@@ -0,0 +1,102 @@
// test that a rollback directory is created during a replica set rollback
// this also tests that updates are recorded in the rollback file
// (this test does no delete rollbacks)
var replTest = new ReplSetTest({ name: 'rollback5', nodes: 3 });
var nodes = replTest.nodeList();
var conns = replTest.startSet();
var r = replTest.initiate({ "_id": "rollback5",
"members": [
{ "_id": 0, "host": nodes[0] },
{ "_id": 1, "host": nodes[1] },
{ "_id": 2, "host": nodes[2], arbiterOnly: true}]
});
// Make sure we have a master
var master = replTest.getMaster();
var a_conn = conns[0];
var b_conn = conns[1];
a_conn.setSlaveOk();
b_conn.setSlaveOk();
var A = a_conn.getDB("test");
var B = b_conn.getDB("test");
var AID = replTest.getNodeId(a_conn);
var BID = replTest.getNodeId(b_conn);
var Apath = "/data/db/rollback5-0/";
var Bpath = "/data/db/rollback5-1/";
assert(master == conns[0], "conns[0] assumed to be master");
assert(a_conn.host == master.host);
// Make sure we have an arbiter
assert.soon(function () {
res = conns[2].getDB("admin").runCommand({ replSetGetStatus: 1 });
return res.myState == 7;
}, "Arbiter failed to initialize.");
A.foo.update({key:'value1'}, {$set: {req: 'req'}}, true);
A.foo.runCommand({getLastError : 1, w : 2, wtimeout : 60000});
replTest.stop(AID);
master = replTest.getMaster();
assert(b_conn.host == master.host);
B.foo.update({key:'value1'}, {$set: {res: 'res'}}, true);
B.foo.runCommand({getLastError : 1, w : 1, wtimeout : 60000});
replTest.stop(BID);
replTest.restart(AID);
master = replTest.getMaster();
assert(a_conn.host == master.host);
A.foo.update({key:'value2'}, {$set: {req: 'req'}}, true);
A.foo.runCommand({getLastError : 1, w : 1, wtimeout : 60000});
replTest.restart(BID); // should rollback
reconnect(B);
print("BEFORE------------------");
printjson(A.foo.find().toArray());
replTest.awaitReplication();
replTest.awaitSecondaryNodes();
print("AFTER------------------");
printjson(A.foo.find().toArray());
assert.eq(2, A.foo.count());
assert.eq('req', A.foo.findOne({key:'value1'}).req);
assert.eq(null, A.foo.findOne({key:'value1'}).res);
assert.eq(2, B.foo.count());
assert.eq('req', B.foo.findOne({key:'value1'}).req);
assert.eq(null, B.foo.findOne({key:'value1'}).res);
// check here for rollback files
var rollbackDir = Bpath + "rollback/";
assert(pathExists(rollbackDir), "rollback directory was not created!");
print("rollback5.js SUCCESS");
replTest.stopSet(15);
function wait(f) {
var n = 0;
while (!f()) {
if (n % 4 == 0)
print("rollback5.js waiting");
if (++n == 4) {
print("" + f);
}
assert(n < 200, 'tried 200 times, giving up');
sleep(1000);
}
}
function reconnect(a) {
wait(function() {
try {
a.bar.stats();
return true;
} catch(e) {
print(e);
return false;
}
});
};

View File

@@ -111,7 +111,11 @@ jsTest.log( "Testing stale version GLE when host goes down..." )
var staleColl = st.s1.getCollection( coll + "" )
staleColl.findOne()
printjson( admin.runCommand({ moveChunk : "" + coll, find : { _id : 0 }, to : shards[2]._id }) )
// As it turns out, on the *second* auto-reconnect attempt we need to wait at least 2 secs,
// otherwise reconnect fails with FAILED_STATE
sleep( 2000 );
assert( admin.runCommand({ moveChunk : "" + coll, find : { _id : 0 }, to : shards[2]._id }).ok );
MongoRunner.stopMongod( st.shard2 )
@@ -124,4 +128,4 @@ assert.neq( null, staleColl.getDB().getLastError() )
jsTest.log( "Done!" )
st.stop()
st.stop()

View File

@@ -380,7 +380,6 @@ namespace mongo {
stringstream ss;
ss << why << "." << terseCurrentTime(false) << "." << NUM++ << ".bson";
_file /= ss.str();
}
RemoveSaver::~RemoveSaver() {
@@ -397,7 +396,8 @@ namespace mongo {
_out = new ofstream();
_out->open( _file.string().c_str() , ios_base::out | ios_base::binary );
if ( ! _out->good() ) {
LOG( LL_WARNING ) << "couldn't create file: " << _file.string() << " for remove saving" << endl;
error() << "couldn't create file: " << _file.string() <<
" for remove saving" << endl;
delete _out;
_out = 0;
return;

View File

@@ -465,6 +465,8 @@ namespace mongo {
uassert( 10066 , "$where may only appear once in query", _where == 0 );
uassert( 10067 , "$where query, but no script engine", globalScriptEngine );
massert( 13089 , "no current client needed for $where" , haveClient() );
uassert( 17126 , "no valid context found for $where", cc().getContext());
_where = new Where( cc().ns() );
if ( e.type() == CodeWScope ) {

View File

@@ -129,9 +129,6 @@ namespace mongo {
}
}
if ( rs )
rs->goingToDelete( rloc.obj() /*cc->c->current()*/ );
theDataFileMgr.deleteRecord(ns, rloc.rec(), rloc);
nDeleted++;
if ( foundAllResults ) {

View File

@@ -364,9 +364,6 @@ namespace mongo {
d->paddingFits();
}
else {
if ( rs )
rs->goingToDelete( onDisk );
BSONObj newObj = mss->createNewFromMods();
checkTooLarge(newObj);
DiskLoc newLoc = theDataFileMgr.updateRecord(ns,

View File

@@ -465,6 +465,16 @@ namespace mongo {
// todo: lots of overhead in context, this can be faster
Client::Context c(d.ns);
// Add the doc to our rollback file
BSONObj obj;
bool found = Helpers::findOne(d.ns, pattern, obj, false);
if ( found ) {
rs->goingToDelete( obj );
} else {
error() << "rollback cannot find object by id" << endl;
}
if( i->second.isEmpty() ) {
// wasn't on the primary; delete.
/* TODO1.6 : can't delete from a capped collection. need to handle that here. */

View File

@@ -227,41 +227,39 @@ namespace mongo {
}
clearSinceLastGetError();
LOG(4) << "checking " << writebacks.size() << " writebacks for"
<< " gle (" << theShard << ")" << endl;
// We never need to handle writebacks if we're coming from the wbl itself
if ( writebacks.size() && !fromWriteBackListener ){
if ( writebacks.size() ){
vector<BSONObj> v = _handleWriteBacks( writebacks , fromWriteBackListener );
if ( v.size() == 0 && fromWriteBackListener ) {
// ok
LOG(4) << "checking " << writebacks.size() << " writebacks for"
<< " gle (" << theShard << ")" << endl;
vector<BSONObj> v = _handleWriteBacks( writebacks , false );
// this will usually be 1
// it can be greater than 1 if a write to a different shard
// than the last write op had a writeback
// all we're going to report is the first
// since that's the current write
// but we block for all
verify( v.size() >= 1 );
if ( res["writebackSince"].numberInt() > 0 ) {
// got writeback from older op
// ignore the result from it, just needed to wait
result.appendElements( res );
}
else if ( writebacks[0].fromLastOperation ) {
result.appendElements( v[0] );
result.appendElementsUnique( res );
result.append( "writebackGLE" , v[0] );
result.append( "initialGLEHost" , theShard );
result.append( "initialGLE", res );
}
else {
// this will usually be 1
// it can be greater than 1 if a write to a different shard
// than the last write op had a writeback
// all we're going to report is the first
// since that's the current write
// but we block for all
verify( v.size() >= 1 );
if ( res["writebackSince"].numberInt() > 0 ) {
// got writeback from older op
// ignore the result from it, just needed to wait
result.appendElements( res );
}
else if ( writebacks[0].fromLastOperation ) {
result.appendElements( v[0] );
result.appendElementsUnique( res );
result.append( "writebackGLE" , v[0] );
result.append( "initialGLEHost" , theShard );
result.append( "initialGLE", res );
}
else {
// there was a writeback
// but its from an old operations
// so all that's important is that we block, not that we return stats
result.appendElements( res );
}
// there was a writeback
// but its from an old operations
// so all that's important is that we block, not that we return stats
result.appendElements( res );
}
}
else {
@@ -365,6 +363,10 @@ namespace mongo {
LOG(4) << "checking " << writebacks.size() << " writebacks for"
<< " gle (" << shards->size() << " shards)" << endl;
// Multi-shard results from the writeback listener implicitly means that:
// A) no versioning was used (multi-update/delete)
// B) internal GLE was used (bulk insert)
if ( errors.size() == 0 ) {
result.appendNull( "err" );
_handleWriteBacks( writebacks , fromWriteBackListener );

View File

@@ -344,6 +344,9 @@ namespace mongo {
gle = b.obj();
}
dassert( !gle.isEmpty() );
verify( !gle.isEmpty() );
if ( gle["code"].numberInt() == 9517 ) {
log() << "new version change detected, "

View File

@@ -533,6 +533,14 @@ namespace mongo {
return undefinedReturn;
}
BSONObj PathExists( const BSONObj &a, void* data ) {
verify( a.nFields() == 1 );
string path = a.firstElement().valuestrsafe();
verify( !path.empty() );
bool exists = boost::filesystem::exists(path);
return BSON( string( "" ) << exists );
}
void copyDir( const boost::filesystem::path &from, const boost::filesystem::path &to ) {
boost::filesystem::directory_iterator end;
boost::filesystem::directory_iterator i( from );
@@ -748,6 +756,7 @@ namespace mongo {
scope.injectNative( "clearRawMongoProgramOutput", ClearRawMongoProgramOutput );
scope.injectNative( "waitProgram" , WaitProgram );
scope.injectNative( "resetDbpath", ResetDbpath );
scope.injectNative( "pathExists", PathExists );
scope.injectNative( "copyDbpath", CopyDbpath );
}
}

View File

@@ -43,7 +43,7 @@ namespace mongo {
* 1.2.3-rc4-pre-
* If you really need to do something else you'll need to fix _versionArray()
*/
const char versionString[] = "2.2.6-rc0";
const char versionString[] = "2.2.8-pre-";
// See unit test for example outputs
static BSONArray _versionArray(const char* version){