summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEliot Horowitz <eliot@10gen.com>2010-04-26 15:24:16 -0400
committerEliot Horowitz <eliot@10gen.com>2010-04-26 15:25:08 -0400
commit839236d8699c8b9590f21d8c158e4f3177b946c0 (patch)
treedaf331058fb0a4e56169edb047aa92d02e097b20
parent351b01e2a992e99792aeee009511caaa6ab38fa1 (diff)
downloadmongo-839236d8699c8b9590f21d8c158e4f3177b946c0.tar.gz
$ operator and $set can behave poorly with replication SERVER-1052
-rw-r--r--db/update.cpp6
-rw-r--r--db/update.h12
-rw-r--r--jstests/repl/basic1.js33
-rw-r--r--jstests/update_arraymatch2.js2
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( { } );