summaryrefslogtreecommitdiff
path: root/src/mongo/s/d_logic.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/s/d_logic.h')
-rw-r--r--src/mongo/s/d_logic.h251
1 files changed, 251 insertions, 0 deletions
diff --git a/src/mongo/s/d_logic.h b/src/mongo/s/d_logic.h
new file mode 100644
index 00000000000..cda29094597
--- /dev/null
+++ b/src/mongo/s/d_logic.h
@@ -0,0 +1,251 @@
+// @file d_logic.h
+/*
+ * Copyright (C) 2010 10gen Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#pragma once
+
+#include "mongo/pch.h"
+
+#include "../db/jsobj.h"
+
+#include "d_chunk_manager.h"
+#include "util.h"
+#include "mongo/util/concurrency/ticketholder.h"
+
+namespace mongo {
+
+ class Database;
+ class DiskLoc;
+
+ typedef ShardChunkVersion ConfigVersion;
+
+ // --------------
+ // --- global state ---
+ // --------------
+
+ class ShardingState {
+ public:
+ ShardingState();
+
+ bool enabled() const { return _enabled; }
+ const string& getConfigServer() const { return _configServer; }
+ void enable( const string& server );
+
+ void gotShardName( const string& name );
+ void gotShardHost( string host );
+
+ string getShardName() { return _shardName; }
+ string getShardHost() { return _shardHost; }
+
+ /** Reverts back to a state where this mongod is not sharded. */
+ void resetShardingState();
+
+ // versioning support
+
+ bool hasVersion( const string& ns );
+ bool hasVersion( const string& ns , ConfigVersion& version );
+ const ConfigVersion getVersion( const string& ns ) const;
+
+ /**
+ * Uninstalls the manager for a given collection. This should be used when the collection is dropped.
+ *
+ * NOTE:
+ * An existing collection with no chunks on this shard will have a manager on version 0, which is different than a
+ * a dropped collection, which will not have a manager.
+ *
+ * TODO
+ * When sharding state is enabled, absolutely all collections should have a manager. (The non-sharded ones are
+ * a be degenerate case of one-chunk collections).
+ * For now, a dropped collection and an non-sharded one are indistinguishable (SERVER-1849)
+ *
+ * @param ns the collection to be dropped
+ */
+ void resetVersion( const string& ns );
+
+ /**
+ * Requests to access a collection at a certain version. If the collection's manager is not at that version it
+ * will try to update itself to the newest version. The request is only granted if the version is the current or
+ * the newest one.
+ *
+ * @param ns collection to be accessed
+ * @param version (IN) the client belive this collection is on and (OUT) the version the manager is actually in
+ * @return true if the access can be allowed at the provided version
+ */
+ bool trySetVersion( const string& ns , ConfigVersion& version );
+
+ void appendInfo( BSONObjBuilder& b );
+
+ // querying support
+
+ bool needShardChunkManager( const string& ns ) const;
+ ShardChunkManagerPtr getShardChunkManager( const string& ns );
+
+ // chunk migrate and split support
+
+ /**
+ * Creates and installs a new chunk manager for a given collection by "forgetting" about one of its chunks.
+ * The new manager uses the provided version, which has to be higher than the current manager's.
+ * One exception: if the forgotten chunk is the last one in this shard for the collection, version has to be 0.
+ *
+ * If it runs successfully, clients need to grab the new version to access the collection.
+ *
+ * @param ns the collection
+ * @param min max the chunk to eliminate from the current manager
+ * @param version at which the new manager should be at
+ */
+ void donateChunk( const string& ns , const BSONObj& min , const BSONObj& max , ShardChunkVersion version );
+
+ /**
+ * Creates and installs a new chunk manager for a given collection by reclaiming a previously donated chunk.
+ * The previous manager's version has to be provided.
+ *
+ * If it runs successfully, clients that became stale by the previous donateChunk will be able to access the
+ * collection again.
+ *
+ * @param ns the collection
+ * @param min max the chunk to reclaim and add to the current manager
+ * @param version at which the new manager should be at
+ */
+ void undoDonateChunk( const string& ns , const BSONObj& min , const BSONObj& max , ShardChunkVersion version );
+
+ /**
+ * Creates and installs a new chunk manager for a given collection by splitting one of its chunks in two or more.
+ * The version for the first split chunk should be provided. The subsequent chunks' version would be the latter with the
+ * minor portion incremented.
+ *
+ * The effect on clients will depend on the version used. If the major portion is the same as the current shards,
+ * clients shouldn't perceive the split.
+ *
+ * @param ns the collection
+ * @param min max the chunk that should be split
+ * @param splitKeys point in which to split
+ * @param version at which the new manager should be at
+ */
+ void splitChunk( const string& ns , const BSONObj& min , const BSONObj& max , const vector<BSONObj>& splitKeys ,
+ ShardChunkVersion version );
+
+ bool inCriticalMigrateSection();
+
+ private:
+ bool _enabled;
+
+ string _configServer;
+
+ string _shardName;
+ string _shardHost;
+
+ // protects state below
+ mutable mongo::mutex _mutex;
+ // protects accessing the config server
+ // Using a ticket holder so we can have multiple redundant tries at any given time
+ mutable TicketHolder _configServerTickets;
+
+ // map from a namespace into the ensemble of chunk ranges that are stored in this mongod
+ // a ShardChunkManager carries all state we need for a collection at this shard, including its version information
+ typedef map<string,ShardChunkManagerPtr> ChunkManagersMap;
+ ChunkManagersMap _chunks;
+ };
+
+ extern ShardingState shardingState;
+
+ /**
+ * one per connection from mongos
+ * holds version state for each namesapce
+ */
+ class ShardedConnectionInfo {
+ public:
+ ShardedConnectionInfo();
+
+ const OID& getID() const { return _id; }
+ bool hasID() const { return _id.isSet(); }
+ void setID( const OID& id );
+
+ const ConfigVersion getVersion( const string& ns ) const;
+ void setVersion( const string& ns , const ConfigVersion& version );
+
+ static ShardedConnectionInfo* get( bool create );
+ static void reset();
+ static void addHook();
+
+ bool inForceVersionOkMode() const {
+ return _forceVersionOk;
+ }
+
+ void enterForceVersionOkMode() { _forceVersionOk = true; }
+ void leaveForceVersionOkMode() { _forceVersionOk = false; }
+
+ private:
+
+ OID _id;
+ bool _forceVersionOk; // if this is true, then chunk version #s aren't check, and all ops are allowed
+
+ typedef map<string,ConfigVersion> NSVersionMap;
+ NSVersionMap _versions;
+
+ static boost::thread_specific_ptr<ShardedConnectionInfo> _tl;
+ };
+
+ struct ShardForceVersionOkModeBlock {
+ ShardForceVersionOkModeBlock() {
+ info = ShardedConnectionInfo::get( false );
+ if ( info )
+ info->enterForceVersionOkMode();
+ }
+ ~ShardForceVersionOkModeBlock() {
+ if ( info )
+ info->leaveForceVersionOkMode();
+ }
+
+ ShardedConnectionInfo * info;
+ };
+
+ // -----------------
+ // --- core ---
+ // -----------------
+
+ unsigned long long extractVersion( BSONElement e , string& errmsg );
+
+
+ /**
+ * @return true if we have any shard info for the ns
+ */
+ bool haveLocalShardingInfo( const string& ns );
+
+ /**
+ * @return true if the current threads shard version is ok, or not in sharded version
+ * Also returns an error message and the Config/ShardChunkVersions causing conflicts
+ */
+ bool shardVersionOk( const string& ns , string& errmsg, ConfigVersion& received, ConfigVersion& wanted );
+
+ /**
+ * @return true if we took care of the message and nothing else should be done
+ */
+ struct DbResponse;
+
+ bool _handlePossibleShardedMessage( Message &m, DbResponse * dbresponse );
+
+ /** What does this do? document please? */
+ inline bool handlePossibleShardedMessage( Message &m, DbResponse * dbresponse ) {
+ if( !shardingState.enabled() )
+ return false;
+ return _handlePossibleShardedMessage(m, dbresponse);
+ }
+
+ void logOpForSharding( const char * opstr , const char * ns , const BSONObj& obj , BSONObj * patt );
+ void aboutToDeleteForSharding( const Database* db , const DiskLoc& dl );
+
+}