1 /***************************************************************************** 2 3 Copyright (c) 1996, 2012, Oracle and/or its affiliates. All Rights Reserved. 4 5 This program is free software; you can redistribute it and/or modify 6 it under the terms of the GNU General Public License, version 2.0, 7 as published by the Free Software Foundation. 8 9 This program is also distributed with certain software (including 10 but not limited to OpenSSL) that is licensed under separate terms, 11 as designated in a particular file or component or in included license 12 documentation. The authors of MySQL hereby grant you an additional 13 permission to link the program and your derivative works with the 14 separately licensed software that they have included with MySQL. 15 16 This program is distributed in the hope that it will be useful, 17 but WITHOUT ANY WARRANTY; without even the implied warranty of 18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 GNU General Public License, version 2.0, for more details. 20 21 You should have received a copy of the GNU General Public License along with 22 this program; if not, write to the Free Software Foundation, Inc., 23 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA 24 25 *****************************************************************************/ 26 27 /**************************************************//** 28 @file include/que0que.h 29 Query graph 30 31 Created 5/27/1996 Heikki Tuuri 32 *******************************************************/ 33 34 #ifndef que0que_h 35 #define que0que_h 36 37 #include "univ.i" 38 #include "data0data.h" 39 #include "dict0types.h" 40 #include "btr0sea.h" 41 #include "trx0trx.h" 42 #include "trx0roll.h" 43 #include "srv0srv.h" 44 #include "usr0types.h" 45 #include "que0types.h" 46 #include "row0types.h" 47 #include "pars0types.h" 48 49 /* If the following flag is set TRUE, the module will print trace info 50 of SQL execution in the UNIV_SQL_DEBUG version */ 51 extern ibool que_trace_on; 52 53 /** Mutex protecting the query threads. */ 54 extern ib_mutex_t que_thr_mutex; 55 56 /***********************************************************************//** 57 Creates a query graph fork node. 58 @return own: fork node */ 59 UNIV_INTERN 60 que_fork_t* 61 que_fork_create( 62 /*============*/ 63 que_t* graph, /*!< in: graph, if NULL then this 64 fork node is assumed to be the 65 graph root */ 66 que_node_t* parent, /*!< in: parent node */ 67 ulint fork_type, /*!< in: fork type */ 68 mem_heap_t* heap); /*!< in: memory heap where created */ 69 /***********************************************************************//** 70 Gets the first thr in a fork. */ 71 UNIV_INLINE 72 que_thr_t* 73 que_fork_get_first_thr( 74 /*===================*/ 75 que_fork_t* fork); /*!< in: query fork */ 76 /***********************************************************************//** 77 Gets the child node of the first thr in a fork. */ 78 UNIV_INLINE 79 que_node_t* 80 que_fork_get_child( 81 /*===============*/ 82 que_fork_t* fork); /*!< in: query fork */ 83 /***********************************************************************//** 84 Sets the parent of a graph node. */ 85 UNIV_INLINE 86 void 87 que_node_set_parent( 88 /*================*/ 89 que_node_t* node, /*!< in: graph node */ 90 que_node_t* parent);/*!< in: parent */ 91 /***********************************************************************//** 92 Creates a query graph thread node. 93 @return own: query thread node */ 94 UNIV_INTERN 95 que_thr_t* 96 que_thr_create( 97 /*===========*/ 98 que_fork_t* parent, /*!< in: parent node, i.e., a fork node */ 99 mem_heap_t* heap); /*!< in: memory heap where created */ 100 /**********************************************************************//** 101 Frees a query graph, but not the heap where it was created. Does not free 102 explicit cursor declarations, they are freed in que_graph_free. */ 103 UNIV_INTERN 104 void 105 que_graph_free_recursive( 106 /*=====================*/ 107 que_node_t* node); /*!< in: query graph node */ 108 /**********************************************************************//** 109 Frees a query graph. */ 110 UNIV_INTERN 111 void 112 que_graph_free( 113 /*===========*/ 114 que_t* graph); /*!< in: query graph; we assume that the memory 115 heap where this graph was created is private 116 to this graph: if not, then use 117 que_graph_free_recursive and free the heap 118 afterwards! */ 119 /**********************************************************************//** 120 Stops a query thread if graph or trx is in a state requiring it. The 121 conditions are tested in the order (1) graph, (2) trx. The lock_sys_t::mutex 122 has to be reserved. 123 @return TRUE if stopped */ 124 UNIV_INTERN 125 ibool 126 que_thr_stop( 127 /*=========*/ 128 que_thr_t* thr); /*!< in: query thread */ 129 /**********************************************************************//** 130 Moves a thread from another state to the QUE_THR_RUNNING state. Increments 131 the n_active_thrs counters of the query graph and transaction. */ 132 UNIV_INTERN 133 void 134 que_thr_move_to_run_state_for_mysql( 135 /*================================*/ 136 que_thr_t* thr, /*!< in: an query thread */ 137 trx_t* trx); /*!< in: transaction */ 138 /**********************************************************************//** 139 A patch for MySQL used to 'stop' a dummy query thread used in MySQL 140 select, when there is no error or lock wait. */ 141 UNIV_INTERN 142 void 143 que_thr_stop_for_mysql_no_error( 144 /*============================*/ 145 que_thr_t* thr, /*!< in: query thread */ 146 trx_t* trx); /*!< in: transaction */ 147 /**********************************************************************//** 148 A patch for MySQL used to 'stop' a dummy query thread used in MySQL. The 149 query thread is stopped and made inactive, except in the case where 150 it was put to the lock wait state in lock0lock.cc, but the lock has already 151 been granted or the transaction chosen as a victim in deadlock resolution. */ 152 UNIV_INTERN 153 void 154 que_thr_stop_for_mysql( 155 /*===================*/ 156 que_thr_t* thr); /*!< in: query thread */ 157 /**********************************************************************//** 158 Run a query thread. Handles lock waits. */ 159 UNIV_INTERN 160 void 161 que_run_threads( 162 /*============*/ 163 que_thr_t* thr); /*!< in: query thread */ 164 /**********************************************************************//** 165 Moves a suspended query thread to the QUE_THR_RUNNING state and release 166 a worker thread to execute it. This function should be used to end 167 the wait state of a query thread waiting for a lock or a stored procedure 168 completion. 169 @return query thread instance of thread to wakeup or NULL */ 170 UNIV_INTERN 171 que_thr_t* 172 que_thr_end_lock_wait( 173 /*==================*/ 174 trx_t* trx); /*!< in: transaction in the 175 QUE_THR_LOCK_WAIT state */ 176 /**********************************************************************//** 177 Starts execution of a command in a query fork. Picks a query thread which 178 is not in the QUE_THR_RUNNING state and moves it to that state. If none 179 can be chosen, a situation which may arise in parallelized fetches, NULL 180 is returned. 181 @return a query thread of the graph moved to QUE_THR_RUNNING state, or 182 NULL; the query thread should be executed by que_run_threads by the 183 caller */ 184 UNIV_INTERN 185 que_thr_t* 186 que_fork_start_command( 187 /*===================*/ 188 que_fork_t* fork); /*!< in: a query fork */ 189 /***********************************************************************//** 190 Gets the trx of a query thread. */ 191 UNIV_INLINE 192 trx_t* 193 thr_get_trx( 194 /*========*/ 195 que_thr_t* thr); /*!< in: query thread */ 196 /*******************************************************************//** 197 Determines if this thread is rolling back an incomplete transaction 198 in crash recovery. 199 @return TRUE if thr is rolling back an incomplete transaction in crash 200 recovery */ 201 UNIV_INLINE 202 ibool 203 thr_is_recv( 204 /*========*/ 205 const que_thr_t* thr); /*!< in: query thread */ 206 /***********************************************************************//** 207 Gets the type of a graph node. */ 208 UNIV_INLINE 209 ulint 210 que_node_get_type( 211 /*==============*/ 212 que_node_t* node); /*!< in: graph node */ 213 /***********************************************************************//** 214 Gets pointer to the value data type field of a graph node. */ 215 UNIV_INLINE 216 dtype_t* 217 que_node_get_data_type( 218 /*===================*/ 219 que_node_t* node); /*!< in: graph node */ 220 /***********************************************************************//** 221 Gets pointer to the value dfield of a graph node. */ 222 UNIV_INLINE 223 dfield_t* 224 que_node_get_val( 225 /*=============*/ 226 que_node_t* node); /*!< in: graph node */ 227 /***********************************************************************//** 228 Gets the value buffer size of a graph node. 229 @return val buffer size, not defined if val.data == NULL in node */ 230 UNIV_INLINE 231 ulint 232 que_node_get_val_buf_size( 233 /*======================*/ 234 que_node_t* node); /*!< in: graph node */ 235 /***********************************************************************//** 236 Sets the value buffer size of a graph node. */ 237 UNIV_INLINE 238 void 239 que_node_set_val_buf_size( 240 /*======================*/ 241 que_node_t* node, /*!< in: graph node */ 242 ulint size); /*!< in: size */ 243 /*********************************************************************//** 244 Gets the next list node in a list of query graph nodes. */ 245 UNIV_INLINE 246 que_node_t* 247 que_node_get_next( 248 /*==============*/ 249 que_node_t* node); /*!< in: node in a list */ 250 /*********************************************************************//** 251 Gets the parent node of a query graph node. 252 @return parent node or NULL */ 253 UNIV_INLINE 254 que_node_t* 255 que_node_get_parent( 256 /*================*/ 257 que_node_t* node); /*!< in: node */ 258 /****************************************************************//** 259 Get the first containing loop node (e.g. while_node_t or for_node_t) for the 260 given node, or NULL if the node is not within a loop. 261 @return containing loop node, or NULL. */ 262 UNIV_INTERN 263 que_node_t* 264 que_node_get_containing_loop_node( 265 /*==============================*/ 266 que_node_t* node); /*!< in: node */ 267 /*********************************************************************//** 268 Catenates a query graph node to a list of them, possible empty list. 269 @return one-way list of nodes */ 270 UNIV_INLINE 271 que_node_t* 272 que_node_list_add_last( 273 /*===================*/ 274 que_node_t* node_list, /*!< in: node list, or NULL */ 275 que_node_t* node); /*!< in: node */ 276 /************************************************************************* 277 Get the last node from the list.*/ 278 UNIV_INLINE 279 que_node_t* 280 que_node_list_get_last( 281 /*===================*/ 282 /* out: node last node from list.*/ 283 que_node_t* node_list); /* in: node list, or NULL */ 284 /*********************************************************************//** 285 Gets a query graph node list length. 286 @return length, for NULL list 0 */ 287 UNIV_INLINE 288 ulint 289 que_node_list_get_len( 290 /*==================*/ 291 que_node_t* node_list); /*!< in: node list, or NULL */ 292 /**********************************************************************//** 293 Checks if graph, trx, or session is in a state where the query thread should 294 be stopped. 295 @return TRUE if should be stopped; NOTE that if the peek is made 296 without reserving the trx_t::mutex, then another peek with the mutex 297 reserved is necessary before deciding the actual stopping */ 298 UNIV_INLINE 299 ibool 300 que_thr_peek_stop( 301 /*==============*/ 302 que_thr_t* thr); /*!< in: query thread */ 303 /***********************************************************************//** 304 Returns TRUE if the query graph is for a SELECT statement. 305 @return TRUE if a select */ 306 UNIV_INLINE 307 ibool 308 que_graph_is_select( 309 /*================*/ 310 que_t* graph); /*!< in: graph */ 311 /**********************************************************************//** 312 Prints info of an SQL query graph node. */ 313 UNIV_INTERN 314 void 315 que_node_print_info( 316 /*================*/ 317 que_node_t* node); /*!< in: query graph node */ 318 /*********************************************************************//** 319 Evaluate the given SQL 320 @return error code or DB_SUCCESS */ 321 UNIV_INTERN 322 dberr_t 323 que_eval_sql( 324 /*=========*/ 325 pars_info_t* info, /*!< in: info struct, or NULL */ 326 const char* sql, /*!< in: SQL string */ 327 ibool reserve_dict_mutex, 328 /*!< in: if TRUE, acquire/release 329 dict_sys->mutex around call to pars_sql. */ 330 trx_t* trx); /*!< in: trx */ 331 332 /**********************************************************************//** 333 Round robin scheduler. 334 @return a query thread of the graph moved to QUE_THR_RUNNING state, or 335 NULL; the query thread should be executed by que_run_threads by the 336 caller */ 337 UNIV_INTERN 338 que_thr_t* 339 que_fork_scheduler_round_robin( 340 /*===========================*/ 341 que_fork_t* fork, /*!< in: a query fork */ 342 que_thr_t* thr); /*!< in: current pos */ 343 344 /*********************************************************************//** 345 Initialise the query sub-system. */ 346 UNIV_INTERN 347 void 348 que_init(void); 349 /*==========*/ 350 351 /*********************************************************************//** 352 Close the query sub-system. */ 353 UNIV_INTERN 354 void 355 que_close(void); 356 /*===========*/ 357 358 /* Query graph query thread node: the fields are protected by the 359 trx_t::mutex with the exceptions named below */ 360 361 struct que_thr_t{ 362 que_common_t common; /*!< type: QUE_NODE_THR */ 363 ulint magic_n; /*!< magic number to catch memory 364 corruption */ 365 que_node_t* child; /*!< graph child node */ 366 que_t* graph; /*!< graph where this node belongs */ 367 ulint state; /*!< state of the query thread */ 368 ibool is_active; /*!< TRUE if the thread has been set 369 to the run state in 370 que_thr_move_to_run_state, but not 371 deactivated in 372 que_thr_dec_reference_count */ 373 /*------------------------------*/ 374 /* The following fields are private to the OS thread executing the 375 query thread, and are not protected by any mutex: */ 376 377 que_node_t* run_node; /*!< pointer to the node where the 378 subgraph down from this node is 379 currently executed */ 380 que_node_t* prev_node; /*!< pointer to the node from which 381 the control came */ 382 ulint resource; /*!< resource usage of the query thread 383 thus far */ 384 ulint lock_state; /*!< lock state of thread (table or 385 row) */ 386 struct srv_slot_t* 387 slot; /* The thread slot in the wait 388 array in srv_sys_t */ 389 /*------------------------------*/ 390 /* The following fields are links for the various lists that 391 this type can be on. */ 392 UT_LIST_NODE_T(que_thr_t) 393 thrs; /*!< list of thread nodes of the fork 394 node */ 395 UT_LIST_NODE_T(que_thr_t) 396 trx_thrs; /*!< lists of threads in wait list of 397 the trx */ 398 UT_LIST_NODE_T(que_thr_t) 399 queue; /*!< list of runnable thread nodes in 400 the server task queue */ 401 ulint fk_cascade_depth; /*!< maximum cascading call depth 402 supported for foreign key constraint 403 related delete/updates */ 404 }; 405 406 #define QUE_THR_MAGIC_N 8476583 407 #define QUE_THR_MAGIC_FREED 123461526 408 409 /* Query graph fork node: its fields are protected by the query thread mutex */ 410 struct que_fork_t{ 411 que_common_t common; /*!< type: QUE_NODE_FORK */ 412 que_t* graph; /*!< query graph of this node */ 413 ulint fork_type; /*!< fork type */ 414 ulint n_active_thrs; /*!< if this is the root of a graph, the 415 number query threads that have been 416 started in que_thr_move_to_run_state 417 but for which que_thr_dec_refer_count 418 has not yet been called */ 419 trx_t* trx; /*!< transaction: this is set only in 420 the root node */ 421 ulint state; /*!< state of the fork node */ 422 que_thr_t* caller; /*!< pointer to a possible calling query 423 thread */ 424 UT_LIST_BASE_NODE_T(que_thr_t) 425 thrs; /*!< list of query threads */ 426 /*------------------------------*/ 427 /* The fields in this section are defined only in the root node */ 428 sym_tab_t* sym_tab; /*!< symbol table of the query, 429 generated by the parser, or NULL 430 if the graph was created 'by hand' */ 431 pars_info_t* info; /*!< info struct, or NULL */ 432 /* The following cur_... fields are relevant only in a select graph */ 433 434 ulint cur_end; /*!< QUE_CUR_NOT_DEFINED, QUE_CUR_START, 435 QUE_CUR_END */ 436 ulint cur_pos; /*!< if there are n rows in the result 437 set, values 0 and n + 1 mean before 438 first row, or after last row, depending 439 on cur_end; values 1...n mean a row 440 index */ 441 ibool cur_on_row; /*!< TRUE if cursor is on a row, i.e., 442 it is not before the first row or 443 after the last row */ 444 sel_node_t* last_sel_node; /*!< last executed select node, or NULL 445 if none */ 446 UT_LIST_NODE_T(que_fork_t) 447 graphs; /*!< list of query graphs of a session 448 or a stored procedure */ 449 /*------------------------------*/ 450 mem_heap_t* heap; /*!< memory heap where the fork was 451 created */ 452 453 }; 454 455 /* Query fork (or graph) types */ 456 #define QUE_FORK_SELECT_NON_SCROLL 1 /* forward-only cursor */ 457 #define QUE_FORK_SELECT_SCROLL 2 /* scrollable cursor */ 458 #define QUE_FORK_INSERT 3 459 #define QUE_FORK_UPDATE 4 460 #define QUE_FORK_ROLLBACK 5 461 /* This is really the undo graph used in rollback, 462 no signal-sending roll_node in this graph */ 463 #define QUE_FORK_PURGE 6 464 #define QUE_FORK_EXECUTE 7 465 #define QUE_FORK_PROCEDURE 8 466 #define QUE_FORK_PROCEDURE_CALL 9 467 #define QUE_FORK_MYSQL_INTERFACE 10 468 #define QUE_FORK_RECOVERY 11 469 470 /* Query fork (or graph) states */ 471 #define QUE_FORK_ACTIVE 1 472 #define QUE_FORK_COMMAND_WAIT 2 473 #define QUE_FORK_INVALID 3 474 #define QUE_FORK_BEING_FREED 4 475 476 /* Flag which is ORed to control structure statement node types */ 477 #define QUE_NODE_CONTROL_STAT 1024 478 479 /* Query graph node types */ 480 #define QUE_NODE_LOCK 1 481 #define QUE_NODE_INSERT 2 482 #define QUE_NODE_UPDATE 4 483 #define QUE_NODE_CURSOR 5 484 #define QUE_NODE_SELECT 6 485 #define QUE_NODE_AGGREGATE 7 486 #define QUE_NODE_FORK 8 487 #define QUE_NODE_THR 9 488 #define QUE_NODE_UNDO 10 489 #define QUE_NODE_COMMIT 11 490 #define QUE_NODE_ROLLBACK 12 491 #define QUE_NODE_PURGE 13 492 #define QUE_NODE_CREATE_TABLE 14 493 #define QUE_NODE_CREATE_INDEX 15 494 #define QUE_NODE_SYMBOL 16 495 #define QUE_NODE_RES_WORD 17 496 #define QUE_NODE_FUNC 18 497 #define QUE_NODE_ORDER 19 498 #define QUE_NODE_PROC (20 + QUE_NODE_CONTROL_STAT) 499 #define QUE_NODE_IF (21 + QUE_NODE_CONTROL_STAT) 500 #define QUE_NODE_WHILE (22 + QUE_NODE_CONTROL_STAT) 501 #define QUE_NODE_ASSIGNMENT 23 502 #define QUE_NODE_FETCH 24 503 #define QUE_NODE_OPEN 25 504 #define QUE_NODE_COL_ASSIGNMENT 26 505 #define QUE_NODE_FOR (27 + QUE_NODE_CONTROL_STAT) 506 #define QUE_NODE_RETURN 28 507 #define QUE_NODE_ROW_PRINTF 29 508 #define QUE_NODE_ELSIF 30 509 #define QUE_NODE_CALL 31 510 #define QUE_NODE_EXIT 32 511 512 /* Query thread states */ 513 #define QUE_THR_RUNNING 1 514 #define QUE_THR_PROCEDURE_WAIT 2 515 #define QUE_THR_COMPLETED 3 /* in selects this means that the 516 thread is at the end of its result set 517 (or start, in case of a scroll cursor); 518 in other statements, this means the 519 thread has done its task */ 520 #define QUE_THR_COMMAND_WAIT 4 521 #define QUE_THR_LOCK_WAIT 5 522 #define QUE_THR_SUSPENDED 7 523 #define QUE_THR_ERROR 8 524 525 /* Query thread lock states */ 526 #define QUE_THR_LOCK_NOLOCK 0 527 #define QUE_THR_LOCK_ROW 1 528 #define QUE_THR_LOCK_TABLE 2 529 530 /* From where the cursor position is counted */ 531 #define QUE_CUR_NOT_DEFINED 1 532 #define QUE_CUR_START 2 533 #define QUE_CUR_END 3 534 535 #ifndef UNIV_NONINL 536 #include "que0que.ic" 537 #endif 538 539 #endif 540