diff options
author | Eliot Horowitz <eliot@10gen.com> | 2010-04-26 15:24:16 -0400 |
---|---|---|
committer | Eliot Horowitz <eliot@10gen.com> | 2010-04-26 15:25:08 -0400 |
commit | 839236d8699c8b9590f21d8c158e4f3177b946c0 (patch) | |
tree | daf331058fb0a4e56169edb047aa92d02e097b20 | |
parent | 351b01e2a992e99792aeee009511caaa6ab38fa1 (diff) | |
download | mongo-839236d8699c8b9590f21d8c158e4f3177b946c0.tar.gz |
$ operator and $set can behave poorly with replication SERVER-1052
-rw-r--r-- | db/update.cpp | 6 | ||||
-rw-r--r-- | db/update.h | 12 | ||||
-rw-r--r-- | jstests/repl/basic1.js | 33 | ||||
-rw-r--r-- | jstests/update_arraymatch2.js | 2 |
4 files changed, 42 insertions, 11 deletions
diff --git a/db/update.cpp b/db/update.cpp index dfe0c36192c..7049fff7fc7 100644 --- a/db/update.cpp +++ b/db/update.cpp @@ -426,7 +426,7 @@ namespace mongo { // [dm] the BSONElementManipulator statements below are for replication (correct?) case Mod::INC: m.m->incrementMe( m.old ); - m.fixedName = "$set"; + m.fixedOpName = "$set"; m.fixed = &(m.old); break; case Mod::SET: @@ -814,11 +814,13 @@ namespace mongo { const BSONObj& onDisk = loc.obj(); ModSet * useMods = mods.get(); + bool forceRewrite = false; auto_ptr<ModSet> mymodset; if ( u->getMatchDetails().elemMatchKey && mods->hasDynamicArray() ){ useMods = mods->fixDynamicArray( u->getMatchDetails().elemMatchKey ); mymodset.reset( useMods ); + forceRewrite = true; } @@ -855,7 +857,7 @@ namespace mongo { pattern = patternBuilder.obj(); } - if ( mss->needOpLogRewrite() ){ + if ( forceRewrite || mss->needOpLogRewrite() ){ DEBUGUPDATE( "\t rewrite update: " << mss->getOpLogRewrite() ); logOp("u", ns, mss->getOpLogRewrite() , &pattern ); } diff --git a/db/update.h b/db/update.h index e14b0fb250f..5d20114fe97 100644 --- a/db/update.h +++ b/db/update.h @@ -327,7 +327,7 @@ namespace mongo { const Mod * m; BSONElement old; - const char * fixedName; + const char * fixedOpName; BSONElement * fixed; int pushStartSize; @@ -337,7 +337,7 @@ namespace mongo { long long inclong; ModState(){ - fixedName = 0; + fixedOpName = 0; fixed = 0; pushStartSize = -1; incType = EOO; @@ -352,7 +352,7 @@ namespace mongo { } bool needOpLogRewrite() const { - if ( fixed || fixedName || incType ) + if ( fixed || fixedOpName || incType ) return true; switch( op() ){ @@ -374,13 +374,13 @@ namespace mongo { return; } - const char * name = fixedName ? fixedName : Mod::modNames[op()]; + const char * name = fixedOpName ? fixedOpName : Mod::modNames[op()]; BSONObjBuilder bb( b.subobjStart( name ) ); if ( fixed ) bb.appendAs( *fixed , m->fieldName ); else - bb.append( m->elt ); + bb.appendAs( m->elt , m->fieldName ); bb.done(); } @@ -470,7 +470,7 @@ namespace mongo { break; case Mod::INC: - ms.fixedName = "$set"; + ms.fixedOpName = "$set"; case Mod::SET: { m._checkForAppending( m.elt ); b.appendAs( m.elt, m.shortFieldName ); diff --git a/jstests/repl/basic1.js b/jstests/repl/basic1.js index e0acf5cb123..950e7c31a70 100644 --- a/jstests/repl/basic1.js +++ b/jstests/repl/basic1.js @@ -7,6 +7,10 @@ var rt = new ReplTest( "basic1" ); m = rt.start( true ); s = rt.start( false ); +function block(){ + am.runCommand( { getlasterror : 1 , w : 2 , wtimeout : 3000 } ) +} + function hash( db ){ var s = ""; var a = db.getCollectionNames(); @@ -90,13 +94,38 @@ checkMR( am.mr ); checkMR( as.mr ); checkNumCollections( "MR2" ); -sleep( 3000 ); +block(); checkNumCollections( "MR3" ); var res = am.mr.mapReduce( m , r , { out : "xyz" } ); -sleep( 3000 ); +block(); + checkNumCollections( "MR4" ); + +t = am.rpos; +t.insert( { _id : 1 , a : [ { n : "a" , c : 1 } , { n : "b" , c : 1 } , { n : "c" , c : 1 } ] , b : [ 1 , 2 , 3 ] } ) +block(); +check( "after pos 1 " ); + +t.update( { "a.n" : "b" } , { $inc : { "a.$.c" : 1 } } ) +block(); +check( "after pos 2 " ); + +t.update( { "b" : 2 } , { $inc : { "b.$" : 1 } } ) +block(); +check( "after pos 3 " ); + +t.update( { "b" : 3} , { $set : { "b.$" : 17 } } ) +block(); +check( "after pos 4 " ); + + +printjson( am.rpos.findOne() ) +printjson( as.rpos.findOne() ) + +//am.getSisterDB( "local" ).getCollection( "oplog.$main" ).find().limit(10).sort( { $natural : -1 } ).forEach( printjson ) + rt.stop(); diff --git a/jstests/update_arraymatch2.js b/jstests/update_arraymatch2.js index 7eb810bc4eb..c07a61c378c 100644 --- a/jstests/update_arraymatch2.js +++ b/jstests/update_arraymatch2.js @@ -1,4 +1,4 @@ -t = db.tilde; +t = db.update_arraymatch2; t.drop(); t.insert( { } ); |