cdbdisp.h 6.4 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13
/*-------------------------------------------------------------------------
 *
 * cdbdisp.h
 * routines for dispatching commands from the dispatcher process
 * to the qExec processes.
 *
 * Copyright (c) 2005-2008, Greenplum inc
 *
 *-------------------------------------------------------------------------
 */
#ifndef CDBDISP_H
#define CDBDISP_H

14
#include "lib/stringinfo.h" /* StringInfo */
15 16 17 18 19

#include "cdb/cdbtm.h"

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

20 21
struct CdbDispatchResults; /* #include "cdb/cdbdispatchresult.h" */
struct Gang; /* #include "cdb/cdbgang.h" */
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44

/*
 * 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
{
45
	struct CdbDispatchResults *primaryResults;
46
	void *dispatchParams;
G
Gang Xiong 已提交
47
	MemoryContext dispatchStateContext;
48 49
} CdbDispatcherState;

50 51 52 53 54 55 56 57
typedef struct DispatcherInternalFuncs
{
	void (*procExitCallBack)(void);
	bool (*checkForCancel)(struct CdbDispatcherState *ds);
	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);
58 59
	void (*waitDispatchFinish)(struct CdbDispatcherState *ds);

60
}DispatcherInternalFuncs;
61

62 63 64 65
/*--------------------------------------------------------------------*/
/*
 * cdbdisp_dispatchToGang:
 * Send the strCommand SQL statement to the subset of all segdbs in the cluster
66
 * specified by the gang parameter. cancelOnError indicates whether an error
67
 * occurring on one of the qExec segdbs should cause all still-executing commands to cancel
68 69
 * 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.
70 71 72 73 74
 * 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:
75
 * i.e., resultCapacity - resultCount >= gp->size. This function will
76
 * assign one resultArray slot per QE of the Gang, paralleling the Gang's
77
 * db_descriptors array. Success or failure of each QE will be noted in
78 79 80 81
 * 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
82
 * must make certain to free it by calling cdbdisp_destroyDispatcherState().
83 84 85 86 87 88 89 90 91 92 93
 *
 * 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,
94 95 96
					   struct Gang *gp,
					   int sliceIndex,
					   CdbDispatchDirectDesc *direct);
97

98 99 100 101 102 103 104 105 106 107
/*
 * 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);

108 109 110 111 112 113 114 115 116 117 118
/*
 * 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);

119 120 121 122 123 124 125 126 127 128 129 130
/*
 * 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);

131
/*
132
 * Wait for all QEs to finish, then report any errors from the given
133 134 135 136 137 138 139
 * 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
140
cdbdisp_finishCommand(struct CdbDispatcherState *ds);
141 142

/*
143
 * CdbDispatchHandleError
144 145 146 147 148 149 150 151 152 153 154 155 156
 *
 * 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
157
CdbDispatchHandleError(struct CdbDispatcherState *ds);
158

159 160 161
void
cdbdisp_cancelDispatch(CdbDispatcherState *ds);

162
/*
163
 * Allocate memory and initialize CdbDispatcherState.
164
 *
165
 * Call cdbdisp_destroyDispatcherState to free it.
166
 *
167
 *   maxSlices: max number of slices of the query/command.
168 169
 */
void
170 171
cdbdisp_makeDispatcherState(CdbDispatcherState *ds,
							int maxSlices,
172 173 174
							bool cancelOnError,
							char *queryText,
							int queryTextLen);
175

176 177
/*
 * Free memory in CdbDispatcherState
178
 *
179 180
 * Free the PQExpBufferData allocated in libpq.
 * Free dispatcher memory context.
181
 */
182
void cdbdisp_destroyDispatcherState(CdbDispatcherState *ds);
183

184 185 186 187
bool cdbdisp_checkForCancel(CdbDispatcherState * ds);

void cdbdisp_onProcExit(void);

188
void cdbdisp_setAsync(bool async);
189

190
#endif   /* CDBDISP_H */