1 /* -*-pgsql-c-*- */ 2 /* 3 * 4 * $Header$ 5 * 6 * pgpool: a language independent connection pool server for PostgreSQL 7 * written by Tatsuo Ishii 8 * 9 * Copyright (c) 2003-2019 PgPool Global Development Group 10 * 11 * Permission to use, copy, modify, and distribute this software and 12 * its documentation for any purpose and without fee is hereby 13 * granted, provided that the above copyright notice appear in all 14 * copies and that both that copyright notice and this permission 15 * notice appear in supporting documentation, and that the name of the 16 * author not be used in advertising or publicity pertaining to 17 * distribution of the software without specific, written prior 18 * permission. The author makes no representations about the 19 * suitability of this software for any purpose. It is provided "as 20 * is" without express or implied warranty. 21 * 22 * pool_process_context.h.: process context information 23 * 24 */ 25 26 #ifndef POOL_SESSION_CONTEXT_H 27 #define POOL_SESSION_CONTEXT_H 28 #define INIT_LIST_SIZE 8 29 30 #include "pool.h" 31 #include "pool_process_context.h" 32 #include "pool_session_context.h" 33 #include "pool_query_context.h" 34 #include "query_cache/pool_memqcache.h" 35 36 /* 37 * Transaction isolation mode 38 */ 39 typedef enum 40 { 41 POOL_UNKNOWN, /* Unknown. Need to ask backend */ 42 POOL_READ_UNCOMMITTED, /* Read uncommitted */ 43 POOL_READ_COMMITTED, /* Read committed */ 44 POOL_REPEATABLE_READ, /* Rpeatable read */ 45 POOL_SERIALIZABLE /* Serializable */ 46 } POOL_TRANSACTION_ISOLATION; 47 48 /* 49 * Return values for pool_use_sync_map 50 */ 51 typedef enum 52 { 53 POOL_IGNORE_SYNC_MAP, /* Please ignore sync map */ 54 POOL_SYNC_MAP_IS_VALID, /* Sync map is valid */ 55 POOL_SYNC_MAP_EMPTY, /* Sync map is empty */ 56 } POOL_SYNC_MAP_STATE; 57 58 /* 59 * Status of sent message 60 */ 61 typedef enum 62 { 63 POOL_SENT_MESSAGE_CREATED, /* initial state of sent meesage */ 64 POOL_SENT_MESSAGE_CLOSED /* sent meesage closed but close complete 65 * message has not arrived yet */ 66 } POOL_SENT_MESSAGE_STATE; 67 68 /* 69 * Message content of extended query 70 */ 71 typedef struct 72 { 73 /* 74 * One of 'P':Parse, 'B':Bind or 'Q':Query (PREPARE). If kind = 'B', it 75 * is assumed that the message is a portal. 76 */ 77 char kind; 78 79 int len; /* message length in host byte order */ 80 char *contents; 81 POOL_SENT_MESSAGE_STATE state; /* message state */ 82 int num_tsparams; 83 char *name; /* object name of prepared statement or portal */ 84 POOL_QUERY_CONTEXT *query_context; 85 86 /* 87 * Following members are only used when memcache is enabled. 88 */ 89 bool is_cache_safe; /* true if the query can be cached */ 90 int param_offset; /* Offset from contents where actual bind 91 * parameters are stored. This is meaningful 92 * only when is_cache_safe is true. */ 93 } POOL_SENT_MESSAGE; 94 95 /* 96 * List of POOL_SENT_MESSAGE (XXX this should have been implemented using a 97 * list, rather than an array) 98 */ 99 typedef struct 100 { 101 int capacity; /* capacity of list */ 102 int size; /* number of elements */ 103 POOL_SENT_MESSAGE **sent_messages; 104 } POOL_SENT_MESSAGE_LIST; 105 106 /* 107 * Received message queue used in extended query/streaming replication mode. 108 * The queue is an FIFO. When Parse/Bind/Describe/Execute/Close message are 109 * received, each message is en-queued. The information is used to process 110 * those response messages, when Parse complete/Bind completes, Parameter 111 * description, row description, command complete and close compete message 112 * are received because they don't have any information regarding 113 * statement/portal. 114 * 115 * The memory used for the queue lives in the session context mememory. 116 */ 117 118 typedef enum 119 { 120 POOL_PARSE = 0, 121 POOL_BIND, 122 POOL_EXECUTE, 123 POOL_DESCRIBE, 124 POOL_CLOSE, 125 POOL_SYNC 126 } POOL_MESSAGE_TYPE; 127 128 typedef struct 129 { 130 POOL_MESSAGE_TYPE type; 131 char *contents; /* message packet contents excluding message 132 * kind */ 133 int contents_len; /* message packet length */ 134 char query[QUERY_STRING_BUFFER_LEN]; /* copy of original query */ 135 char statement[MAX_IDENTIFIER_LEN]; /* prepared statment name if 136 * any */ 137 char portal[MAX_IDENTIFIER_LEN]; /* portal name if any */ 138 bool is_rows_returned; /* true if the message could produce row 139 * data */ 140 bool not_forward_to_frontend; /* Do not forward response from 141 * backend to frontend. This is 142 * used by parse_before_bind() */ 143 int node_ids[2]; /* backend node ids this message was sent to. 144 * -1 means no message was sent. */ 145 POOL_QUERY_CONTEXT *query_context; /* query context */ 146 } POOL_PENDING_MESSAGE; 147 148 /* Return true if node_id is one of node_ids */ 149 #define IS_SENT_NODE_ID(msg, node_id) (msg->node_ids[0] == node_id || msg->node_ids[1] == node_id) 150 151 /* 152 * Per session context: 153 */ 154 typedef struct 155 { 156 POOL_PROCESS_CONTEXT *process_context; /* belonging process */ 157 POOL_CONNECTION *frontend; /* connection to frontend */ 158 POOL_CONNECTION_POOL *backend; /* connection to backends */ 159 160 /* 161 * If true, we are waiting for backend response. For SELECT this flags 162 * should be kept until all responses are returned from backend. i.e. 163 * until "Read for Query" packet. 164 */ 165 bool in_progress; 166 167 /* If true, we are doing extended query message */ 168 bool doing_extended_query_message; 169 170 /* 171 * If true, we have rewritten where_to_send map in the current query 172 * context. pool_unset_query_in_progress() should restore the data from 173 * where_to_send_save. For now, this is only necessary while doing 174 * extended query protocol and in streaming replication mode. 175 */ 176 bool need_to_restore_where_to_send; 177 bool where_to_send_save[MAX_NUM_BACKENDS]; 178 179 /* If true, the command in progress has finished successfully. */ 180 bool command_success; 181 182 /* If true, write query has been appeared in this transaction */ 183 bool writing_transaction; 184 185 /* If true, error occurred in this transaction */ 186 bool failed_transaction; 187 188 /* If true, we skip reading from backends */ 189 bool skip_reading_from_backends; 190 191 /* ignore any command until Sync message */ 192 bool ignore_till_sync; 193 194 /* 195 * Transaction isolation mode. 196 */ 197 POOL_TRANSACTION_ISOLATION transaction_isolation; 198 199 /* 200 * Associated query context, only used for non-extended protocol. In 201 * extended protocol, the query context resides in "PreparedStatementList 202 * *pstmt_list" (see below). 203 */ 204 POOL_QUERY_CONTEXT *query_context; 205 #ifdef NOT_USED 206 /* where to send map for PREPARE/EXECUTE/DEALLOCATE */ 207 POOL_PREPARED_SEND_MAP prep_where; 208 #endif /* NOT_USED */ 209 MemoryContext memory_context; /* memory context for session */ 210 211 /* message which doesn't receive complete message */ 212 POOL_SENT_MESSAGE *uncompleted_message; 213 214 POOL_SENT_MESSAGE_LIST message_list; 215 216 int load_balance_node_id; /* selected load balance node id */ 217 218 /* 219 * If true, UPDATE/DELETE caused difference in number of affected tuples 220 * in backends. 221 */ 222 bool mismatch_ntuples; 223 224 /* 225 * If mismatch_ntuples true, this array holds the number of affected 226 * tuples of each node. -1 for down nodes. 227 */ 228 int ntuples[MAX_NUM_BACKENDS]; 229 230 /* 231 * If true, we are executing reset query list. 232 */ 233 bool reset_context; 234 235 /* 236 * Query cache management area 237 */ 238 POOL_QUERY_CACHE_ARRAY *query_cache_array; /* pending SELECT results */ 239 long long int num_selects; /* number of successful SELECTs in this 240 * transaction */ 241 242 /* 243 * Parse/Bind/Decribe/Execute/Close message queue. 244 */ 245 List *pending_messages; 246 247 /* 248 * The last pending message. Reset at Ready for query. Note that this is 249 * a shallow copy of pending message. Once the are is reset, 250 * previos_message_exists is set to false. 251 */ 252 bool previous_message_exists; 253 POOL_PENDING_MESSAGE previous_message; 254 255 /* Protocol major version number */ 256 int major; 257 /* Protocol minor version number */ 258 int minor; 259 260 /* 261 * Do not read messages from frontend. Used in extended protocol + 262 * streaming replication. If sync message is received from frontend, this 263 * flag prevent from reading any message from frontend until read for 264 * query message arrives from backend. 265 */ 266 bool suspend_reading_from_frontend; 267 268 #ifdef NOT_USED 269 /* Preferred "master" node id. Only used for SimpleForwardToFrontend. */ 270 int preferred_master_node_id; 271 #endif 272 } POOL_SESSION_CONTEXT; 273 274 extern void pool_init_session_context(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend); 275 extern void pool_session_context_destroy(void); 276 extern POOL_SESSION_CONTEXT * pool_get_session_context(bool noerror); 277 extern int pool_get_local_session_id(void); 278 extern bool pool_is_query_in_progress(void); 279 extern void pool_set_query_in_progress(void); 280 extern void pool_unset_query_in_progress(void); 281 extern bool pool_is_skip_reading_from_backends(void); 282 extern void pool_set_skip_reading_from_backends(void); 283 extern void pool_unset_skip_reading_from_backends(void); 284 extern bool pool_is_doing_extended_query_message(void); 285 extern void pool_set_doing_extended_query_message(void); 286 extern void pool_unset_doing_extended_query_message(void); 287 extern bool pool_is_ignore_till_sync(void); 288 extern void pool_set_ignore_till_sync(void); 289 extern void pool_unset_ignore_till_sync(void); 290 extern POOL_SENT_MESSAGE * pool_create_sent_message(char kind, int len, char *contents, 291 int num_tsparams, const char *name, 292 POOL_QUERY_CONTEXT * query_context); 293 extern void pool_add_sent_message(POOL_SENT_MESSAGE * message); 294 extern bool pool_remove_sent_message(char kind, const char *name); 295 extern void pool_remove_sent_messages(char kind); 296 extern void pool_clear_sent_message_list(void); 297 extern void pool_sent_message_destroy(POOL_SENT_MESSAGE * message); 298 extern POOL_SENT_MESSAGE * pool_get_sent_message(char kind, const char *name, POOL_SENT_MESSAGE_STATE state); 299 extern void pool_set_sent_message_state(POOL_SENT_MESSAGE * message); 300 extern void pool_zap_query_context_in_sent_messages(POOL_QUERY_CONTEXT *query_context); 301 extern POOL_SENT_MESSAGE * pool_get_sent_message_by_query_context(POOL_QUERY_CONTEXT * query_context); 302 extern void pool_unset_writing_transaction(void); 303 extern void pool_set_writing_transaction(void); 304 extern bool pool_is_writing_transaction(void); 305 extern void pool_unset_failed_transaction(void); 306 extern void pool_set_failed_transaction(void); 307 extern bool pool_is_failed_transaction(void); 308 extern void pool_unset_transaction_isolation(void); 309 extern void pool_set_transaction_isolation(POOL_TRANSACTION_ISOLATION isolation_level); 310 extern POOL_TRANSACTION_ISOLATION pool_get_transaction_isolation(void); 311 extern void pool_unset_command_success(void); 312 extern void pool_set_command_success(void); 313 extern bool pool_is_command_success(void); 314 extern void pool_copy_prep_where(bool *src, bool *dest); 315 extern bool can_query_context_destroy(POOL_QUERY_CONTEXT * qc); 316 extern void pool_pending_messages_init(void); 317 extern void pool_pending_messages_destroy(void); 318 extern POOL_PENDING_MESSAGE * pool_pending_message_create(char kind, int len, char *contents); 319 extern void pool_pending_message_free_pending_message(POOL_PENDING_MESSAGE * message); 320 extern void pool_pending_message_dest_set(POOL_PENDING_MESSAGE * message, POOL_QUERY_CONTEXT * query_context); 321 extern void pool_pending_message_query_context_dest_set(POOL_PENDING_MESSAGE * message, POOL_QUERY_CONTEXT * query_context); 322 extern void pool_pending_message_query_set(POOL_PENDING_MESSAGE * message, POOL_QUERY_CONTEXT * query_context); 323 extern void pool_pending_message_add(POOL_PENDING_MESSAGE * message); 324 extern POOL_PENDING_MESSAGE * pool_pending_message_head_message(void); 325 extern POOL_PENDING_MESSAGE * pool_pending_message_pull_out(void); 326 extern POOL_PENDING_MESSAGE * pool_pending_message_get(POOL_MESSAGE_TYPE type); 327 extern char pool_get_close_message_spec(POOL_PENDING_MESSAGE * msg); 328 extern char *pool_get_close_message_name(POOL_PENDING_MESSAGE * msg); 329 extern void pool_pending_message_reset_previous_message(void); 330 extern void pool_pending_message_set_previous_message(POOL_PENDING_MESSAGE * message); 331 extern POOL_PENDING_MESSAGE * pool_pending_message_get_previous_message(void); 332 extern bool pool_pending_message_exists(void); 333 extern const char *pool_pending_message_type_to_string(POOL_MESSAGE_TYPE type); 334 extern void pool_check_pending_message_and_reply(POOL_MESSAGE_TYPE type, char kind); 335 extern POOL_PENDING_MESSAGE * pool_pending_message_find_lastest_by_query_context(POOL_QUERY_CONTEXT * qc); 336 extern int pool_pending_message_get_target_backend_id(POOL_PENDING_MESSAGE * msg); 337 extern int pool_pending_message_get_message_num_by_backend_id(int backend_id); 338 extern void dump_pending_message(void); 339 extern void pool_set_major_version(int major); 340 extern void pool_set_minor_version(int minor); 341 extern int pool_get_minor_version(void); 342 extern bool pool_is_suspend_reading_from_frontend(void); 343 extern void pool_set_suspend_reading_from_frontend(void); 344 extern void pool_unset_suspend_reading_from_frontend(void); 345 346 #ifdef NOT_USED 347 extern void pool_set_preferred_master_node_id(int node_id); 348 extern int pool_get_preferred_master_node_id(void); 349 extern void pool_reset_preferred_master_node_id(void); 350 #endif 351 352 #ifdef NOT_USED 353 extern void pool_add_prep_where(char *name, bool *map); 354 extern bool *pool_get_prep_where(char *name); 355 extern void pool_delete_prep_where(char *name); 356 #endif /* NOT_USED */ 357 #endif /* POOL_SESSION_CONTEXT_H */ 358