Ejemplo n.º 1
0
/*
 * MultiRealTimeExecute loops over the given tasks, and manages their execution
 * until either one task permanently fails or all tasks successfully complete.
 * The function opens up a connection for each task it needs to execute, and
 * manages these tasks' execution in real-time.
 */
void
MultiRealTimeExecute(Job *job)
{
	List *taskList = job->taskList;
	List *taskExecutionList = NIL;
	ListCell *taskExecutionCell = NULL;
	ListCell *taskCell = NULL;
	uint32 failedTaskId = 0;
	bool allTasksCompleted = false;
	bool taskCompleted = false;
	bool taskFailed = false;
	bool sizeLimitIsExceeded = false;
	DistributedExecutionStats executionStats = { 0 };

	List *workerNodeList = NIL;
	HTAB *workerHash = NULL;
	const char *workerHashName = "Worker node hash";
	WaitInfo *waitInfo = MultiClientCreateWaitInfo(list_length(taskList));

	workerNodeList = ActiveReadableNodeList();
	workerHash = WorkerHash(workerHashName, workerNodeList);

	if (IsTransactionBlock())
	{
		BeginOrContinueCoordinatedTransaction();
	}

	/* initialize task execution structures for remote execution */
	foreach(taskCell, taskList)
	{
		Task *task = (Task *) lfirst(taskCell);

		TaskExecution *taskExecution = InitTaskExecution(task, EXEC_TASK_CONNECT_START);
		taskExecutionList = lappend(taskExecutionList, taskExecution);
	}
Ejemplo n.º 2
0
/*
 *	PreventTransactionChain
 *
 *	This routine is to be called by statements that must not run inside
 *	a transaction block, typically because they have non-rollback-able
 *	side effects or do internal commits.
 *
 *	If we have already started a transaction block, issue an error; also issue
 *	an error if we appear to be running inside a user-defined function (which
 *	could issue more commands and possibly cause a failure after the statement
 *	completes).
 *
 *	stmtNode: pointer to parameter block for statement; this is used in
 *	a very klugy way to determine whether we are inside a function.
 *	stmtType: statement type name for error messages.
 */
void
PreventTransactionChain(void *stmtNode, const char *stmtType)
{
	/*
	 * xact block already started?
	 */
	if (IsTransactionBlock())
		ereport(ERROR,
				(errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
		/* translator: %s represents an SQL statement name */
				 errmsg("%s cannot run inside a transaction block",
						stmtType)));

	/*
	 * Are we inside a function call?  If the statement's parameter block
	 * was allocated in QueryContext, assume it is an interactive command.
	 * Otherwise assume it is coming from a function.
	 */
	if (!MemoryContextContains(QueryContext, stmtNode))
		ereport(ERROR,
				(errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
		/* translator: %s represents an SQL statement name */
			 errmsg("%s cannot be executed from a function", stmtType)));
	/* If we got past IsTransactionBlock test, should be in default state */
	if (CurrentTransactionState->blockState != TBLOCK_DEFAULT)
		elog(ERROR, "cannot prevent transaction chain");
	/* all okay */
}
Ejemplo n.º 3
0
static void MMProcessUtility(Node *parsetree, const char *queryString,
							 ProcessUtilityContext context, ParamListInfo params,
							 DestReceiver *dest, char *completionTag)
{
	bool skipCommand;
	switch (nodeTag(parsetree))
	{
		case T_TransactionStmt:
		case T_PlannedStmt:
		case T_ClosePortalStmt:
		case T_FetchStmt:
		case T_DoStmt:
		case T_CopyStmt:
		case T_PrepareStmt:
		case T_ExecuteStmt:
		case T_NotifyStmt:
		case T_ListenStmt:
		case T_UnlistenStmt:
		case T_LoadStmt:
		case T_VariableSetStmt:
		case T_VariableShowStmt:
			skipCommand = true;
			break;
	    default:
			skipCommand = false;			
			break;
	}
	if (skipCommand || IsTransactionBlock()) { 
		if (PreviousProcessUtilityHook != NULL)
		{
			PreviousProcessUtilityHook(parsetree, queryString, context,
									   params, dest, completionTag);
		}
		else
		{
			standard_ProcessUtility(parsetree, queryString, context,
									params, dest, completionTag);
		}
		if (!skipCommand) {
			MMIsDistributedTrans = false;
		}
	} else { 		
		MMBroadcastUtilityStmt(queryString, false);
	}
}
Ejemplo n.º 4
0
/*
 *	RequireTransactionChain
 *
 *	This routine is to be called by statements that must run inside
 *	a transaction block, because they have no effects that persist past
 *	transaction end (and so calling them outside a transaction block
 *	is presumably an error).  DECLARE CURSOR is an example.
 *
 *	If we appear to be running inside a user-defined function, we do not
 *	issue an error, since the function could issue more commands that make
 *	use of the current statement's results.  Thus this is an inverse for
 *	PreventTransactionChain.
 *
 *	stmtNode: pointer to parameter block for statement; this is used in
 *	a very klugy way to determine whether we are inside a function.
 *	stmtType: statement type name for error messages.
 */
void
RequireTransactionChain(void *stmtNode, const char *stmtType)
{
	/*
	 * xact block already started?
	 */
	if (IsTransactionBlock())
		return;

	/*
	 * Are we inside a function call?  If the statement's parameter block
	 * was allocated in QueryContext, assume it is an interactive command.
	 * Otherwise assume it is coming from a function.
	 */
	if (!MemoryContextContains(QueryContext, stmtNode))
		return;
	ereport(ERROR,
			(errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
	/* translator: %s represents an SQL statement name */
			 errmsg("%s may only be used in transaction blocks",
					stmtType)));
}
Ejemplo n.º 5
0
Datum
mm_drop_node(PG_FUNCTION_ARGS)
{
	int nodeId = PG_GETARG_INT32(0);
	bool dropSlot = PG_GETARG_BOOL(1);
	if (!BIT_SET(dtm->disabledNodeMask, nodeId-1))
	{
		if (nodeId <= 0 || nodeId > dtm->nNodes) 
		{ 
			elog(ERROR, "NodeID %d is out of range [1,%d]", nodeId, dtm->nNodes);
		}
		dtm->disabledNodeMask |= ((int64)1 << (nodeId-1));
		dtm->nNodes -= 1;
		if (!IsTransactionBlock())
		{
			MMBroadcastUtilityStmt(psprintf("select mm_drop_node(%d,%s)", nodeId, dropSlot ? "true" : "false"), true);
		}
		if (dropSlot) 
		{
			ReplicationSlotDrop(psprintf("mm_slot_%d", nodeId));
		}		
	}
    PG_RETURN_VOID();
}