mirror of https://github.com/citusdata/citus.git
Metadata sync api supports batching commands.
parent
104e85e18f
commit
cee759d66d
|
@ -36,16 +36,18 @@
|
||||||
#include "catalog/pg_proc.h"
|
#include "catalog/pg_proc.h"
|
||||||
#include "catalog/pg_type.h"
|
#include "catalog/pg_type.h"
|
||||||
#include "commands/async.h"
|
#include "commands/async.h"
|
||||||
|
#include "distributed/adaptive_executor.h"
|
||||||
#include "distributed/argutils.h"
|
#include "distributed/argutils.h"
|
||||||
#include "distributed/backend_data.h"
|
#include "distributed/backend_data.h"
|
||||||
#include "distributed/citus_ruleutils.h"
|
#include "distributed/citus_ruleutils.h"
|
||||||
#include "distributed/colocation_utils.h"
|
#include "distributed/colocation_utils.h"
|
||||||
#include "distributed/commands.h"
|
#include "distributed/commands.h"
|
||||||
|
#include "distributed/coordinator_protocol.h"
|
||||||
#include "distributed/deparser.h"
|
#include "distributed/deparser.h"
|
||||||
|
#include "distributed/deparse_shard_query.h"
|
||||||
#include "distributed/distribution_column.h"
|
#include "distributed/distribution_column.h"
|
||||||
#include "distributed/listutils.h"
|
#include "distributed/listutils.h"
|
||||||
#include "distributed/metadata_utility.h"
|
#include "distributed/metadata_utility.h"
|
||||||
#include "distributed/coordinator_protocol.h"
|
|
||||||
#include "distributed/maintenanced.h"
|
#include "distributed/maintenanced.h"
|
||||||
#include "distributed/metadata_cache.h"
|
#include "distributed/metadata_cache.h"
|
||||||
#include "distributed/metadata_sync.h"
|
#include "distributed/metadata_sync.h"
|
||||||
|
@ -91,6 +93,7 @@
|
||||||
/* managed via a GUC */
|
/* managed via a GUC */
|
||||||
char *EnableManualMetadataChangesForUser = "";
|
char *EnableManualMetadataChangesForUser = "";
|
||||||
int MetadataSyncTransMode = METADATA_SYNC_TRANSACTIONAL;
|
int MetadataSyncTransMode = METADATA_SYNC_TRANSACTIONAL;
|
||||||
|
int MetadataSyncBatchCount = METADATA_SYNC_DEFAULT_BATCH_COUNT;
|
||||||
|
|
||||||
|
|
||||||
static void EnsureObjectMetadataIsSane(int distributionArgumentIndex,
|
static void EnsureObjectMetadataIsSane(int distributionArgumentIndex,
|
||||||
|
@ -146,6 +149,8 @@ static char * ColocationGroupCreateCommand(uint32 colocationId, int shardCount,
|
||||||
static char * ColocationGroupDeleteCommand(uint32 colocationId);
|
static char * ColocationGroupDeleteCommand(uint32 colocationId);
|
||||||
static char * RemoteTypeIdExpression(Oid typeId);
|
static char * RemoteTypeIdExpression(Oid typeId);
|
||||||
static char * RemoteCollationIdExpression(Oid colocationId);
|
static char * RemoteCollationIdExpression(Oid colocationId);
|
||||||
|
static bool ExceedsSyncBatchCount(MetadataSyncContext *context);
|
||||||
|
static void ExecuteCommandListOnWorkerList(List *commandList, List *workerList);
|
||||||
|
|
||||||
|
|
||||||
PG_FUNCTION_INFO_V1(start_metadata_sync_to_all_nodes);
|
PG_FUNCTION_INFO_V1(start_metadata_sync_to_all_nodes);
|
||||||
|
@ -201,11 +206,11 @@ start_metadata_sync_to_node(PG_FUNCTION_ARGS)
|
||||||
* It contains activated nodes, bare connections if the mode is nontransactional,
|
* It contains activated nodes, bare connections if the mode is nontransactional,
|
||||||
* and a memory context for allocation.
|
* and a memory context for allocation.
|
||||||
*/
|
*/
|
||||||
bool collectCommands = false;
|
|
||||||
bool nodesAddedInSameTransaction = false;
|
bool nodesAddedInSameTransaction = false;
|
||||||
|
bool noConnectionMode = false;
|
||||||
MetadataSyncContext *context = CreateMetadataSyncContext(list_make1(workerNode),
|
MetadataSyncContext *context = CreateMetadataSyncContext(list_make1(workerNode),
|
||||||
collectCommands,
|
nodesAddedInSameTransaction,
|
||||||
nodesAddedInSameTransaction);
|
noConnectionMode);
|
||||||
|
|
||||||
ActivateNodeList(context);
|
ActivateNodeList(context);
|
||||||
TransactionModifiedNodeMetadata = true;
|
TransactionModifiedNodeMetadata = true;
|
||||||
|
@ -234,11 +239,11 @@ start_metadata_sync_to_all_nodes(PG_FUNCTION_ARGS)
|
||||||
* It contains activated nodes, bare connections if the mode is nontransactional,
|
* It contains activated nodes, bare connections if the mode is nontransactional,
|
||||||
* and a memory context for allocation.
|
* and a memory context for allocation.
|
||||||
*/
|
*/
|
||||||
bool collectCommands = false;
|
|
||||||
bool nodesAddedInSameTransaction = false;
|
bool nodesAddedInSameTransaction = false;
|
||||||
|
bool noConnectionMode = false;
|
||||||
MetadataSyncContext *context = CreateMetadataSyncContext(nodeList,
|
MetadataSyncContext *context = CreateMetadataSyncContext(nodeList,
|
||||||
collectCommands,
|
nodesAddedInSameTransaction,
|
||||||
nodesAddedInSameTransaction);
|
noConnectionMode);
|
||||||
|
|
||||||
ActivateNodeList(context);
|
ActivateNodeList(context);
|
||||||
TransactionModifiedNodeMetadata = true;
|
TransactionModifiedNodeMetadata = true;
|
||||||
|
@ -4008,15 +4013,15 @@ EstablishAndSetMetadataSyncBareConnections(MetadataSyncContext *context)
|
||||||
* CreateMetadataSyncContext creates a context which contains worker connections
|
* CreateMetadataSyncContext creates a context which contains worker connections
|
||||||
* and a MemoryContext to be used throughout the metadata sync.
|
* and a MemoryContext to be used throughout the metadata sync.
|
||||||
*
|
*
|
||||||
* If we collect commands, connections will not be established as caller's intent
|
* If noConnectionMode is set, we do not establish connection. Instead, we just
|
||||||
* is to collect sync commands.
|
* collect commands.
|
||||||
*
|
*
|
||||||
* If the nodes are newly added before activation, we would not try to unset
|
* If the nodes are newly added before activation, we would not try to unset
|
||||||
* metadatasynced in separate transaction during nontransactional metadatasync.
|
* metadatasynced in separate transaction during nontransactional metadatasync.
|
||||||
*/
|
*/
|
||||||
MetadataSyncContext *
|
MetadataSyncContext *
|
||||||
CreateMetadataSyncContext(List *nodeList, bool collectCommands,
|
CreateMetadataSyncContext(List *nodeList, bool nodesAddedInSameTransaction,
|
||||||
bool nodesAddedInSameTransaction)
|
bool noConnectionMode)
|
||||||
{
|
{
|
||||||
/* should be alive during local transaction during the sync */
|
/* should be alive during local transaction during the sync */
|
||||||
MemoryContext context = AllocSetContextCreate(TopTransactionContext,
|
MemoryContext context = AllocSetContextCreate(TopTransactionContext,
|
||||||
|
@ -4028,18 +4033,18 @@ CreateMetadataSyncContext(List *nodeList, bool collectCommands,
|
||||||
|
|
||||||
metadataSyncContext->context = context;
|
metadataSyncContext->context = context;
|
||||||
metadataSyncContext->transactionMode = MetadataSyncTransMode;
|
metadataSyncContext->transactionMode = MetadataSyncTransMode;
|
||||||
metadataSyncContext->collectCommands = collectCommands;
|
|
||||||
metadataSyncContext->collectedCommands = NIL;
|
metadataSyncContext->collectedCommands = NIL;
|
||||||
metadataSyncContext->nodesAddedInSameTransaction = nodesAddedInSameTransaction;
|
metadataSyncContext->nodesAddedInSameTransaction = nodesAddedInSameTransaction;
|
||||||
|
metadataSyncContext->noConnectionMode = noConnectionMode;
|
||||||
|
|
||||||
/* filter the nodes that needs to be activated from given node list */
|
/* filter the nodes that needs to be activated from given node list */
|
||||||
SetMetadataSyncNodesFromNodeList(metadataSyncContext, nodeList);
|
SetMetadataSyncNodesFromNodeList(metadataSyncContext, nodeList);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* establish connections only for nontransactional mode to prevent connection
|
* Establish connections only for nontransactional mode to prevent connection
|
||||||
* open-close for each command
|
* open-close for each command.
|
||||||
*/
|
*/
|
||||||
if (!collectCommands && MetadataSyncTransMode == METADATA_SYNC_NON_TRANSACTIONAL)
|
if (!noConnectionMode && MetadataSyncTransMode == METADATA_SYNC_NON_TRANSACTIONAL)
|
||||||
{
|
{
|
||||||
EstablishAndSetMetadataSyncBareConnections(metadataSyncContext);
|
EstablishAndSetMetadataSyncBareConnections(metadataSyncContext);
|
||||||
}
|
}
|
||||||
|
@ -4055,53 +4060,160 @@ CreateMetadataSyncContext(List *nodeList, bool collectCommands,
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ResetMetadataSyncMemoryContext resets memory context inside metadataSyncContext, if
|
* ExceedsSyncBatchCount returns whether given context accumulated
|
||||||
* we are not collecting commands.
|
* more than METADATA_SYNC_DEFAULT_BATCH_COUNT.
|
||||||
*/
|
*/
|
||||||
void
|
static bool
|
||||||
ResetMetadataSyncMemoryContext(MetadataSyncContext *context)
|
ExceedsSyncBatchCount(MetadataSyncContext *context)
|
||||||
{
|
{
|
||||||
if (!MetadataSyncCollectsCommands(context))
|
int collectedCommandCount = list_length(context->collectedCommands);
|
||||||
{
|
return collectedCommandCount > METADATA_SYNC_DEFAULT_BATCH_COUNT;
|
||||||
MemoryContextReset(context->context);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* MetadataSyncCollectsCommands returns whether context is used for collecting
|
* ExecuteCommandListOnWorkerList executes a command list on all nodes
|
||||||
* commands instead of sending them to workers.
|
* in the given list.
|
||||||
*/
|
*/
|
||||||
bool
|
static void
|
||||||
MetadataSyncCollectsCommands(MetadataSyncContext *context)
|
ExecuteCommandListOnWorkerList(List *commandList, List *workerList)
|
||||||
{
|
{
|
||||||
return context->collectCommands;
|
List *taskList = NIL;
|
||||||
|
|
||||||
|
WorkerNode *workerNode = NULL;
|
||||||
|
foreach_ptr(workerNode, workerList)
|
||||||
|
{
|
||||||
|
ShardPlacement *placement = CitusMakeNode(ShardPlacement);
|
||||||
|
SetPlacementNodeMetadata(placement, workerNode);
|
||||||
|
|
||||||
|
Task *task = CitusMakeNode(Task);
|
||||||
|
task->taskType = DDL_TASK;
|
||||||
|
SetTaskQueryStringList(task, commandList);
|
||||||
|
task->taskPlacementList = list_make1(placement);
|
||||||
|
|
||||||
|
taskList = lappend(taskList, task);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool localExecutionSupported = false;
|
||||||
|
|
||||||
|
ExecuteUtilityTaskList(taskList, localExecutionSupported);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* SendOrCollectCommandListToActivatedNodes sends the commands to the activated nodes with
|
* ProcessBatchCommandsToActivatedNodes processes collected commands inside
|
||||||
* bare connections inside metadatacontext or via coordinated connections.
|
* metadataSyncContext. Sends commands to activated workers if batch limit
|
||||||
* Note that when context only collects commands, we add commands into the context
|
* is exceeded or user forces. If noConnectionMode is set, it would not process
|
||||||
* without sending the commands.
|
* the commands.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
SendOrCollectCommandListToActivatedNodes(MetadataSyncContext *context, List *commands)
|
ProcessBatchCommandsToActivatedNodes(MetadataSyncContext *context, bool forceSend)
|
||||||
{
|
{
|
||||||
/* do nothing if no commands */
|
/* do not send and reset commands if we are in noConnectionMode */
|
||||||
if (commands == NIL)
|
if (MetadataSyncInNoConnectionMode(context))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
if (forceSend || ExceedsSyncBatchCount(context))
|
||||||
* do not send any command to workers if we collect commands.
|
{
|
||||||
* Collect commands into metadataSyncContext's collected command
|
SendCollectedCommandsToActivatedNodes(context);
|
||||||
* list.
|
ResetMetadataSyncMemoryContext(context);
|
||||||
*/
|
}
|
||||||
if (MetadataSyncCollectsCommands(context))
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ProcessBatchCommandsToSingleNode does the same operation as
|
||||||
|
* ProcessBatchCommandsToActivatedNodes but for metadata nodes.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
ProcessBatchCommandsToMetadataNodes(MetadataSyncContext *context, bool forceSend)
|
||||||
|
{
|
||||||
|
/* do not send and reset commands if we are in noConnectionMode */
|
||||||
|
if (MetadataSyncInNoConnectionMode(context))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (forceSend || ExceedsSyncBatchCount(context))
|
||||||
|
{
|
||||||
|
SendCollectedCommandsToMetadataNodes(context);
|
||||||
|
ResetMetadataSyncMemoryContext(context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ProcessBatchCommandsToSingleNode does the same as operation
|
||||||
|
* ProcessBatchCommandsToActivatedNodes but for only given node.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
ProcessBatchCommandsToSingleNode(MetadataSyncContext *context, int nodeIdx,
|
||||||
|
bool forceSend)
|
||||||
|
{
|
||||||
|
/* do not send and reset commands if we are in noConnectionMode */
|
||||||
|
if (MetadataSyncInNoConnectionMode(context))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (forceSend || ExceedsSyncBatchCount(context))
|
||||||
|
{
|
||||||
|
SendCollectedCommandsToSingleNode(context, nodeIdx);
|
||||||
|
ResetMetadataSyncMemoryContext(context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ResetMetadataSyncMemoryContext resets memory context inside metadataSyncContext.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
ResetMetadataSyncMemoryContext(MetadataSyncContext *context)
|
||||||
|
{
|
||||||
|
Assert(!MetadataSyncInNoConnectionMode(context));
|
||||||
|
MemoryContextReset(context->context);
|
||||||
|
context->collectedCommands = NIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* CollectCommandIntoMetadataSyncContext collcets given commands into metadataSyncContext.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
CollectCommandIntoMetadataSyncContext(MetadataSyncContext *context, List *commandList)
|
||||||
|
{
|
||||||
|
context->collectedCommands = list_concat(context->collectedCommands, commandList);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MetadataSyncInNoConnectionMode returns whether context is used for collecting
|
||||||
|
* commands instead of sending them to workers.
|
||||||
|
*/
|
||||||
|
bool
|
||||||
|
MetadataSyncInNoConnectionMode(MetadataSyncContext *context)
|
||||||
|
{
|
||||||
|
return context->noConnectionMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SendCollectedCommandsToActivatedNodes sends collected commands to the activated
|
||||||
|
* nodes with bare connections inside metadatacontext or via coordinated connections.
|
||||||
|
* Note that when we are in noConnectionMode, we add commands into the context without
|
||||||
|
* sending the commands.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
SendCollectedCommandsToActivatedNodes(MetadataSyncContext *context)
|
||||||
|
{
|
||||||
|
Assert(!MetadataSyncInNoConnectionMode(context));
|
||||||
|
|
||||||
|
/* do nothing if no commands */
|
||||||
|
List *commands = context->collectedCommands;
|
||||||
|
if (commands == NIL)
|
||||||
{
|
{
|
||||||
context->collectedCommands = list_concat(context->collectedCommands, commands);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4111,9 +4223,11 @@ SendOrCollectCommandListToActivatedNodes(MetadataSyncContext *context, List *com
|
||||||
if (context->transactionMode == METADATA_SYNC_TRANSACTIONAL)
|
if (context->transactionMode == METADATA_SYNC_TRANSACTIONAL)
|
||||||
{
|
{
|
||||||
List *workerNodes = context->activatedWorkerNodeList;
|
List *workerNodes = context->activatedWorkerNodeList;
|
||||||
SendMetadataCommandListToWorkerListInCoordinatedTransaction(workerNodes,
|
ExecuteCommandListOnWorkerList(commands, workerNodes);
|
||||||
CurrentUserName(),
|
|
||||||
commands);
|
/* SendMetadataCommandListToWorkerListInCoordinatedTransaction(workerNodes, */
|
||||||
|
/* CurrentUserName(), */
|
||||||
|
/* commands); */
|
||||||
}
|
}
|
||||||
else if (context->transactionMode == METADATA_SYNC_NON_TRANSACTIONAL)
|
else if (context->transactionMode == METADATA_SYNC_NON_TRANSACTIONAL)
|
||||||
{
|
{
|
||||||
|
@ -4128,22 +4242,20 @@ SendOrCollectCommandListToActivatedNodes(MetadataSyncContext *context, List *com
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* SendOrCollectCommandListToMetadataNodes sends the commands to the metadata nodes with
|
* SendCollectedCommandsToMetadataNodes sends collected commands to the metadata
|
||||||
* bare connections inside metadatacontext or via coordinated connections.
|
* nodes with bare connections inside metadatacontext or via coordinated connections.
|
||||||
* Note that when context only collects commands, we add commands into the context
|
* Note that when we are in noConnectionMode, we add commands into the context without
|
||||||
* without sending the commands.
|
* sending the commands.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
SendOrCollectCommandListToMetadataNodes(MetadataSyncContext *context, List *commands)
|
SendCollectedCommandsToMetadataNodes(MetadataSyncContext *context)
|
||||||
{
|
{
|
||||||
/*
|
Assert(!MetadataSyncInNoConnectionMode(context));
|
||||||
* do not send any command to workers if we collcet commands.
|
|
||||||
* Collect commands into metadataSyncContext's collected command
|
/* do nothing if no commands */
|
||||||
* list.
|
List *commands = context->collectedCommands;
|
||||||
*/
|
if (commands == NIL)
|
||||||
if (MetadataSyncCollectsCommands(context))
|
|
||||||
{
|
{
|
||||||
context->collectedCommands = list_concat(context->collectedCommands, commands);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4154,9 +4266,11 @@ SendOrCollectCommandListToMetadataNodes(MetadataSyncContext *context, List *comm
|
||||||
{
|
{
|
||||||
List *metadataNodes = TargetWorkerSetNodeList(NON_COORDINATOR_METADATA_NODES,
|
List *metadataNodes = TargetWorkerSetNodeList(NON_COORDINATOR_METADATA_NODES,
|
||||||
RowShareLock);
|
RowShareLock);
|
||||||
SendMetadataCommandListToWorkerListInCoordinatedTransaction(metadataNodes,
|
ExecuteCommandListOnWorkerList(commands, metadataNodes);
|
||||||
CurrentUserName(),
|
|
||||||
commands);
|
/* SendMetadataCommandListToWorkerListInCoordinatedTransaction(metadataNodes, */
|
||||||
|
/* CurrentUserName(), */
|
||||||
|
/* commands); */
|
||||||
}
|
}
|
||||||
else if (context->transactionMode == METADATA_SYNC_NON_TRANSACTIONAL)
|
else if (context->transactionMode == METADATA_SYNC_NON_TRANSACTIONAL)
|
||||||
{
|
{
|
||||||
|
@ -4170,23 +4284,20 @@ SendOrCollectCommandListToMetadataNodes(MetadataSyncContext *context, List *comm
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* SendOrCollectCommandListToSingleNode sends the commands to the specific worker
|
* SendCollectedCommandsToSingleNode sends collected commands to the specific worker
|
||||||
* indexed by nodeIdx with bare connection inside metadatacontext or via coordinated
|
* indexed by nodeIdx with bare connection inside metadatacontext or via coordinated
|
||||||
* connection. Note that when context only collects commands, we add commands into
|
* connection. Note that when we are in noConnectionMode, we add commands into
|
||||||
* the context without sending the commands.
|
* the context without sending the commands.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
SendOrCollectCommandListToSingleNode(MetadataSyncContext *context, List *commands,
|
SendCollectedCommandsToSingleNode(MetadataSyncContext *context, int nodeIdx)
|
||||||
int nodeIdx)
|
|
||||||
{
|
{
|
||||||
/*
|
Assert(!MetadataSyncInNoConnectionMode(context));
|
||||||
* Do not send any command to workers if we collect commands.
|
|
||||||
* Collect commands into metadataSyncContext's collected command
|
/* do nothing if no commands */
|
||||||
* list.
|
List *commands = context->collectedCommands;
|
||||||
*/
|
if (commands == NIL)
|
||||||
if (MetadataSyncCollectsCommands(context))
|
|
||||||
{
|
{
|
||||||
context->collectedCommands = list_concat(context->collectedCommands, commands);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4199,9 +4310,11 @@ SendOrCollectCommandListToSingleNode(MetadataSyncContext *context, List *command
|
||||||
Assert(nodeIdx < list_length(workerNodes));
|
Assert(nodeIdx < list_length(workerNodes));
|
||||||
|
|
||||||
WorkerNode *node = list_nth(workerNodes, nodeIdx);
|
WorkerNode *node = list_nth(workerNodes, nodeIdx);
|
||||||
SendMetadataCommandListToWorkerListInCoordinatedTransaction(list_make1(node),
|
ExecuteCommandListOnWorkerList(commands, list_make1(node));
|
||||||
CurrentUserName(),
|
|
||||||
commands);
|
/* SendMetadataCommandListToWorkerListInCoordinatedTransaction(list_make1(node), */
|
||||||
|
/* CurrentUserName(), */
|
||||||
|
/* commands); */
|
||||||
}
|
}
|
||||||
else if (context->transactionMode == METADATA_SYNC_NON_TRANSACTIONAL)
|
else if (context->transactionMode == METADATA_SYNC_NON_TRANSACTIONAL)
|
||||||
{
|
{
|
||||||
|
@ -4243,7 +4356,6 @@ WorkerDropAllShellTablesCommand(bool singleTransaction)
|
||||||
static List *
|
static List *
|
||||||
PropagateNodeWideObjectsCommandList(void)
|
PropagateNodeWideObjectsCommandList(void)
|
||||||
{
|
{
|
||||||
/* collect all commands */
|
|
||||||
List *ddlCommands = NIL;
|
List *ddlCommands = NIL;
|
||||||
|
|
||||||
if (EnableAlterRoleSetPropagation)
|
if (EnableAlterRoleSetPropagation)
|
||||||
|
@ -4330,17 +4442,24 @@ SyncDistributedObjects(MetadataSyncContext *context)
|
||||||
void
|
void
|
||||||
SendNodeWideObjectsSyncCommands(MetadataSyncContext *context)
|
SendNodeWideObjectsSyncCommands(MetadataSyncContext *context)
|
||||||
{
|
{
|
||||||
|
MemoryContext oldContext = MemoryContextSwitchTo(context->context);
|
||||||
|
|
||||||
/* propagate node wide objects. It includes only roles for now. */
|
/* propagate node wide objects. It includes only roles for now. */
|
||||||
List *commandList = PropagateNodeWideObjectsCommandList();
|
List *commandList = PropagateNodeWideObjectsCommandList();
|
||||||
|
|
||||||
if (commandList == NIL)
|
if (commandList == NIL)
|
||||||
{
|
{
|
||||||
|
MemoryContextSwitchTo(oldContext);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
commandList = lcons(DISABLE_DDL_PROPAGATION, commandList);
|
commandList = lcons(DISABLE_DDL_PROPAGATION, commandList);
|
||||||
commandList = lappend(commandList, ENABLE_DDL_PROPAGATION);
|
commandList = lappend(commandList, ENABLE_DDL_PROPAGATION);
|
||||||
SendOrCollectCommandListToActivatedNodes(context, commandList);
|
|
||||||
|
bool forceSend = true;
|
||||||
|
CollectCommandIntoMetadataSyncContext(context, commandList);
|
||||||
|
ProcessBatchCommandsToActivatedNodes(context, forceSend);
|
||||||
|
MemoryContextSwitchTo(oldContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -4352,14 +4471,22 @@ SendNodeWideObjectsSyncCommands(MetadataSyncContext *context)
|
||||||
void
|
void
|
||||||
SendShellTableDeletionCommands(MetadataSyncContext *context)
|
SendShellTableDeletionCommands(MetadataSyncContext *context)
|
||||||
{
|
{
|
||||||
|
bool forceSend = true;
|
||||||
|
|
||||||
|
MemoryContext oldContext = MemoryContextSwitchTo(context->context);
|
||||||
|
|
||||||
/* break all sequence deps for citus tables and remove all shell tables */
|
/* break all sequence deps for citus tables and remove all shell tables */
|
||||||
char *breakSeqDepsCommand = BREAK_CITUS_TABLE_SEQUENCE_DEPENDENCY_COMMAND;
|
char *breakSeqDepsCommand = BREAK_CITUS_TABLE_SEQUENCE_DEPENDENCY_COMMAND;
|
||||||
SendOrCollectCommandListToActivatedNodes(context, list_make1(breakSeqDepsCommand));
|
CollectCommandIntoMetadataSyncContext(context, list_make1(breakSeqDepsCommand));
|
||||||
|
ProcessBatchCommandsToActivatedNodes(context, forceSend);
|
||||||
|
|
||||||
/* remove shell tables */
|
/* remove shell tables */
|
||||||
bool singleTransaction = (context->transactionMode == METADATA_SYNC_TRANSACTIONAL);
|
bool singleTransaction = (context->transactionMode == METADATA_SYNC_TRANSACTIONAL);
|
||||||
char *dropShellTablesCommand = WorkerDropAllShellTablesCommand(singleTransaction);
|
char *dropShellTablesCommand = WorkerDropAllShellTablesCommand(singleTransaction);
|
||||||
SendOrCollectCommandListToActivatedNodes(context, list_make1(dropShellTablesCommand));
|
CollectCommandIntoMetadataSyncContext(context, list_make1(dropShellTablesCommand));
|
||||||
|
ProcessBatchCommandsToActivatedNodes(context, forceSend);
|
||||||
|
|
||||||
|
MemoryContextSwitchTo(oldContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -4371,21 +4498,27 @@ SendShellTableDeletionCommands(MetadataSyncContext *context)
|
||||||
void
|
void
|
||||||
SendMetadataDeletionCommands(MetadataSyncContext *context)
|
SendMetadataDeletionCommands(MetadataSyncContext *context)
|
||||||
{
|
{
|
||||||
|
MemoryContext oldContext = MemoryContextSwitchTo(context->context);
|
||||||
|
|
||||||
/* remove pg_dist_partition entries */
|
/* remove pg_dist_partition entries */
|
||||||
SendOrCollectCommandListToActivatedNodes(context, list_make1(DELETE_ALL_PARTITIONS));
|
CollectCommandIntoMetadataSyncContext(context, list_make1(DELETE_ALL_PARTITIONS));
|
||||||
|
|
||||||
/* remove pg_dist_shard entries */
|
/* remove pg_dist_shard entries */
|
||||||
SendOrCollectCommandListToActivatedNodes(context, list_make1(DELETE_ALL_SHARDS));
|
CollectCommandIntoMetadataSyncContext(context, list_make1(DELETE_ALL_SHARDS));
|
||||||
|
|
||||||
/* remove pg_dist_placement entries */
|
/* remove pg_dist_placement entries */
|
||||||
SendOrCollectCommandListToActivatedNodes(context, list_make1(DELETE_ALL_PLACEMENTS));
|
CollectCommandIntoMetadataSyncContext(context, list_make1(DELETE_ALL_PLACEMENTS));
|
||||||
|
|
||||||
/* remove pg_dist_object entries */
|
/* remove pg_dist_object entries */
|
||||||
SendOrCollectCommandListToActivatedNodes(context,
|
CollectCommandIntoMetadataSyncContext(context,
|
||||||
list_make1(DELETE_ALL_DISTRIBUTED_OBJECTS));
|
list_make1(DELETE_ALL_DISTRIBUTED_OBJECTS));
|
||||||
|
|
||||||
/* remove pg_dist_colocation entries */
|
/* remove pg_dist_colocation entries */
|
||||||
SendOrCollectCommandListToActivatedNodes(context, list_make1(DELETE_ALL_COLOCATION));
|
CollectCommandIntoMetadataSyncContext(context, list_make1(DELETE_ALL_COLOCATION));
|
||||||
|
|
||||||
|
bool forceSend = true;
|
||||||
|
ProcessBatchCommandsToActivatedNodes(context, forceSend);
|
||||||
|
MemoryContextSwitchTo(oldContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -4396,6 +4529,7 @@ SendMetadataDeletionCommands(MetadataSyncContext *context)
|
||||||
void
|
void
|
||||||
SendColocationMetadataCommands(MetadataSyncContext *context)
|
SendColocationMetadataCommands(MetadataSyncContext *context)
|
||||||
{
|
{
|
||||||
|
bool forceSend = false;
|
||||||
ScanKeyData scanKey[1];
|
ScanKeyData scanKey[1];
|
||||||
int scanKeyCount = 0;
|
int scanKeyCount = 0;
|
||||||
|
|
||||||
|
@ -4407,11 +4541,12 @@ SendColocationMetadataCommands(MetadataSyncContext *context)
|
||||||
HeapTuple nextTuple = NULL;
|
HeapTuple nextTuple = NULL;
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
ResetMetadataSyncMemoryContext(context);
|
|
||||||
|
|
||||||
nextTuple = systable_getnext(scanDesc);
|
nextTuple = systable_getnext(scanDesc);
|
||||||
if (!HeapTupleIsValid(nextTuple))
|
if (!HeapTupleIsValid(nextTuple))
|
||||||
{
|
{
|
||||||
|
/* send if we have commands that are not sent */
|
||||||
|
forceSend = true;
|
||||||
|
ProcessBatchCommandsToActivatedNodes(context, forceSend);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4476,7 +4611,8 @@ SendColocationMetadataCommands(MetadataSyncContext *context)
|
||||||
" = c.collnamespace)");
|
" = c.collnamespace)");
|
||||||
|
|
||||||
List *commandList = list_make1(colocationGroupCreateCommand->data);
|
List *commandList = list_make1(colocationGroupCreateCommand->data);
|
||||||
SendOrCollectCommandListToActivatedNodes(context, commandList);
|
CollectCommandIntoMetadataSyncContext(context, commandList);
|
||||||
|
ProcessBatchCommandsToActivatedNodes(context, forceSend);
|
||||||
}
|
}
|
||||||
MemoryContextSwitchTo(oldContext);
|
MemoryContextSwitchTo(oldContext);
|
||||||
|
|
||||||
|
@ -4493,11 +4629,14 @@ SendColocationMetadataCommands(MetadataSyncContext *context)
|
||||||
void
|
void
|
||||||
SendDependencyCreationCommands(MetadataSyncContext *context)
|
SendDependencyCreationCommands(MetadataSyncContext *context)
|
||||||
{
|
{
|
||||||
/* disable ddl propagation */
|
/*
|
||||||
SendOrCollectCommandListToActivatedNodes(context,
|
* We need to preserve collected dependencies as we reset memory context
|
||||||
list_make1(DISABLE_DDL_PROPAGATION));
|
* inside metadataSyncContext during commands generation below.
|
||||||
|
*/
|
||||||
MemoryContext oldContext = MemoryContextSwitchTo(context->context);
|
MemoryContext dependencyContext = AllocSetContextCreate(CurrentMemoryContext,
|
||||||
|
"dependency context",
|
||||||
|
ALLOCSET_DEFAULT_SIZES);
|
||||||
|
MemoryContext oldContext = MemoryContextSwitchTo(dependencyContext);
|
||||||
|
|
||||||
/* collect all dependencies in creation order and get their ddl commands */
|
/* collect all dependencies in creation order and get their ddl commands */
|
||||||
List *dependencies = GetDistributedObjectAddressList();
|
List *dependencies = GetDistributedObjectAddressList();
|
||||||
|
@ -4512,22 +4651,16 @@ SendDependencyCreationCommands(MetadataSyncContext *context)
|
||||||
|
|
||||||
dependencies = OrderObjectAddressListInDependencyOrder(dependencies);
|
dependencies = OrderObjectAddressListInDependencyOrder(dependencies);
|
||||||
|
|
||||||
/*
|
MemoryContextSwitchTo(context->context);
|
||||||
* We need to create a subcontext as we reset the context after each dependency
|
|
||||||
* creation but we want to preserve all dependency objects at metadataSyncContext.
|
/* disable ddl propagation */
|
||||||
*/
|
bool forceSend = true;
|
||||||
MemoryContext commandsContext = AllocSetContextCreate(context->context,
|
CollectCommandIntoMetadataSyncContext(context, list_make1(DISABLE_DDL_PROPAGATION));
|
||||||
"dependency commands context",
|
ProcessBatchCommandsToActivatedNodes(context, forceSend);
|
||||||
ALLOCSET_DEFAULT_SIZES);
|
|
||||||
MemoryContextSwitchTo(commandsContext);
|
|
||||||
ObjectAddress *dependency = NULL;
|
ObjectAddress *dependency = NULL;
|
||||||
foreach_ptr(dependency, dependencies)
|
foreach_ptr(dependency, dependencies)
|
||||||
{
|
{
|
||||||
if (!MetadataSyncCollectsCommands(context))
|
|
||||||
{
|
|
||||||
MemoryContextReset(commandsContext);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (IsAnyObjectAddressOwnedByExtension(list_make1(dependency), NULL))
|
if (IsAnyObjectAddressOwnedByExtension(list_make1(dependency), NULL))
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
@ -4538,19 +4671,18 @@ SendDependencyCreationCommands(MetadataSyncContext *context)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* dependency creation commands */
|
/* dependency creation commands */
|
||||||
|
forceSend = false;
|
||||||
List *ddlCommands = GetAllDependencyCreateDDLCommands(list_make1(dependency));
|
List *ddlCommands = GetAllDependencyCreateDDLCommands(list_make1(dependency));
|
||||||
SendOrCollectCommandListToActivatedNodes(context, ddlCommands);
|
CollectCommandIntoMetadataSyncContext(context, ddlCommands);
|
||||||
|
ProcessBatchCommandsToActivatedNodes(context, forceSend);
|
||||||
}
|
}
|
||||||
MemoryContextSwitchTo(oldContext);
|
|
||||||
|
|
||||||
if (!MetadataSyncCollectsCommands(context))
|
|
||||||
{
|
|
||||||
MemoryContextDelete(commandsContext);
|
|
||||||
}
|
|
||||||
ResetMetadataSyncMemoryContext(context);
|
|
||||||
|
|
||||||
/* enable ddl propagation */
|
/* enable ddl propagation */
|
||||||
SendOrCollectCommandListToActivatedNodes(context, list_make1(ENABLE_DDL_PROPAGATION));
|
forceSend = true;
|
||||||
|
CollectCommandIntoMetadataSyncContext(context, list_make1(ENABLE_DDL_PROPAGATION));
|
||||||
|
ProcessBatchCommandsToActivatedNodes(context, forceSend);
|
||||||
|
MemoryContextSwitchTo(oldContext);
|
||||||
|
MemoryContextDelete(dependencyContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -4562,6 +4694,7 @@ SendDependencyCreationCommands(MetadataSyncContext *context)
|
||||||
void
|
void
|
||||||
SendDistTableMetadataCommands(MetadataSyncContext *context)
|
SendDistTableMetadataCommands(MetadataSyncContext *context)
|
||||||
{
|
{
|
||||||
|
bool forceSend = false;
|
||||||
ScanKeyData scanKey[1];
|
ScanKeyData scanKey[1];
|
||||||
int scanKeyCount = 0;
|
int scanKeyCount = 0;
|
||||||
|
|
||||||
|
@ -4575,11 +4708,12 @@ SendDistTableMetadataCommands(MetadataSyncContext *context)
|
||||||
HeapTuple nextTuple = NULL;
|
HeapTuple nextTuple = NULL;
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
ResetMetadataSyncMemoryContext(context);
|
|
||||||
|
|
||||||
nextTuple = systable_getnext(scanDesc);
|
nextTuple = systable_getnext(scanDesc);
|
||||||
if (!HeapTupleIsValid(nextTuple))
|
if (!HeapTupleIsValid(nextTuple))
|
||||||
{
|
{
|
||||||
|
/* send if we have commands that are not sent */
|
||||||
|
forceSend = true;
|
||||||
|
ProcessBatchCommandsToActivatedNodes(context, forceSend);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4594,7 +4728,8 @@ SendDistTableMetadataCommands(MetadataSyncContext *context)
|
||||||
}
|
}
|
||||||
|
|
||||||
List *commandList = CitusTableMetadataCreateCommandList(relationId);
|
List *commandList = CitusTableMetadataCreateCommandList(relationId);
|
||||||
SendOrCollectCommandListToActivatedNodes(context, commandList);
|
CollectCommandIntoMetadataSyncContext(context, commandList);
|
||||||
|
ProcessBatchCommandsToActivatedNodes(context, forceSend);
|
||||||
}
|
}
|
||||||
MemoryContextSwitchTo(oldContext);
|
MemoryContextSwitchTo(oldContext);
|
||||||
|
|
||||||
|
@ -4611,6 +4746,7 @@ SendDistTableMetadataCommands(MetadataSyncContext *context)
|
||||||
void
|
void
|
||||||
SendDistObjectCommands(MetadataSyncContext *context)
|
SendDistObjectCommands(MetadataSyncContext *context)
|
||||||
{
|
{
|
||||||
|
bool forceSend = false;
|
||||||
ScanKeyData scanKey[1];
|
ScanKeyData scanKey[1];
|
||||||
int scanKeyCount = 0;
|
int scanKeyCount = 0;
|
||||||
|
|
||||||
|
@ -4624,11 +4760,12 @@ SendDistObjectCommands(MetadataSyncContext *context)
|
||||||
HeapTuple nextTuple = NULL;
|
HeapTuple nextTuple = NULL;
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
ResetMetadataSyncMemoryContext(context);
|
|
||||||
|
|
||||||
nextTuple = systable_getnext(scanDesc);
|
nextTuple = systable_getnext(scanDesc);
|
||||||
if (!HeapTupleIsValid(nextTuple))
|
if (!HeapTupleIsValid(nextTuple))
|
||||||
{
|
{
|
||||||
|
/* send if we have commands that are not sent */
|
||||||
|
forceSend = true;
|
||||||
|
ProcessBatchCommandsToActivatedNodes(context, forceSend);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4678,13 +4815,15 @@ SendDistObjectCommands(MetadataSyncContext *context)
|
||||||
forceDelegation = NO_FORCE_PUSHDOWN;
|
forceDelegation = NO_FORCE_PUSHDOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
forceSend = false;
|
||||||
char *workerMetadataUpdateCommand =
|
char *workerMetadataUpdateCommand =
|
||||||
MarkObjectsDistributedCreateCommand(list_make1(address),
|
MarkObjectsDistributedCreateCommand(list_make1(address),
|
||||||
list_make1_int(distributionArgumentIndex),
|
list_make1_int(distributionArgumentIndex),
|
||||||
list_make1_int(colocationId),
|
list_make1_int(colocationId),
|
||||||
list_make1_int(forceDelegation));
|
list_make1_int(forceDelegation));
|
||||||
SendOrCollectCommandListToActivatedNodes(context,
|
List *commandList = list_make1(workerMetadataUpdateCommand);
|
||||||
list_make1(workerMetadataUpdateCommand));
|
CollectCommandIntoMetadataSyncContext(context, commandList);
|
||||||
|
ProcessBatchCommandsToActivatedNodes(context, forceSend);
|
||||||
}
|
}
|
||||||
MemoryContextSwitchTo(oldContext);
|
MemoryContextSwitchTo(oldContext);
|
||||||
|
|
||||||
|
@ -4702,10 +4841,6 @@ SendDistObjectCommands(MetadataSyncContext *context)
|
||||||
void
|
void
|
||||||
SendInterTableRelationshipCommands(MetadataSyncContext *context)
|
SendInterTableRelationshipCommands(MetadataSyncContext *context)
|
||||||
{
|
{
|
||||||
/* disable ddl propagation */
|
|
||||||
SendOrCollectCommandListToActivatedNodes(context,
|
|
||||||
list_make1(DISABLE_DDL_PROPAGATION));
|
|
||||||
|
|
||||||
ScanKeyData scanKey[1];
|
ScanKeyData scanKey[1];
|
||||||
int scanKeyCount = 0;
|
int scanKeyCount = 0;
|
||||||
|
|
||||||
|
@ -4716,11 +4851,15 @@ SendInterTableRelationshipCommands(MetadataSyncContext *context)
|
||||||
scanKeyCount, scanKey);
|
scanKeyCount, scanKey);
|
||||||
|
|
||||||
MemoryContext oldContext = MemoryContextSwitchTo(context->context);
|
MemoryContext oldContext = MemoryContextSwitchTo(context->context);
|
||||||
|
|
||||||
|
/* disable ddl propagation */
|
||||||
|
bool forceSend = true;
|
||||||
|
CollectCommandIntoMetadataSyncContext(context, list_make1(DISABLE_DDL_PROPAGATION));
|
||||||
|
ProcessBatchCommandsToActivatedNodes(context, forceSend);
|
||||||
|
|
||||||
HeapTuple nextTuple = NULL;
|
HeapTuple nextTuple = NULL;
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
ResetMetadataSyncMemoryContext(context);
|
|
||||||
|
|
||||||
nextTuple = systable_getnext(scanDesc);
|
nextTuple = systable_getnext(scanDesc);
|
||||||
if (!HeapTupleIsValid(nextTuple))
|
if (!HeapTupleIsValid(nextTuple))
|
||||||
{
|
{
|
||||||
|
@ -4742,14 +4881,18 @@ SendInterTableRelationshipCommands(MetadataSyncContext *context)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
forceSend = false;
|
||||||
List *commandList = InterTableRelationshipOfRelationCommandList(relationId);
|
List *commandList = InterTableRelationshipOfRelationCommandList(relationId);
|
||||||
SendOrCollectCommandListToActivatedNodes(context, commandList);
|
CollectCommandIntoMetadataSyncContext(context, commandList);
|
||||||
|
ProcessBatchCommandsToActivatedNodes(context, forceSend);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* enable ddl propagation */
|
||||||
|
forceSend = true;
|
||||||
|
CollectCommandIntoMetadataSyncContext(context, list_make1(ENABLE_DDL_PROPAGATION));
|
||||||
|
ProcessBatchCommandsToActivatedNodes(context, forceSend);
|
||||||
MemoryContextSwitchTo(oldContext);
|
MemoryContextSwitchTo(oldContext);
|
||||||
|
|
||||||
systable_endscan(scanDesc);
|
systable_endscan(scanDesc);
|
||||||
table_close(relation, AccessShareLock);
|
table_close(relation, AccessShareLock);
|
||||||
|
|
||||||
/* enable ddl propagation */
|
|
||||||
SendOrCollectCommandListToActivatedNodes(context, list_make1(ENABLE_DDL_PROPAGATION));
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -762,11 +762,11 @@ citus_activate_node(PG_FUNCTION_ARGS)
|
||||||
* It contains activated nodes, bare connections if the mode is nontransactional,
|
* It contains activated nodes, bare connections if the mode is nontransactional,
|
||||||
* and a memory context for allocation.
|
* and a memory context for allocation.
|
||||||
*/
|
*/
|
||||||
bool collectCommands = false;
|
|
||||||
bool nodesAddedInSameTransaction = false;
|
bool nodesAddedInSameTransaction = false;
|
||||||
|
bool noConnectionMode = false;
|
||||||
MetadataSyncContext *context = CreateMetadataSyncContext(list_make1(workerNode),
|
MetadataSyncContext *context = CreateMetadataSyncContext(list_make1(workerNode),
|
||||||
collectCommands,
|
nodesAddedInSameTransaction,
|
||||||
nodesAddedInSameTransaction);
|
noConnectionMode);
|
||||||
|
|
||||||
ActivateNodeList(context);
|
ActivateNodeList(context);
|
||||||
TransactionModifiedNodeMetadata = true;
|
TransactionModifiedNodeMetadata = true;
|
||||||
|
@ -932,7 +932,7 @@ MarkNodesNotSyncedInLoopBackConnection(MetadataSyncContext *context,
|
||||||
pid_t parentSessionPid)
|
pid_t parentSessionPid)
|
||||||
{
|
{
|
||||||
Assert(context->transactionMode == METADATA_SYNC_NON_TRANSACTIONAL);
|
Assert(context->transactionMode == METADATA_SYNC_NON_TRANSACTIONAL);
|
||||||
Assert(!MetadataSyncCollectsCommands(context));
|
Assert(!MetadataSyncInNoConnectionMode(context));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set metadatasynced to false for all activated nodes to mark the nodes as not synced
|
* Set metadatasynced to false for all activated nodes to mark the nodes as not synced
|
||||||
|
@ -1000,8 +1000,8 @@ MarkNodesNotSyncedInLoopBackConnection(MetadataSyncContext *context,
|
||||||
static void
|
static void
|
||||||
SetNodeMetadata(MetadataSyncContext *context, bool localOnly)
|
SetNodeMetadata(MetadataSyncContext *context, bool localOnly)
|
||||||
{
|
{
|
||||||
/* do not execute local transaction if we collect commands */
|
/* do not execute local transaction if we are in noConnectionMode */
|
||||||
if (!MetadataSyncCollectsCommands(context))
|
if (!MetadataSyncInNoConnectionMode(context))
|
||||||
{
|
{
|
||||||
List *updatedActivatedNodeList = NIL;
|
List *updatedActivatedNodeList = NIL;
|
||||||
|
|
||||||
|
@ -1022,7 +1022,7 @@ SetNodeMetadata(MetadataSyncContext *context, bool localOnly)
|
||||||
SetMetadataSyncNodesFromNodeList(context, updatedActivatedNodeList);
|
SetMetadataSyncNodesFromNodeList(context, updatedActivatedNodeList);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!localOnly && EnableMetadataSync)
|
if (!localOnly)
|
||||||
{
|
{
|
||||||
WorkerNode *node = NULL;
|
WorkerNode *node = NULL;
|
||||||
foreach_ptr(node, context->activatedWorkerNodeList)
|
foreach_ptr(node, context->activatedWorkerNodeList)
|
||||||
|
@ -1040,7 +1040,7 @@ SetNodeMetadata(MetadataSyncContext *context, bool localOnly)
|
||||||
* The function operates in 3 different modes according to transactionMode inside
|
* The function operates in 3 different modes according to transactionMode inside
|
||||||
* metadataSyncContext.
|
* metadataSyncContext.
|
||||||
*
|
*
|
||||||
* 1. MetadataSyncCollectsCommands(context):
|
* 1. MetadataSyncInNoConnectionMode(context):
|
||||||
* Only collect commands instead of sending them to workers,
|
* Only collect commands instead of sending them to workers,
|
||||||
* 2. context.transactionMode == METADATA_SYNC_TRANSACTIONAL:
|
* 2. context.transactionMode == METADATA_SYNC_TRANSACTIONAL:
|
||||||
* Send all commands using coordinated transaction,
|
* Send all commands using coordinated transaction,
|
||||||
|
@ -1090,15 +1090,14 @@ ActivateNodeList(MetadataSyncContext *context)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* we need to unset metadatasynced flag to false at coordinator in separate
|
* we need to unset metadatasynced flag to false at coordinator in separate
|
||||||
* transaction only at nontransactional sync mode and if we do not collect
|
* transaction only at nontransactional sync mode and if are in noConnectionMode.
|
||||||
* commands.
|
|
||||||
*
|
*
|
||||||
* We make sure we set the flag to false at the start of nontransactional
|
* We make sure we set the flag to false at the start of nontransactional
|
||||||
* metadata sync to mark those nodes are not synced in case of a failure in
|
* metadata sync to mark those nodes are not synced in case of a failure in
|
||||||
* the middle of the sync.
|
* the middle of the sync.
|
||||||
*/
|
*/
|
||||||
if (context->transactionMode == METADATA_SYNC_NON_TRANSACTIONAL &&
|
if (context->transactionMode == METADATA_SYNC_NON_TRANSACTIONAL &&
|
||||||
!MetadataSyncCollectsCommands(context))
|
!MetadataSyncInNoConnectionMode(context))
|
||||||
{
|
{
|
||||||
MarkNodesNotSyncedInLoopBackConnection(context, MyProcPid);
|
MarkNodesNotSyncedInLoopBackConnection(context, MyProcPid);
|
||||||
}
|
}
|
||||||
|
@ -2201,16 +2200,19 @@ AddNodeMetadataViaMetadataContext(char *nodeName, int32 nodePort,
|
||||||
}
|
}
|
||||||
|
|
||||||
List *nodeList = list_make1(node);
|
List *nodeList = list_make1(node);
|
||||||
bool collectCommands = false;
|
|
||||||
bool nodesAddedInSameTransaction = true;
|
bool nodesAddedInSameTransaction = true;
|
||||||
MetadataSyncContext *context = CreateMetadataSyncContext(nodeList, collectCommands,
|
bool noConnectionMode = false;
|
||||||
nodesAddedInSameTransaction);
|
MetadataSyncContext *context = CreateMetadataSyncContext(nodeList,
|
||||||
|
nodesAddedInSameTransaction,
|
||||||
|
noConnectionMode);
|
||||||
|
|
||||||
if (EnableMetadataSync)
|
if (EnableMetadataSync)
|
||||||
{
|
{
|
||||||
|
MemoryContext oldContext = MemoryContextSwitchTo(context->context);
|
||||||
|
|
||||||
/* send the delete command to all primary nodes with metadata */
|
/* send the delete command to all primary nodes with metadata */
|
||||||
char *nodeDeleteCommand = NodeDeleteCommand(node->nodeId);
|
char *nodeDeleteCommand = NodeDeleteCommand(node->nodeId);
|
||||||
SendOrCollectCommandListToMetadataNodes(context, list_make1(nodeDeleteCommand));
|
CollectCommandIntoMetadataSyncContext(context, list_make1(nodeDeleteCommand));
|
||||||
|
|
||||||
/* finally prepare the insert command and send it to all primary nodes */
|
/* finally prepare the insert command and send it to all primary nodes */
|
||||||
uint32 primariesWithMetadata = CountPrimariesWithMetadata();
|
uint32 primariesWithMetadata = CountPrimariesWithMetadata();
|
||||||
|
@ -2230,9 +2232,12 @@ AddNodeMetadataViaMetadataContext(char *nodeName, int32 nodePort,
|
||||||
nodeInsertCommand = NodeListIdempotentInsertCommand(nodeList);
|
nodeInsertCommand = NodeListIdempotentInsertCommand(nodeList);
|
||||||
}
|
}
|
||||||
Assert(nodeInsertCommand != NULL);
|
Assert(nodeInsertCommand != NULL);
|
||||||
SendOrCollectCommandListToMetadataNodes(context,
|
CollectCommandIntoMetadataSyncContext(context, list_make1(nodeInsertCommand));
|
||||||
list_make1(nodeInsertCommand));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool forceSend = true;
|
||||||
|
ProcessBatchCommandsToMetadataNodes(context, forceSend);
|
||||||
|
MemoryContextSwitchTo(oldContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
ActivateNodeList(context);
|
ActivateNodeList(context);
|
||||||
|
@ -2273,6 +2278,8 @@ static void
|
||||||
SetNodeStateViaMetadataContext(MetadataSyncContext *context, WorkerNode *workerNode,
|
SetNodeStateViaMetadataContext(MetadataSyncContext *context, WorkerNode *workerNode,
|
||||||
Datum value)
|
Datum value)
|
||||||
{
|
{
|
||||||
|
MemoryContext oldContext = MemoryContextSwitchTo(context->context);
|
||||||
|
|
||||||
char *isActiveCommand =
|
char *isActiveCommand =
|
||||||
GetMetadataSyncCommandToSetNodeColumn(workerNode, Anum_pg_dist_node_isactive,
|
GetMetadataSyncCommandToSetNodeColumn(workerNode, Anum_pg_dist_node_isactive,
|
||||||
value);
|
value);
|
||||||
|
@ -2285,7 +2292,10 @@ SetNodeStateViaMetadataContext(MetadataSyncContext *context, WorkerNode *workerN
|
||||||
List *commandList = list_make3(isActiveCommand, metadatasyncedCommand,
|
List *commandList = list_make3(isActiveCommand, metadatasyncedCommand,
|
||||||
hasmetadataCommand);
|
hasmetadataCommand);
|
||||||
|
|
||||||
SendOrCollectCommandListToMetadataNodes(context, commandList);
|
bool forceSend = true;
|
||||||
|
CollectCommandIntoMetadataSyncContext(context, commandList);
|
||||||
|
ProcessBatchCommandsToMetadataNodes(context, forceSend);
|
||||||
|
MemoryContextSwitchTo(oldContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -3033,18 +3043,18 @@ ErrorIfAnyNodeNotExist(List *nodeList)
|
||||||
static void
|
static void
|
||||||
UpdateLocalGroupIdsViaMetadataContext(MetadataSyncContext *context)
|
UpdateLocalGroupIdsViaMetadataContext(MetadataSyncContext *context)
|
||||||
{
|
{
|
||||||
|
MemoryContext oldContext = MemoryContextSwitchTo(context->context);
|
||||||
|
bool forceSend = true;
|
||||||
int activatedPrimaryCount = list_length(context->activatedWorkerNodeList);
|
int activatedPrimaryCount = list_length(context->activatedWorkerNodeList);
|
||||||
int nodeIdx = 0;
|
int nodeIdx = 0;
|
||||||
for (nodeIdx = 0; nodeIdx < activatedPrimaryCount; nodeIdx++)
|
for (nodeIdx = 0; nodeIdx < activatedPrimaryCount; nodeIdx++)
|
||||||
{
|
{
|
||||||
WorkerNode *node = list_nth(context->activatedWorkerNodeList, nodeIdx);
|
WorkerNode *node = list_nth(context->activatedWorkerNodeList, nodeIdx);
|
||||||
List *commandList = list_make1(LocalGroupIdUpdateCommand(node->groupId));
|
List *commandList = list_make1(LocalGroupIdUpdateCommand(node->groupId));
|
||||||
|
CollectCommandIntoMetadataSyncContext(context, commandList);
|
||||||
/* send commands to new workers, the current user should be a superuser */
|
ProcessBatchCommandsToSingleNode(context, nodeIdx, forceSend);
|
||||||
Assert(superuser());
|
|
||||||
|
|
||||||
SendOrCollectCommandListToSingleNode(context, commandList, nodeIdx);
|
|
||||||
}
|
}
|
||||||
|
MemoryContextSwitchTo(oldContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -3089,7 +3099,7 @@ SyncNodeMetadata(MetadataSyncContext *context)
|
||||||
* Do not fail when we call this method from activate_node_snapshot
|
* Do not fail when we call this method from activate_node_snapshot
|
||||||
* from workers.
|
* from workers.
|
||||||
*/
|
*/
|
||||||
if (!MetadataSyncCollectsCommands(context))
|
if (!MetadataSyncInNoConnectionMode(context))
|
||||||
{
|
{
|
||||||
EnsureCoordinator();
|
EnsureCoordinator();
|
||||||
}
|
}
|
||||||
|
@ -3099,6 +3109,8 @@ SyncNodeMetadata(MetadataSyncContext *context)
|
||||||
|
|
||||||
LockRelationOid(DistNodeRelationId(), ExclusiveLock);
|
LockRelationOid(DistNodeRelationId(), ExclusiveLock);
|
||||||
|
|
||||||
|
MemoryContext oldContext = MemoryContextSwitchTo(context->context);
|
||||||
|
|
||||||
/* generate the queries which drop the node metadata */
|
/* generate the queries which drop the node metadata */
|
||||||
List *dropMetadataCommandList = NodeMetadataDropCommands();
|
List *dropMetadataCommandList = NodeMetadataDropCommands();
|
||||||
|
|
||||||
|
@ -3113,5 +3125,8 @@ SyncNodeMetadata(MetadataSyncContext *context)
|
||||||
* We should have already added node metadata to metadata workers. Sync node
|
* We should have already added node metadata to metadata workers. Sync node
|
||||||
* metadata just for activated workers.
|
* metadata just for activated workers.
|
||||||
*/
|
*/
|
||||||
SendOrCollectCommandListToActivatedNodes(context, recreateNodeSnapshotCommandList);
|
bool forceSend = true;
|
||||||
|
CollectCommandIntoMetadataSyncContext(context, recreateNodeSnapshotCommandList);
|
||||||
|
ProcessBatchCommandsToActivatedNodes(context, forceSend);
|
||||||
|
MemoryContextSwitchTo(oldContext);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1873,6 +1873,17 @@ RegisterCitusConfigVariables(void)
|
||||||
GUC_STANDARD,
|
GUC_STANDARD,
|
||||||
NULL, NULL, NULL);
|
NULL, NULL, NULL);
|
||||||
|
|
||||||
|
DefineCustomIntVariable(
|
||||||
|
"citus.metadata_sync_batch_size",
|
||||||
|
gettext_noop("Sets total number of commands in a batch for metadata syncs."),
|
||||||
|
gettext_noop("metadata sync commands are sent as batches configured by "
|
||||||
|
"the batch size to reduce network round trip delay."),
|
||||||
|
&MetadataSyncBatchCount,
|
||||||
|
METADATA_SYNC_DEFAULT_BATCH_COUNT, 1, 1000,
|
||||||
|
PGC_SUSET,
|
||||||
|
GUC_SUPERUSER_ONLY | GUC_NO_SHOW_ALL,
|
||||||
|
NULL, NULL, NULL);
|
||||||
|
|
||||||
DefineCustomIntVariable(
|
DefineCustomIntVariable(
|
||||||
"citus.metadata_sync_interval",
|
"citus.metadata_sync_interval",
|
||||||
gettext_noop("Sets the time to wait between metadata syncs."),
|
gettext_noop("Sets the time to wait between metadata syncs."),
|
||||||
|
|
|
@ -51,14 +51,14 @@ activate_node_snapshot(PG_FUNCTION_ARGS)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Create MetadataSyncContext which is used throughout nodes' activation.
|
* Create MetadataSyncContext which is used throughout nodes' activation.
|
||||||
* As we set collectCommands to true, it would not create connections to workers.
|
* As we set noConnectionMode to true, it would not establish connections to
|
||||||
* Instead it would collect and return sync commands to be sent to workers.
|
* workers. Instead it would collect and return sync commands to be sent to workers.
|
||||||
*/
|
*/
|
||||||
bool collectCommands = true;
|
|
||||||
bool nodesAddedInSameTransaction = false;
|
bool nodesAddedInSameTransaction = false;
|
||||||
|
bool noConnectionMode = true;
|
||||||
MetadataSyncContext *context = CreateMetadataSyncContext(list_make1(dummyWorkerNode),
|
MetadataSyncContext *context = CreateMetadataSyncContext(list_make1(dummyWorkerNode),
|
||||||
collectCommands,
|
nodesAddedInSameTransaction,
|
||||||
nodesAddedInSameTransaction);
|
noConnectionMode);
|
||||||
|
|
||||||
ActivateNodeList(context);
|
ActivateNodeList(context);
|
||||||
|
|
||||||
|
|
|
@ -624,6 +624,7 @@ DeleteAllReplicatedTablePlacementsFromNodeGroupViaMetadataContext(
|
||||||
}
|
}
|
||||||
|
|
||||||
MemoryContext oldContext = MemoryContextSwitchTo(context->context);
|
MemoryContext oldContext = MemoryContextSwitchTo(context->context);
|
||||||
|
bool forceSend = false;
|
||||||
GroupShardPlacement *placement = NULL;
|
GroupShardPlacement *placement = NULL;
|
||||||
foreach_ptr(placement, replicatedPlacementListForGroup)
|
foreach_ptr(placement, replicatedPlacementListForGroup)
|
||||||
{
|
{
|
||||||
|
@ -633,18 +634,16 @@ DeleteAllReplicatedTablePlacementsFromNodeGroupViaMetadataContext(
|
||||||
{
|
{
|
||||||
char *deletePlacementCommand =
|
char *deletePlacementCommand =
|
||||||
DeleteShardPlacementCommand(placement->placementId);
|
DeleteShardPlacementCommand(placement->placementId);
|
||||||
|
List *commandList = list_make1(deletePlacementCommand);
|
||||||
SendOrCollectCommandListToMetadataNodes(context,
|
CollectCommandIntoMetadataSyncContext(context, commandList);
|
||||||
list_make1(deletePlacementCommand));
|
ProcessBatchCommandsToMetadataNodes(context, forceSend);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* do not execute local transaction if we collect commands */
|
/* do not execute local transaction if we collect commands */
|
||||||
if (!MetadataSyncCollectsCommands(context))
|
if (!MetadataSyncInNoConnectionMode(context))
|
||||||
{
|
{
|
||||||
DeleteShardPlacementRow(placement->placementId);
|
DeleteShardPlacementRow(placement->placementId);
|
||||||
}
|
}
|
||||||
|
|
||||||
ResetMetadataSyncMemoryContext(context);
|
|
||||||
}
|
}
|
||||||
MemoryContextSwitchTo(oldContext);
|
MemoryContextSwitchTo(oldContext);
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,8 @@
|
||||||
#include "distributed/metadata_cache.h"
|
#include "distributed/metadata_cache.h"
|
||||||
#include "nodes/pg_list.h"
|
#include "nodes/pg_list.h"
|
||||||
|
|
||||||
|
#define METADATA_SYNC_DEFAULT_BATCH_COUNT 10
|
||||||
|
|
||||||
/* managed via guc.c */
|
/* managed via guc.c */
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
|
@ -29,6 +31,7 @@ typedef enum
|
||||||
extern int MetadataSyncInterval;
|
extern int MetadataSyncInterval;
|
||||||
extern int MetadataSyncRetryInterval;
|
extern int MetadataSyncRetryInterval;
|
||||||
extern int MetadataSyncTransMode;
|
extern int MetadataSyncTransMode;
|
||||||
|
extern int MetadataSyncBatchCount;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* MetadataSyncContext is used throughout metadata sync.
|
* MetadataSyncContext is used throughout metadata sync.
|
||||||
|
@ -39,9 +42,9 @@ typedef struct MetadataSyncContext
|
||||||
List *activatedWorkerBareConnections; /* bare connections to activated nodes */
|
List *activatedWorkerBareConnections; /* bare connections to activated nodes */
|
||||||
MemoryContext context; /* memory context for all allocations */
|
MemoryContext context; /* memory context for all allocations */
|
||||||
MetadataSyncTransactionMode transactionMode; /* transaction mode for the sync */
|
MetadataSyncTransactionMode transactionMode; /* transaction mode for the sync */
|
||||||
bool collectCommands; /* if we collect commands instead of sending and resetting */
|
List *collectedCommands; /* collected commands. */
|
||||||
List *collectedCommands; /* collected commands. (NIL if collectCommands == false) */
|
|
||||||
bool nodesAddedInSameTransaction; /* if the nodes are added just before activation */
|
bool nodesAddedInSameTransaction; /* if the nodes are added just before activation */
|
||||||
|
bool noConnectionMode; /* should we establish connections or just collect commands */
|
||||||
} MetadataSyncContext;
|
} MetadataSyncContext;
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
|
@ -139,19 +142,24 @@ extern void SyncNewColocationGroupToNodes(uint32 colocationId, int shardCount,
|
||||||
extern void SyncDeleteColocationGroupToNodes(uint32 colocationId);
|
extern void SyncDeleteColocationGroupToNodes(uint32 colocationId);
|
||||||
|
|
||||||
extern MetadataSyncContext * CreateMetadataSyncContext(List *nodeList,
|
extern MetadataSyncContext * CreateMetadataSyncContext(List *nodeList,
|
||||||
bool collectCommands,
|
bool nodesAddedInSameTransaction,
|
||||||
bool nodesAddedInSameTransaction);
|
bool noConnectionMode);
|
||||||
extern void EstablishAndSetMetadataSyncBareConnections(MetadataSyncContext *context);
|
extern void EstablishAndSetMetadataSyncBareConnections(MetadataSyncContext *context);
|
||||||
extern void SetMetadataSyncNodesFromNodeList(MetadataSyncContext *context,
|
extern void SetMetadataSyncNodesFromNodeList(MetadataSyncContext *context,
|
||||||
List *nodeList);
|
List *nodeList);
|
||||||
extern void ResetMetadataSyncMemoryContext(MetadataSyncContext *context);
|
extern void ResetMetadataSyncMemoryContext(MetadataSyncContext *context);
|
||||||
extern bool MetadataSyncCollectsCommands(MetadataSyncContext *context);
|
extern void CollectCommandIntoMetadataSyncContext(MetadataSyncContext *context,
|
||||||
extern void SendOrCollectCommandListToActivatedNodes(MetadataSyncContext *context,
|
List *commandList);
|
||||||
List *commands);
|
extern void ProcessBatchCommandsToActivatedNodes(MetadataSyncContext *context, bool
|
||||||
extern void SendOrCollectCommandListToMetadataNodes(MetadataSyncContext *context,
|
forceSend);
|
||||||
List *commands);
|
extern void ProcessBatchCommandsToMetadataNodes(MetadataSyncContext *context,
|
||||||
extern void SendOrCollectCommandListToSingleNode(MetadataSyncContext *context,
|
bool forceSend);
|
||||||
List *commands, int nodeIdx);
|
extern void ProcessBatchCommandsToSingleNode(MetadataSyncContext *context, int nodeIdx,
|
||||||
|
bool forceSend);
|
||||||
|
extern bool MetadataSyncInNoConnectionMode(MetadataSyncContext *context);
|
||||||
|
extern void SendCollectedCommandsToActivatedNodes(MetadataSyncContext *context);
|
||||||
|
extern void SendCollectedCommandsToMetadataNodes(MetadataSyncContext *context);
|
||||||
|
extern void SendCollectedCommandsToSingleNode(MetadataSyncContext *context, int nodeIdx);
|
||||||
|
|
||||||
extern void ActivateNodeList(MetadataSyncContext *context);
|
extern void ActivateNodeList(MetadataSyncContext *context);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue