cdbdisp.h 6.6 KB
Newer Older
1 2 3 4 5 6
/*-------------------------------------------------------------------------
 *
 * cdbdisp.h
 * routines for dispatching commands from the dispatcher process
 * to the qExec processes.
 *
7 8 9 10 11 12
 * Portions Copyright (c) 2005-2008, Greenplum inc
 * Portions Copyright (c) 2012-Present Pivotal Software, Inc.
 *
 *
 * IDENTIFICATION
 *	    src/include/cdb/cdbdisp.h
13 14 15 16 17 18
 *
 *-------------------------------------------------------------------------
 */
#ifndef CDBDISP_H
#define CDBDISP_H

19
#include "lib/stringinfo.h" /* StringInfo */
20 21 22 23 24

#include "cdb/cdbtm.h"

#define CDB_MOTION_LOST_CONTACT_STRING "Interconnect error master lost contact with segment."

25 26
struct CdbDispatchResults; /* #include "cdb/cdbdispatchresult.h" */
struct Gang; /* #include "cdb/cdbgang.h" */
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49

/*
 * Types of message to QE when we wait for it.
 */
typedef enum DispatchWaitMode
{
	DISPATCH_WAIT_NONE = 0,			/* wait until QE fully completes */
	DISPATCH_WAIT_FINISH,			/* send query finish */
	DISPATCH_WAIT_CANCEL			/* send query cancel */
} DispatchWaitMode;

typedef struct CdbDispatchDirectDesc
{
	bool directed_dispatch;
	uint16 count;
	uint16 content[1];
} CdbDispatchDirectDesc;

extern CdbDispatchDirectDesc default_dispatch_direct_desc;
#define DEFAULT_DISP_DIRECT (&default_dispatch_direct_desc)

typedef struct CdbDispatcherState
{
50
	struct CdbDispatchResults *primaryResults;
51
	void *dispatchParams;
G
Gang Xiong 已提交
52
	MemoryContext dispatchStateContext;
53 54
} CdbDispatcherState;

55 56 57 58
typedef struct DispatcherInternalFuncs
{
	void (*procExitCallBack)(void);
	bool (*checkForCancel)(struct CdbDispatcherState *ds);
59
	int (*getWaitSocketFd)(struct CdbDispatcherState *ds);
60 61 62 63
	void* (*makeDispatchParams)(int maxSlices, char *queryText, int queryTextLen);
	void (*checkResults)(struct CdbDispatcherState *ds, DispatchWaitMode waitMode);
	void (*dispatchToGang)(struct CdbDispatcherState *ds, struct Gang *gp,
			int sliceIndex, CdbDispatchDirectDesc *direct);
64 65
	void (*waitDispatchFinish)(struct CdbDispatcherState *ds);

66
}DispatcherInternalFuncs;
67

68 69 70 71
/*--------------------------------------------------------------------*/
/*
 * cdbdisp_dispatchToGang:
 * Send the strCommand SQL statement to the subset of all segdbs in the cluster
72
 * specified by the gang parameter. cancelOnError indicates whether an error
73
 * occurring on one of the qExec segdbs should cause all still-executing commands to cancel
74 75
 * on other qExecs. Normally this would be true. The commands are sent over the libpq
 * connections that were established during cdblink_setup. They are run inside of threads.
76 77 78 79 80
 * The number of segdbs handled by any one thread is determined by the
 * guc variable gp_connections_per_thread.
 *
 * The caller must provide a CdbDispatchResults object having available
 * resultArray slots sufficient for the number of QEs to be dispatched:
81
 * i.e., resultCapacity - resultCount >= gp->size. This function will
82
 * assign one resultArray slot per QE of the Gang, paralleling the Gang's
83
 * db_descriptors array. Success or failure of each QE will be noted in
84 85 86 87
 * the QE's CdbDispatchResult entry; but before examining the results, the
 * caller must wait for execution to end by calling CdbCheckDispatchResult().
 *
 * The CdbDispatchResults object owns some malloc'ed storage, so the caller
88
 * must make certain to free it by calling cdbdisp_destroyDispatcherState().
89 90 91 92 93 94 95 96 97 98 99
 *
 * When dispatchResults->cancelOnError is false, strCommand is to be
 * dispatched to every connected gang member if possible, despite any
 * cancellation requests, QE errors, connection failures, etc.
 *
 * NB: This function should return normally even if there is an error.
 * It should not longjmp out via elog(ERROR, ...), ereport(ERROR, ...),
 * PG_THROW, CHECK_FOR_INTERRUPTS, etc.
 */
void
cdbdisp_dispatchToGang(struct CdbDispatcherState *ds,
100 101 102
					   struct Gang *gp,
					   int sliceIndex,
					   CdbDispatchDirectDesc *direct);
103

104 105 106 107 108 109 110 111 112 113
/*
 * cdbdisp_waitDispatchFinish:
 *
 * For asynchronous dispatcher, we have to wait all dispatch to finish before we move on to query execution,
 * otherwise we may get into a deadlock situation, e.g, gather motion node waiting for data,
 * while segments waiting for plan. This is skipped in threaded dispatcher as data is sent in blocking style.
 */
void
cdbdisp_waitDispatchFinish(struct CdbDispatcherState *ds);

114 115 116 117 118 119 120 121 122 123 124
/*
 * CdbCheckDispatchResult:
 *
 * Waits for completion of threads launched by cdbdisp_dispatchToGang().
 *
 * QEs that were dispatched with 'cancelOnError' true and are not yet idle
 * will be canceled/finished according to waitMode.
 */
void
CdbCheckDispatchResult(struct CdbDispatcherState *ds, DispatchWaitMode waitMode);

125 126 127 128 129 130 131 132 133 134 135 136
/*
 * cdbdisp_getDispatchResults:
 *
 * Block until all QEs return results or report errors.
 *
 * Return Values:
 *   Return NULL If one or more QEs got Error in which case qeErrorMsg contain
 *   QE error messages.
 */
struct CdbDispatchResults *
cdbdisp_getDispatchResults(struct CdbDispatcherState *ds, StringInfoData *qeErrorMsg);

137
/*
138
 * Wait for all QEs to finish, then report any errors from the given
139 140 141 142 143 144 145
 * CdbDispatchResults objects and free them.  If not all QEs in the
 * associated gang(s) executed the command successfully, throws an
 * error and does not return.  No-op if both CdbDispatchResults ptrs are NULL.
 * This is a convenience function; callers with unusual requirements may
 * instead call CdbCheckDispatchResult(), etc., directly.
 */
void
146
cdbdisp_finishCommand(struct CdbDispatcherState *ds);
147 148

/*
149
 * CdbDispatchHandleError
150 151 152 153 154 155 156 157 158 159 160 161 162
 *
 * When caller catches an error, the PG_CATCH handler can use this
 * function instead of cdbdisp_finishCommand to wait for all QEs
 * to finish, clean up, and report QE errors if appropriate.
 * This function should be called only from PG_CATCH handlers.
 *
 * This function destroys and frees the given CdbDispatchResults objects.
 * It is a no-op if both CdbDispatchResults ptrs are NULL.
 *
 * On return, the caller is expected to finish its own cleanup and
 * exit via PG_RE_THROW().
 */
void
163
CdbDispatchHandleError(struct CdbDispatcherState *ds);
164

165 166 167
void
cdbdisp_cancelDispatch(CdbDispatcherState *ds);

168
/*
169
 * Allocate memory and initialize CdbDispatcherState.
170
 *
171
 * Call cdbdisp_destroyDispatcherState to free it.
172
 *
173
 *   maxSlices: max number of slices of the query/command.
174 175
 */
void
176 177
cdbdisp_makeDispatcherState(CdbDispatcherState *ds,
							int maxSlices,
178 179 180
							bool cancelOnError,
							char *queryText,
							int queryTextLen);
181

182 183
/*
 * Free memory in CdbDispatcherState
184
 *
185 186
 * Free the PQExpBufferData allocated in libpq.
 * Free dispatcher memory context.
187
 */
188
void cdbdisp_destroyDispatcherState(CdbDispatcherState *ds);
189

190
bool cdbdisp_checkForCancel(CdbDispatcherState * ds);
191
int cdbdisp_getWaitSocketFd(CdbDispatcherState *ds);
192 193 194

void cdbdisp_onProcExit(void);

195
void cdbdisp_setAsync(bool async);
196

197
#endif   /* CDBDISP_H */