summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGreg Studer <greg@10gen.com>2013-07-09 11:59:16 -0400
committerDan Pasette <dan@mongodb.com>2013-10-02 16:06:55 -0400
commit8d082558e94bf937de09a1d6be62cc85441c1c5b (patch)
tree26300b830a8cbd38f008555785655e02096f7cca
parent4a34704bfa393b7a52b64a447a9c735bafe52782 (diff)
downloadmongo-8d082558e94bf937de09a1d6be62cc85441c1c5b.tar.gz
SERVER-9861 explicitly forget temporary collections for versioning in M/R
-rw-r--r--jstests/sharding/forget_mr_temp_ns.js46
-rw-r--r--src/mongo/db/commands/mr.cpp10
-rw-r--r--src/mongo/s/shard.h5
-rw-r--r--src/mongo/s/shardconnection.cpp9
4 files changed, 69 insertions, 1 deletions
diff --git a/jstests/sharding/forget_mr_temp_ns.js b/jstests/sharding/forget_mr_temp_ns.js
new file mode 100644
index 00000000000..54eeb88d9b5
--- /dev/null
+++ b/jstests/sharding/forget_mr_temp_ns.js
@@ -0,0 +1,46 @@
+//
+// Tests whether we forget M/R's temporary namespaces for sharded output
+//
+
+var options = { separateConfig : true };
+
+var st = new ShardingTest({ shards : 1, mongos : 1, other : options });
+
+var mongos = st.s0;
+var admin = mongos.getDB( "admin" );
+var coll = mongos.getCollection( "foo.bar" );
+var outputColl = mongos.getCollection( (coll.getDB() + "") + ".mrOutput" );
+
+for ( var i = 0; i < 10; i++ ) {
+ coll.insert({ _id : i, even : (i % 2 == 0) });
+}
+assert.eq( null, coll.getDB().getLastError() );
+
+var map = function() { emit( this.even, 1 ); };
+var reduce = function( key, values ) { return Array.sum(values); };
+
+out = coll.mapReduce( map, reduce, { out: { reduce : outputColl.getName(), sharded: true } } );
+
+printjson( out );
+printjson( outputColl.find().toArray() );
+
+var mongodThreadStats = st.shard0.getDB( "admin" ).runCommand({ shardConnPoolStats : 1 }).threads;
+var mongosThreadStats = admin.runCommand({ shardConnPoolStats : 1 }).threads;
+
+printjson( mongodThreadStats );
+printjson( mongosThreadStats );
+
+var checkForSeenNS = function( threadStats, regex ) {
+ for ( var i = 0; i < threadStats.length; i++ ) {
+ var seenNSes = threadStats[i].seenNS;
+ for ( var j = 0; j < seenNSes.length; j++ ) {
+ assert( !( regex.test( seenNSes ) ) );
+ }
+ }
+}
+
+checkForSeenNS( mongodThreadStats, /^foo.tmp/ );
+checkForSeenNS( mongosThreadStats, /^foo.tmp/ );
+
+st.stop();
+
diff --git a/src/mongo/db/commands/mr.cpp b/src/mongo/db/commands/mr.cpp
index 84fbfa8cb4d..1b237d3ed7f 100644
--- a/src/mongo/db/commands/mr.cpp
+++ b/src/mongo/db/commands/mr.cpp
@@ -301,8 +301,13 @@ namespace mongo {
*/
void State::dropTempCollections() {
_db.dropCollection(_config.tempNamespace);
- if (_useIncremental)
+ // Always forget about temporary namespaces, so we don't cache lots of them
+ ShardConnection::forgetNS( _config.tempNamespace );
+ if (_useIncremental) {
_db.dropCollection(_config.incLong);
+ ShardConnection::forgetNS( _config.incLong );
+ }
+
}
/**
@@ -1475,6 +1480,9 @@ namespace mongo {
break;
}
+ // Forget temporary input collection, if output is sharded collection
+ ShardConnection::forgetNS( inputNS );
+
result.append( "chunkSizes" , chunkSizes.arr() );
long long outputCount = state.postProcessCollection(op, pm);
diff --git a/src/mongo/s/shard.h b/src/mongo/s/shard.h
index e917baa0986..39504311a65 100644
--- a/src/mongo/s/shard.h
+++ b/src/mongo/s/shard.h
@@ -307,6 +307,11 @@ namespace mongo {
*/
static void clearPool();
+ /**
+ * Forgets a namespace to prevent future versioning.
+ */
+ static void forgetNS( const string& ns );
+
private:
void _init();
void _finishInit();
diff --git a/src/mongo/s/shardconnection.cpp b/src/mongo/s/shardconnection.cpp
index 61b47904147..6d21234071a 100644
--- a/src/mongo/s/shardconnection.cpp
+++ b/src/mongo/s/shardconnection.cpp
@@ -322,6 +322,11 @@ namespace mongo {
_hosts.clear();
}
+ void forgetNS( const string& ns ) {
+ scoped_spinlock lock( _lock );
+ _seenNS.erase( ns );
+ }
+
// -----
static thread_specific_ptr<ClientConnections> _perThread;
@@ -487,4 +492,8 @@ namespace mongo {
shardConnectionPool.clear();
ClientConnections::threadInstance()->clearPool();
}
+
+ void ShardConnection::forgetNS( const string& ns ) {
+ ClientConnections::threadInstance()->forgetNS( ns );
+ }
}