Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

SERVER-5142 double-check in lock for new version before recreating Sh…

…ardChunkManager
  • Loading branch information...
commit edc6a4892119009b514202e4d0c97d5c3bf54e1d 1 parent 446f597
Greg Studer authored March 02, 2012 erh committed March 06, 2012

Showing 2 changed files with 25 additions and 2 deletions. Show diff stats Hide diff stats

  1. 4  s/d_logic.h
  2. 23  s/d_state.cpp
4  s/d_logic.h
@@ -147,6 +147,10 @@ namespace mongo {
147 147
 
148 148
         // protects state below
149 149
         mutable mongo::mutex _mutex;
  150
+        // protects accessing the config server
  151
+        // can't use default _mutex b/c it's possible this shard is also the config server,
  152
+        // and we need to access the ShardingState to process new connections
  153
+        mutable mongo::mutex _configServerMutex;
150 154
 
151 155
         // map from a namespace into the ensemble of chunk ranges that are stored in this mongod
152 156
         // a ShardChunkManager carries all state we need for a collection at this shard, including its version information
23  s/d_state.cpp
@@ -45,7 +45,7 @@ namespace mongo {
45 45
     // -----ShardingState START ----
46 46
 
47 47
     ShardingState::ShardingState()
48  
-        : _enabled(false) , _mutex( "ShardingState" ) {
  48
+        : _enabled(false) , _mutex( "ShardingState" ), _configServerMutex( "_configServer_ShardingState" ) {
49 49
     }
50 50
 
51 51
     void ShardingState::enable( const string& server ) {
@@ -183,7 +183,22 @@ namespace mongo {
183 183
 
184 184
     bool ShardingState::trySetVersion( const string& ns , ConfigVersion& version /* IN-OUT */ ) {
185 185
 
186  
-        // fast path - requested version is at the same version as this chunk manager
  186
+        // Currently this function is called after a getVersion(), which is the first "check", and the assumption here
  187
+        // is that we don't do anything nearly as long as a remote query in a thread between then and now.
  188
+        // Otherwise it may be worth adding an additional check without the _configServerMutex below, since then it
  189
+        // would be likely that the version may have changed in the meantime without waiting for or fetching config results.
  190
+
  191
+        // TODO:  Mutex-per-namespace?
  192
+        
  193
+        LOG( 2 ) << "trying to set shard version of " << version.toString() << " for '" << ns << "'" << endl;
  194
+        
  195
+        scoped_lock clk( _configServerMutex );
  196
+
  197
+        // fast path - double-check if requested version is at the same version as this chunk manager before verifying
  198
+        // against config server
  199
+        //
  200
+        // This path will short-circuit the version set if another thread already managed to update the version in the
  201
+        // meantime.  First check is from getVersion().
187 202
         //
188 203
         // cases:
189 204
         //   + this shard updated the version for a migrate's commit (FROM side)
@@ -197,6 +212,8 @@ namespace mongo {
197 212
             if ( it != _chunks.end() && it->second->getVersion() == version )
198 213
                 return true;
199 214
         }
  215
+        
  216
+        LOG( 2 ) << "verifying remote version against " << version.toString() << " for '" << ns << "'" << endl;
200 217
 
201 218
         // slow path - requested version is different than the current chunk manager's, if one exists, so must check for
202 219
         // newest version in the config server
@@ -209,8 +226,10 @@ namespace mongo {
209 226
         //     the secondary had no state (managers) at all, so every client request will fall here
210 227
         //   + a stale client request a version that's not current anymore
211 228
 
  229
+        // Can't lock default mutex while creating ShardChunkManager, b/c may have to create a new connection to myself
212 230
         const string c = (_configServer == _shardHost) ? "" /* local */ : _configServer;
213 231
         ShardChunkManagerPtr p( new ShardChunkManager( c , ns , _shardName ) );
  232
+
214 233
         {
215 234
             scoped_lock lk( _mutex );
216 235
 

0 notes on commit edc6a48

Please sign in to comment.
Something went wrong with that request. Please try again.