bool MySqlShardingPool::init() { for (int i = 0; i < shardNum(); i++) { MySqlConnectionByShard shard(i, this); } return true; }
StoragePtr TableFunctionShardByHash::execute(ASTPtr ast_function, Context & context) const { ASTs & args_func = typeid_cast<ASTFunction &>(*ast_function).children; const char * err = "Table function 'shardByHash' requires 4 parameters: " "cluster name, key string to hash, name of remote database, name of remote table."; if (args_func.size() != 1) throw Exception(err, ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH); ASTs & args = typeid_cast<ASTExpressionList &>(*args_func.at(0)).children; if (args.size() != 4) throw Exception(err, ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH); String cluster_name; String key; String remote_database; String remote_table; auto getStringLiteral = [](const IAST & node, const char * description) { const ASTLiteral * lit = typeid_cast<const ASTLiteral *>(&node); if (!lit) throw Exception(description + String(" must be string literal (in single quotes)."), ErrorCodes::BAD_ARGUMENTS); if (lit->value.getType() != Field::Types::String) throw Exception(description + String(" must be string literal (in single quotes)."), ErrorCodes::BAD_ARGUMENTS); return safeGet<const String &>(lit->value); }; cluster_name = getClusterName(*args[0]); key = getStringLiteral(*args[1], "Key to hash"); args[2] = evaluateConstantExpressionOrIdentidierAsLiteral(args[2], context); args[3] = evaluateConstantExpressionOrIdentidierAsLiteral(args[3], context); remote_database = static_cast<const ASTLiteral &>(*args[2]).value.safeGet<String>(); remote_table = static_cast<const ASTLiteral &>(*args[3]).value.safeGet<String>(); /// Аналогично другим TableFunctions. for (auto & arg : args) if (ASTIdentifier * id = typeid_cast<ASTIdentifier *>(arg.get())) id->kind = ASTIdentifier::Table; const Cluster & cluster = context.getCluster(cluster_name); size_t shard_index = sipHash64(key) % cluster.getShardCount(); std::shared_ptr<Cluster> shard(cluster.getClusterWithSingleShard(shard_index).release()); return StorageDistributed::create( getName(), std::make_shared<NamesAndTypesList>(getStructureOfRemoteTable(*shard, remote_database, remote_table, context)), remote_database, remote_table, shard, context); }
DBConfig::CollectionInfo::CollectionInfo( const BSONObj& in ) { _dirty = false; _dropped = in["dropped"].trueValue(); if ( in["key"].isABSONObj() ) { _key = in["key"].Obj().getOwned(); _unqiue = in["unique"].trueValue(); shard( in["_id"].String() , _key , _unqiue ); } _dirty = false; }
void setSingleChunkForShards( const vector<BSONObj> &splitPoints ) { ChunkMap &chunkMap = const_cast<ChunkMap&>( _chunkMap ); ChunkRangeManager &chunkRanges = const_cast<ChunkRangeManager&>( _chunkRanges ); set<Shard> &shards = const_cast<set<Shard>&>( _shards ); vector<BSONObj> mySplitPoints( splitPoints ); mySplitPoints.insert( mySplitPoints.begin(), _key.globalMin() ); mySplitPoints.push_back( _key.globalMax() ); for( unsigned i = 1; i < mySplitPoints.size(); ++i ) { string name = str::stream() << (i-1); Shard shard( name, name ); shards.insert( shard ); ChunkPtr chunk( new Chunk( this, mySplitPoints[ i-1 ], mySplitPoints[ i ], shard ) ); chunkMap[ mySplitPoints[ i ] ] = chunk; } chunkRanges.reloadAll( chunkMap ); }
DBConfig::CollectionInfo::CollectionInfo( const BSONObj& in ) { _dirty = false; _dropped = in["dropped"].trueValue(); if ( in["key"].isABSONObj() ) shard( in["_id"].String() , in["key"].Obj() , in["unique"].trueValue() ); }