mirror of https://github.com/citusdata/citus.git
Use GetPlacementListConnection for multi-shard commands
parent
01c9b1f921
commit
29f21fea59
|
@ -86,7 +86,6 @@ static void ExecuteMultipleTasks(CitusScanState *scanState, List *taskList,
|
||||||
bool isModificationQuery, bool expectResults);
|
bool isModificationQuery, bool expectResults);
|
||||||
static int64 ExecuteModifyTasks(List *taskList, bool expectResults,
|
static int64 ExecuteModifyTasks(List *taskList, bool expectResults,
|
||||||
ParamListInfo paramListInfo, CitusScanState *scanState);
|
ParamListInfo paramListInfo, CitusScanState *scanState);
|
||||||
static List * TaskShardIntervalList(List *taskList);
|
|
||||||
static void AcquireExecutorShardLock(Task *task, CmdType commandType);
|
static void AcquireExecutorShardLock(Task *task, CmdType commandType);
|
||||||
static void AcquireExecutorMultiShardLocks(List *taskList);
|
static void AcquireExecutorMultiShardLocks(List *taskList);
|
||||||
static bool RequiresConsistentSnapshot(Task *task);
|
static bool RequiresConsistentSnapshot(Task *task);
|
||||||
|
@ -1020,7 +1019,6 @@ ExecuteModifyTasks(List *taskList, bool expectResults, ParamListInfo paramListIn
|
||||||
ListCell *taskCell = NULL;
|
ListCell *taskCell = NULL;
|
||||||
Task *firstTask = NULL;
|
Task *firstTask = NULL;
|
||||||
int connectionFlags = 0;
|
int connectionFlags = 0;
|
||||||
List *shardIntervalList = NIL;
|
|
||||||
List *affectedTupleCountList = NIL;
|
List *affectedTupleCountList = NIL;
|
||||||
HTAB *shardConnectionHash = NULL;
|
HTAB *shardConnectionHash = NULL;
|
||||||
bool tasksPending = true;
|
bool tasksPending = true;
|
||||||
|
@ -1039,8 +1037,6 @@ ExecuteModifyTasks(List *taskList, bool expectResults, ParamListInfo paramListIn
|
||||||
"commands")));
|
"commands")));
|
||||||
}
|
}
|
||||||
|
|
||||||
shardIntervalList = TaskShardIntervalList(taskList);
|
|
||||||
|
|
||||||
/* ensure that there are no concurrent modifications on the same shards */
|
/* ensure that there are no concurrent modifications on the same shards */
|
||||||
AcquireExecutorMultiShardLocks(taskList);
|
AcquireExecutorMultiShardLocks(taskList);
|
||||||
|
|
||||||
|
@ -1064,8 +1060,7 @@ ExecuteModifyTasks(List *taskList, bool expectResults, ParamListInfo paramListIn
|
||||||
}
|
}
|
||||||
|
|
||||||
/* open connection to all relevant placements, if not already open */
|
/* open connection to all relevant placements, if not already open */
|
||||||
shardConnectionHash = OpenTransactionsToAllShardPlacements(shardIntervalList,
|
shardConnectionHash = OpenTransactionsForAllTasks(taskList, connectionFlags);
|
||||||
connectionFlags);
|
|
||||||
|
|
||||||
XactModificationLevel = XACT_MODIFICATION_MULTI_SHARD;
|
XactModificationLevel = XACT_MODIFICATION_MULTI_SHARD;
|
||||||
|
|
||||||
|
@ -1203,29 +1198,6 @@ ExecuteModifyTasks(List *taskList, bool expectResults, ParamListInfo paramListIn
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* TaskShardIntervalList returns a list of shard intervals for a given list of
|
|
||||||
* tasks.
|
|
||||||
*/
|
|
||||||
static List *
|
|
||||||
TaskShardIntervalList(List *taskList)
|
|
||||||
{
|
|
||||||
ListCell *taskCell = NULL;
|
|
||||||
List *shardIntervalList = NIL;
|
|
||||||
|
|
||||||
foreach(taskCell, taskList)
|
|
||||||
{
|
|
||||||
Task *task = (Task *) lfirst(taskCell);
|
|
||||||
int64 shardId = task->anchorShardId;
|
|
||||||
ShardInterval *shardInterval = LoadShardInterval(shardId);
|
|
||||||
|
|
||||||
shardIntervalList = lappend(shardIntervalList, shardInterval);
|
|
||||||
}
|
|
||||||
|
|
||||||
return shardIntervalList;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* SendQueryInSingleRowMode sends the given query on the connection in an
|
* SendQueryInSingleRowMode sends the given query on the connection in an
|
||||||
* asynchronous way. The function also sets the single-row mode on the
|
* asynchronous way. The function also sets the single-row mode on the
|
||||||
|
|
|
@ -210,7 +210,7 @@ ModifyMultipleShardsTaskList(Query *query, List *shardIntervalList, Oid relation
|
||||||
task = CitusMakeNode(Task);
|
task = CitusMakeNode(Task);
|
||||||
task->jobId = jobId;
|
task->jobId = jobId;
|
||||||
task->taskId = taskId++;
|
task->taskId = taskId++;
|
||||||
task->taskType = SQL_TASK;
|
task->taskType = MODIFY_TASK;
|
||||||
task->queryString = shardQueryString->data;
|
task->queryString = shardQueryString->data;
|
||||||
task->dependedTaskList = NULL;
|
task->dependedTaskList = NULL;
|
||||||
task->replicationModel = REPLICATION_MODEL_INVALID;
|
task->replicationModel = REPLICATION_MODEL_INVALID;
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#include "distributed/connection_management.h"
|
#include "distributed/connection_management.h"
|
||||||
#include "distributed/master_metadata_utility.h"
|
#include "distributed/master_metadata_utility.h"
|
||||||
#include "distributed/metadata_cache.h"
|
#include "distributed/metadata_cache.h"
|
||||||
|
#include "distributed/multi_router_executor.h"
|
||||||
#include "distributed/multi_shard_transaction.h"
|
#include "distributed/multi_shard_transaction.h"
|
||||||
#include "distributed/placement_connection.h"
|
#include "distributed/placement_connection.h"
|
||||||
#include "distributed/shardinterval_utils.h"
|
#include "distributed/shardinterval_utils.h"
|
||||||
|
@ -30,25 +31,27 @@
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* OpenTransactionsToAllShardPlacements opens connections to all placements
|
* OpenTransactionsForAllTasks opens a connection for each task,
|
||||||
* using the provided shard identifier list and returns it as a shard ID ->
|
* taking into account which shards are read and modified by the task
|
||||||
* ShardConnections hash. connectionFlags can be used to specify whether
|
* to select the appopriate connection, or error out if no appropriate
|
||||||
* the command is FOR_DML or FOR_DDL.
|
* connection can be found. The set of connections is returned as an
|
||||||
|
* anchor shard ID -> ShardConnections hash.
|
||||||
*/
|
*/
|
||||||
HTAB *
|
HTAB *
|
||||||
OpenTransactionsToAllShardPlacements(List *shardIntervalList, int connectionFlags)
|
OpenTransactionsForAllTasks(List *taskList, int connectionFlags)
|
||||||
{
|
{
|
||||||
HTAB *shardConnectionHash = NULL;
|
HTAB *shardConnectionHash = NULL;
|
||||||
ListCell *shardIntervalCell = NULL;
|
ListCell *taskCell = NULL;
|
||||||
List *newConnectionList = NIL;
|
List *newConnectionList = NIL;
|
||||||
|
|
||||||
shardConnectionHash = CreateShardConnectionHash(CurrentMemoryContext);
|
shardConnectionHash = CreateShardConnectionHash(CurrentMemoryContext);
|
||||||
|
|
||||||
/* open connections to shards which don't have connections yet */
|
/* open connections to shards which don't have connections yet */
|
||||||
foreach(shardIntervalCell, shardIntervalList)
|
foreach(taskCell, taskList)
|
||||||
{
|
{
|
||||||
ShardInterval *shardInterval = (ShardInterval *) lfirst(shardIntervalCell);
|
Task *task = (Task *) lfirst(taskCell);
|
||||||
uint64 shardId = shardInterval->shardId;
|
ShardPlacementAccessType accessType = PLACEMENT_ACCESS_SELECT;
|
||||||
|
uint64 shardId = task->anchorShardId;
|
||||||
ShardConnections *shardConnections = NULL;
|
ShardConnections *shardConnections = NULL;
|
||||||
bool shardConnectionsFound = false;
|
bool shardConnectionsFound = false;
|
||||||
List *shardPlacementList = NIL;
|
List *shardPlacementList = NIL;
|
||||||
|
@ -69,9 +72,24 @@ OpenTransactionsToAllShardPlacements(List *shardIntervalList, int connectionFlag
|
||||||
UINT64_FORMAT, shardId)));
|
UINT64_FORMAT, shardId)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (task->taskType == MODIFY_TASK)
|
||||||
|
{
|
||||||
|
accessType = PLACEMENT_ACCESS_DML;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* can only open connections for DDL and DML commands */
|
||||||
|
Assert(task->taskType == DDL_TASK);
|
||||||
|
|
||||||
|
accessType = PLACEMENT_ACCESS_DDL;
|
||||||
|
}
|
||||||
|
|
||||||
foreach(placementCell, shardPlacementList)
|
foreach(placementCell, shardPlacementList)
|
||||||
{
|
{
|
||||||
ShardPlacement *shardPlacement = (ShardPlacement *) lfirst(placementCell);
|
ShardPlacement *shardPlacement = (ShardPlacement *) lfirst(placementCell);
|
||||||
|
ShardPlacementAccess placementModification;
|
||||||
|
List *placementAccessList = NIL;
|
||||||
|
List *placementSelectList = NIL;
|
||||||
MultiConnection *connection = NULL;
|
MultiConnection *connection = NULL;
|
||||||
|
|
||||||
WorkerNode *workerNode = FindWorkerNode(shardPlacement->nodeName,
|
WorkerNode *workerNode = FindWorkerNode(shardPlacement->nodeName,
|
||||||
|
@ -83,9 +101,24 @@ OpenTransactionsToAllShardPlacements(List *shardIntervalList, int connectionFlag
|
||||||
shardPlacement->nodePort)));
|
shardPlacement->nodePort)));
|
||||||
}
|
}
|
||||||
|
|
||||||
connection = StartPlacementConnection(connectionFlags,
|
/* add placement access for modification */
|
||||||
shardPlacement,
|
placementModification.placement = shardPlacement;
|
||||||
NULL);
|
placementModification.accessType = accessType;
|
||||||
|
|
||||||
|
placementAccessList = lappend(placementAccessList, &placementModification);
|
||||||
|
|
||||||
|
/* add additional placement accesses for subselects (e.g. INSERT .. SELECT) */
|
||||||
|
placementSelectList = BuildPlacementSelectList(shardPlacement->nodeName,
|
||||||
|
shardPlacement->nodePort,
|
||||||
|
task->relationShardList);
|
||||||
|
placementAccessList = list_concat(placementAccessList, placementSelectList);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Find a connection that sees preceding writes and cannot self-deadlock,
|
||||||
|
* or error out if no such connection exists.
|
||||||
|
*/
|
||||||
|
connection = StartPlacementListConnection(connectionFlags,
|
||||||
|
placementAccessList, NULL);
|
||||||
|
|
||||||
ClaimConnectionExclusively(connection);
|
ClaimConnectionExclusively(connection);
|
||||||
|
|
||||||
|
|
|
@ -27,8 +27,7 @@ typedef struct ShardConnections
|
||||||
} ShardConnections;
|
} ShardConnections;
|
||||||
|
|
||||||
|
|
||||||
extern HTAB * OpenTransactionsToAllShardPlacements(List *shardIdList,
|
extern HTAB * OpenTransactionsForAllTasks(List *taskList, int connectionFlags);
|
||||||
int connectionFlags);
|
|
||||||
extern HTAB * CreateShardConnectionHash(MemoryContext memoryContext);
|
extern HTAB * CreateShardConnectionHash(MemoryContext memoryContext);
|
||||||
extern ShardConnections * GetShardHashConnections(HTAB *connectionHash, int64 shardId,
|
extern ShardConnections * GetShardHashConnections(HTAB *connectionHash, int64 shardId,
|
||||||
bool *connectionsFound);
|
bool *connectionsFound);
|
||||||
|
|
Loading…
Reference in New Issue