1 #ifndef MDL_H 2 #define MDL_H 3 /* Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved. 4 Copyright (c) 2020, 2021, MariaDB 5 6 This program is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; version 2 of the License. 9 10 This program is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 GNU General Public License for more details. 14 15 You should have received a copy of the GNU General Public License 16 along with this program; if not, write to the Free Software Foundation, 17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA */ 18 19 #include "sql_plist.h" 20 #include "ilist.h" 21 #include <my_sys.h> 22 #include <m_string.h> 23 #include <mysql_com.h> 24 #include <lf.h> 25 26 class THD; 27 28 class MDL_context; 29 class MDL_lock; 30 class MDL_ticket; 31 bool ok_for_lower_case_names(const char *name); 32 33 typedef unsigned short mdl_bitmap_t; 34 #define MDL_BIT(A) static_cast<mdl_bitmap_t>(1U << A) 35 36 37 /** 38 @def ENTER_COND(C, M, S, O) 39 Start a wait on a condition. 40 @param C the condition to wait on 41 @param M the associated mutex 42 @param S the new stage to enter 43 @param O the previous stage 44 @sa EXIT_COND(). 45 */ 46 #define ENTER_COND(C, M, S, O) enter_cond(C, M, S, O, __func__, __FILE__, __LINE__) 47 48 /** 49 @def EXIT_COND(S) 50 End a wait on a condition 51 @param S the new stage to enter 52 */ 53 #define EXIT_COND(S) exit_cond(S, __func__, __FILE__, __LINE__) 54 55 /** 56 An interface to separate the MDL module from the THD, and the rest of the 57 server code. 58 */ 59 60 class MDL_context_owner 61 { 62 public: ~MDL_context_owner()63 virtual ~MDL_context_owner() {} 64 65 /** 66 Enter a condition wait. 67 For @c enter_cond() / @c exit_cond() to work the mutex must be held before 68 @c enter_cond(); this mutex is then released by @c exit_cond(). 69 Usage must be: lock mutex; enter_cond(); your code; exit_cond(). 70 @param cond the condition to wait on 71 @param mutex the associated mutex 72 @param [in] stage the stage to enter, or NULL 73 @param [out] old_stage the previous stage, or NULL 74 @param src_function function name of the caller 75 @param src_file file name of the caller 76 @param src_line line number of the caller 77 @sa ENTER_COND(), THD::enter_cond() 78 @sa EXIT_COND(), THD::exit_cond() 79 */ 80 virtual void enter_cond(mysql_cond_t *cond, mysql_mutex_t *mutex, 81 const PSI_stage_info *stage, PSI_stage_info *old_stage, 82 const char *src_function, const char *src_file, 83 int src_line) = 0; 84 85 /** 86 @def EXIT_COND(S) 87 End a wait on a condition 88 @param [in] stage the new stage to enter 89 @param src_function function name of the caller 90 @param src_file file name of the caller 91 @param src_line line number of the caller 92 @sa ENTER_COND(), THD::enter_cond() 93 @sa EXIT_COND(), THD::exit_cond() 94 */ 95 virtual void exit_cond(const PSI_stage_info *stage, 96 const char *src_function, const char *src_file, 97 int src_line) = 0; 98 /** 99 Has the owner thread been killed? 100 */ 101 virtual int is_killed() = 0; 102 103 /** 104 This one is only used for DEBUG_SYNC. 105 (Do not use it to peek/poke into other parts of THD.) 106 */ 107 virtual THD* get_thd() = 0; 108 109 /** 110 @see THD::notify_shared_lock() 111 */ 112 virtual bool notify_shared_lock(MDL_context_owner *in_use, 113 bool needs_thr_lock_abort) = 0; 114 }; 115 116 /** 117 Type of metadata lock request. 118 119 @sa Comments for MDL_object_lock::can_grant_lock() and 120 MDL_scoped_lock::can_grant_lock() for details. 121 122 Scoped locks are database (or schema) locks. 123 The object locks are for tables, triggers etc. 124 */ 125 126 enum enum_mdl_type { 127 /* This means that the MDL_request is not initialized */ 128 MDL_NOT_INITIALIZED= -1, 129 /* 130 An intention exclusive metadata lock (IX). Used only for scoped locks. 131 Owner of this type of lock can acquire upgradable exclusive locks on 132 individual objects. 133 Compatible with other IX locks, but is incompatible with scoped S and 134 X locks. 135 IX lock is taken in SCHEMA namespace when we intend to modify 136 object metadata. Object may refer table, stored procedure, trigger, 137 view/etc. 138 */ 139 MDL_INTENTION_EXCLUSIVE= 0, 140 /* 141 A shared metadata lock (S). 142 To be used in cases when we are interested in object metadata only 143 and there is no intention to access object data (e.g. for stored 144 routines or during preparing prepared statements). 145 We also mis-use this type of lock for open HANDLERs, since lock 146 acquired by this statement has to be compatible with lock acquired 147 by LOCK TABLES ... WRITE statement, i.e. SNRW (We can't get by by 148 acquiring S lock at HANDLER ... OPEN time and upgrading it to SR 149 lock for HANDLER ... READ as it doesn't solve problem with need 150 to abort DML statements which wait on table level lock while having 151 open HANDLER in the same connection). 152 To avoid deadlock which may occur when SNRW lock is being upgraded to 153 X lock for table on which there is an active S lock which is owned by 154 thread which waits in its turn for table-level lock owned by thread 155 performing upgrade we have to use thr_abort_locks_for_thread() 156 facility in such situation. 157 This problem does not arise for locks on stored routines as we don't 158 use SNRW locks for them. It also does not arise when S locks are used 159 during PREPARE calls as table-level locks are not acquired in this 160 case. 161 This lock is taken for global read lock, when caching a stored 162 procedure in memory for the duration of the transaction and for 163 tables used by prepared statements. 164 */ 165 MDL_SHARED, 166 /* 167 A high priority shared metadata lock. 168 Used for cases when there is no intention to access object data (i.e. 169 data in the table). 170 "High priority" means that, unlike other shared locks, it is granted 171 ignoring pending requests for exclusive locks. Intended for use in 172 cases when we only need to access metadata and not data, e.g. when 173 filling an INFORMATION_SCHEMA table. 174 Since SH lock is compatible with SNRW lock, the connection that 175 holds SH lock lock should not try to acquire any kind of table-level 176 or row-level lock, as this can lead to a deadlock. Moreover, after 177 acquiring SH lock, the connection should not wait for any other 178 resource, as it might cause starvation for X locks and a potential 179 deadlock during upgrade of SNW or SNRW to X lock (e.g. if the 180 upgrading connection holds the resource that is being waited for). 181 */ 182 MDL_SHARED_HIGH_PRIO, 183 /* 184 A shared metadata lock (SR) for cases when there is an intention to read 185 data from table. 186 A connection holding this kind of lock can read table metadata and read 187 table data (after acquiring appropriate table and row-level locks). 188 This means that one can only acquire TL_READ, TL_READ_NO_INSERT, and 189 similar table-level locks on table if one holds SR MDL lock on it. 190 To be used for tables in SELECTs, subqueries, and LOCK TABLE ... READ 191 statements. 192 */ 193 MDL_SHARED_READ, 194 /* 195 A shared metadata lock (SW) for cases when there is an intention to modify 196 (and not just read) data in the table. 197 A connection holding SW lock can read table metadata and modify or read 198 table data (after acquiring appropriate table and row-level locks). 199 To be used for tables to be modified by INSERT, UPDATE, DELETE 200 statements, but not LOCK TABLE ... WRITE or DDL). Also taken by 201 SELECT ... FOR UPDATE. 202 */ 203 MDL_SHARED_WRITE, 204 /* 205 An upgradable shared metadata lock for cases when there is an 206 intention to modify (and not just read) data in the table. 207 Can be upgraded to MDL_SHARED_NO_WRITE and MDL_EXCLUSIVE. 208 A connection holding SU lock can read table metadata and modify or read 209 table data (after acquiring appropriate table and row-level locks). 210 To be used for the first phase of ALTER TABLE. 211 */ 212 MDL_SHARED_UPGRADABLE, 213 /* 214 A shared metadata lock for cases when we need to read data from table 215 and block all concurrent modifications to it (for both data and metadata). 216 Used by LOCK TABLES READ statement. 217 */ 218 MDL_SHARED_READ_ONLY, 219 /* 220 An upgradable shared metadata lock which blocks all attempts to update 221 table data, allowing reads. 222 A connection holding this kind of lock can read table metadata and read 223 table data. 224 Can be upgraded to X metadata lock. 225 Note, that since this type of lock is not compatible with SNRW or SW 226 lock types, acquiring appropriate engine-level locks for reading 227 (TL_READ* for MyISAM, shared row locks in InnoDB) should be 228 contention-free. 229 To be used for the first phase of ALTER TABLE, when copying data between 230 tables, to allow concurrent SELECTs from the table, but not UPDATEs. 231 */ 232 MDL_SHARED_NO_WRITE, 233 /* 234 An upgradable shared metadata lock which allows other connections 235 to access table metadata, but not data. 236 It blocks all attempts to read or update table data, while allowing 237 INFORMATION_SCHEMA and SHOW queries. 238 A connection holding this kind of lock can read table metadata modify and 239 read table data. 240 Can be upgraded to X metadata lock. 241 To be used for LOCK TABLES WRITE statement. 242 Not compatible with any other lock type except S and SH. 243 */ 244 MDL_SHARED_NO_READ_WRITE, 245 /* 246 An exclusive metadata lock (X). 247 A connection holding this lock can modify both table's metadata and data. 248 No other type of metadata lock can be granted while this lock is held. 249 To be used for CREATE/DROP/RENAME TABLE statements and for execution of 250 certain phases of other DDL statements. 251 */ 252 MDL_EXCLUSIVE, 253 /* This should be the last !!! */ 254 MDL_TYPE_END 255 }; 256 257 258 /** Backup locks */ 259 260 /** 261 Block concurrent backup 262 */ 263 #define MDL_BACKUP_START enum_mdl_type(0) 264 /** 265 Block new write requests to non transactional tables 266 */ 267 #define MDL_BACKUP_FLUSH enum_mdl_type(1) 268 /** 269 In addition to previous locks, blocks running requests to non trans tables 270 Used to wait until all DML usage of on trans tables are finished 271 */ 272 #define MDL_BACKUP_WAIT_FLUSH enum_mdl_type(2) 273 /** 274 In addition to previous locks, blocks new DDL's from starting 275 */ 276 #define MDL_BACKUP_WAIT_DDL enum_mdl_type(3) 277 /** 278 In addition to previous locks, blocks commits 279 */ 280 #define MDL_BACKUP_WAIT_COMMIT enum_mdl_type(4) 281 282 /** 283 Blocks (or is blocked by) statements that intend to modify data. Acquired 284 before commit lock by FLUSH TABLES WITH READ LOCK. 285 */ 286 #define MDL_BACKUP_FTWRL1 enum_mdl_type(5) 287 288 /** 289 Blocks (or is blocked by) commits. Acquired after global read lock by 290 FLUSH TABLES WITH READ LOCK. 291 */ 292 #define MDL_BACKUP_FTWRL2 enum_mdl_type(6) 293 294 #define MDL_BACKUP_DML enum_mdl_type(7) 295 #define MDL_BACKUP_TRANS_DML enum_mdl_type(8) 296 #define MDL_BACKUP_SYS_DML enum_mdl_type(9) 297 298 /** 299 Must be acquired by DDL statements that intend to modify data. 300 Currently it's also used for LOCK TABLES. 301 */ 302 #define MDL_BACKUP_DDL enum_mdl_type(10) 303 304 /** 305 Blocks new DDL's. Used by backup code to enable DDL logging 306 */ 307 #define MDL_BACKUP_BLOCK_DDL enum_mdl_type(11) 308 309 /* 310 Statement is modifying data, but will not block MDL_BACKUP_DDL or earlier 311 BACKUP stages. 312 ALTER TABLE is started with MDL_BACKUP_DDL, but changed to 313 MDL_BACKUP_ALTER_COPY while alter table is copying or modifing data. 314 */ 315 316 #define MDL_BACKUP_ALTER_COPY enum_mdl_type(12) 317 318 /** 319 Must be acquired during commit. 320 */ 321 #define MDL_BACKUP_COMMIT enum_mdl_type(13) 322 #define MDL_BACKUP_END enum_mdl_type(14) 323 324 325 /** Duration of metadata lock. */ 326 327 enum enum_mdl_duration { 328 /** 329 Locks with statement duration are automatically released at the end 330 of statement or transaction. 331 */ 332 MDL_STATEMENT= 0, 333 /** 334 Locks with transaction duration are automatically released at the end 335 of transaction. 336 */ 337 MDL_TRANSACTION, 338 /** 339 Locks with explicit duration survive the end of statement and transaction. 340 They have to be released explicitly by calling MDL_context::release_lock(). 341 */ 342 MDL_EXPLICIT, 343 /* This should be the last ! */ 344 MDL_DURATION_END }; 345 346 347 /** Maximal length of key for metadata locking subsystem. */ 348 #define MAX_MDLKEY_LENGTH (1 + NAME_LEN + 1 + NAME_LEN + 1) 349 350 351 /** 352 Metadata lock object key. 353 354 A lock is requested or granted based on a fully qualified name and type. 355 E.g. They key for a table consists of <0 (=table)>+<database>+<table name>. 356 Elsewhere in the comments this triple will be referred to simply as "key" 357 or "name". 358 */ 359 360 struct MDL_key 361 { 362 public: 363 #ifdef HAVE_PSI_INTERFACE 364 static void init_psi_keys(); 365 #endif 366 367 /** 368 Object namespaces. 369 Sic: when adding a new member to this enum make sure to 370 update m_namespace_to_wait_state_name array in mdl.cc and 371 metadata_lock_info_lock_name in metadata_lock_info.cc! 372 373 Different types of objects exist in different namespaces 374 - SCHEMA is for databases (to protect against DROP DATABASE) 375 - TABLE is for tables and views. 376 - BACKUP is for locking DML, DDL and COMMIT's during BACKUP STAGES 377 - FUNCTION is for stored functions. 378 - PROCEDURE is for stored procedures. 379 - TRIGGER is for triggers. 380 - EVENT is for event scheduler events 381 Note that although there isn't metadata locking on triggers, 382 it's necessary to have a separate namespace for them since 383 MDL_key is also used outside of the MDL subsystem. 384 */ 385 enum enum_mdl_namespace { BACKUP=0, 386 SCHEMA, 387 TABLE, 388 FUNCTION, 389 PROCEDURE, 390 PACKAGE_BODY, 391 TRIGGER, 392 EVENT, 393 USER_LOCK, /* user level locks. */ 394 /* This should be the last ! */ 395 NAMESPACE_END }; 396 ptrMDL_key397 const uchar *ptr() const { return (uchar*) m_ptr; } lengthMDL_key398 uint length() const { return m_length; } 399 db_nameMDL_key400 const char *db_name() const { return m_ptr + 1; } db_name_lengthMDL_key401 uint db_name_length() const { return m_db_name_length; } 402 nameMDL_key403 const char *name() const { return m_ptr + m_db_name_length + 2; } name_lengthMDL_key404 uint name_length() const { return m_length - m_db_name_length - 3; } 405 mdl_namespaceMDL_key406 enum_mdl_namespace mdl_namespace() const 407 { return (enum_mdl_namespace)(m_ptr[0]); } 408 409 /** 410 Construct a metadata lock key from a triplet (mdl_namespace, 411 database and name). 412 413 @remark The key for a table is <mdl_namespace>+<database name>+<table name> 414 415 @param mdl_namespace Id of namespace of object to be locked 416 @param db Name of database to which the object belongs 417 @param name Name of of the object 418 @param key Where to store the the MDL key. 419 */ mdl_key_initMDL_key420 void mdl_key_init(enum_mdl_namespace mdl_namespace_arg, 421 const char *db, const char *name_arg) 422 { 423 m_ptr[0]= (char) mdl_namespace_arg; 424 /* 425 It is responsibility of caller to ensure that db and object names 426 are not longer than NAME_LEN. Still we play safe and try to avoid 427 buffer overruns. 428 */ 429 DBUG_ASSERT(strlen(db) <= NAME_LEN); 430 DBUG_ASSERT(strlen(name_arg) <= NAME_LEN); 431 m_db_name_length= static_cast<uint16>(strmake(m_ptr + 1, db, NAME_LEN) - 432 m_ptr - 1); 433 m_length= static_cast<uint16>(strmake(m_ptr + m_db_name_length + 2, 434 name_arg, 435 NAME_LEN) - m_ptr + 1); 436 m_hash_value= my_hash_sort(&my_charset_bin, (uchar*) m_ptr + 1, 437 m_length - 1); 438 DBUG_SLOW_ASSERT(mdl_namespace_arg == USER_LOCK || ok_for_lower_case_names(db)); 439 } mdl_key_initMDL_key440 void mdl_key_init(const MDL_key *rhs) 441 { 442 memcpy(m_ptr, rhs->m_ptr, rhs->m_length); 443 m_length= rhs->m_length; 444 m_db_name_length= rhs->m_db_name_length; 445 m_hash_value= rhs->m_hash_value; 446 } is_equalMDL_key447 bool is_equal(const MDL_key *rhs) const 448 { 449 return (m_length == rhs->m_length && 450 memcmp(m_ptr, rhs->m_ptr, m_length) == 0); 451 } 452 /** 453 Compare two MDL keys lexicographically. 454 */ cmpMDL_key455 int cmp(const MDL_key *rhs) const 456 { 457 /* 458 The key buffer is always '\0'-terminated. Since key 459 character set is utf-8, we can safely assume that no 460 character starts with a zero byte. 461 */ 462 return memcmp(m_ptr, rhs->m_ptr, MY_MIN(m_length, rhs->m_length)); 463 } 464 MDL_keyMDL_key465 MDL_key(const MDL_key *rhs) 466 { 467 mdl_key_init(rhs); 468 } MDL_keyMDL_key469 MDL_key(enum_mdl_namespace namespace_arg, 470 const char *db_arg, const char *name_arg) 471 { 472 mdl_key_init(namespace_arg, db_arg, name_arg); 473 } MDL_keyMDL_key474 MDL_key() {} /* To use when part of MDL_request. */ 475 476 /** 477 Get thread state name to be used in case when we have to 478 wait on resource identified by key. 479 */ get_wait_state_nameMDL_key480 const PSI_stage_info * get_wait_state_name() const 481 { 482 return & m_namespace_to_wait_state_name[(int)mdl_namespace()]; 483 } hash_valueMDL_key484 my_hash_value_type hash_value() const 485 { 486 return m_hash_value + mdl_namespace(); 487 } tc_hash_valueMDL_key488 my_hash_value_type tc_hash_value() const 489 { 490 return m_hash_value; 491 } 492 493 private: 494 uint16 m_length; 495 uint16 m_db_name_length; 496 my_hash_value_type m_hash_value; 497 char m_ptr[MAX_MDLKEY_LENGTH]; 498 static PSI_stage_info m_namespace_to_wait_state_name[NAMESPACE_END]; 499 private: 500 MDL_key(const MDL_key &); /* not implemented */ 501 MDL_key &operator=(const MDL_key &); /* not implemented */ 502 friend my_hash_value_type mdl_hash_function(CHARSET_INFO *, 503 const uchar *, size_t); 504 }; 505 506 507 /** 508 A pending metadata lock request. 509 510 A lock request and a granted metadata lock are represented by 511 different classes because they have different allocation 512 sites and hence different lifetimes. The allocation of lock requests is 513 controlled from outside of the MDL subsystem, while allocation of granted 514 locks (tickets) is controlled within the MDL subsystem. 515 516 MDL_request is a C structure, you don't need to call a constructor 517 or destructor for it. 518 */ 519 520 class MDL_request 521 { 522 public: 523 /** Type of metadata lock. */ 524 enum enum_mdl_type type; 525 /** Duration for requested lock. */ 526 enum enum_mdl_duration duration; 527 528 /** 529 Pointers for participating in the list of lock requests for this context. 530 */ 531 MDL_request *next_in_list; 532 MDL_request **prev_in_list; 533 /** 534 Pointer to the lock ticket object for this lock request. 535 Valid only if this lock request is satisfied. 536 */ 537 MDL_ticket *ticket; 538 539 /** A lock is requested based on a fully qualified name and type. */ 540 MDL_key key; 541 542 const char *m_src_file; 543 uint m_src_line; 544 545 public: 546 new(size_t size,MEM_ROOT * mem_root)547 static void *operator new(size_t size, MEM_ROOT *mem_root) throw () 548 { return alloc_root(mem_root, size); } delete(void *,MEM_ROOT *)549 static void operator delete(void *, MEM_ROOT *) {} 550 551 void init_with_source(MDL_key::enum_mdl_namespace namespace_arg, 552 const char *db_arg, const char *name_arg, 553 enum_mdl_type mdl_type_arg, 554 enum_mdl_duration mdl_duration_arg, 555 const char *src_file, uint src_line); 556 void init_by_key_with_source(const MDL_key *key_arg, enum_mdl_type mdl_type_arg, 557 enum_mdl_duration mdl_duration_arg, 558 const char *src_file, uint src_line); 559 /** Set type of lock request. Can be only applied to pending locks. */ set_type(enum_mdl_type type_arg)560 inline void set_type(enum_mdl_type type_arg) 561 { 562 DBUG_ASSERT(ticket == NULL); 563 type= type_arg; 564 } move_from(MDL_request & from)565 void move_from(MDL_request &from) 566 { 567 type= from.type; 568 duration= from.duration; 569 ticket= from.ticket; 570 next_in_list= from.next_in_list; 571 prev_in_list= from.prev_in_list; 572 key.mdl_key_init(&from.key); 573 from.ticket= NULL; // that's what "move" means 574 } 575 576 /** 577 Is this a request for a lock which allow data to be updated? 578 579 @note This method returns true for MDL_SHARED_UPGRADABLE type of 580 lock. Even though this type of lock doesn't allow updates 581 it will always be upgraded to one that does. 582 */ is_write_lock_request()583 bool is_write_lock_request() const 584 { 585 return (type >= MDL_SHARED_WRITE && 586 type != MDL_SHARED_READ_ONLY); 587 } 588 589 /* 590 This is to work around the ugliness of TABLE_LIST 591 compiler-generated assignment operator. It is currently used 592 in several places to quickly copy "most" of the members of the 593 table list. These places currently never assume that the mdl 594 request is carried over to the new TABLE_LIST, or shared 595 between lists. 596 597 This method does not initialize the instance being assigned! 598 Use of init() for initialization after this assignment operator 599 is mandatory. Can only be used before the request has been 600 granted. 601 */ 602 MDL_request& operator=(const MDL_request &) 603 { 604 type= MDL_NOT_INITIALIZED; 605 ticket= NULL; 606 /* Do nothing, in particular, don't try to copy the key. */ 607 return *this; 608 } 609 /* Another piece of ugliness for TABLE_LIST constructor */ MDL_request()610 MDL_request(): type(MDL_NOT_INITIALIZED), ticket(NULL) {} 611 MDL_request(const MDL_request * rhs)612 MDL_request(const MDL_request *rhs) 613 :type(rhs->type), 614 duration(rhs->duration), 615 ticket(NULL), 616 key(&rhs->key) 617 {} 618 }; 619 620 621 typedef void (*mdl_cached_object_release_hook)(void *); 622 623 #define MDL_REQUEST_INIT(R, P1, P2, P3, P4, P5) \ 624 (*R).init_with_source(P1, P2, P3, P4, P5, __FILE__, __LINE__) 625 626 #define MDL_REQUEST_INIT_BY_KEY(R, P1, P2, P3) \ 627 (*R).init_by_key_with_source(P1, P2, P3, __FILE__, __LINE__) 628 629 630 /** 631 An abstract class for inspection of a connected 632 subgraph of the wait-for graph. 633 */ 634 635 class MDL_wait_for_graph_visitor 636 { 637 public: 638 virtual bool enter_node(MDL_context *node) = 0; 639 virtual void leave_node(MDL_context *node) = 0; 640 641 virtual bool inspect_edge(MDL_context *dest) = 0; 642 virtual ~MDL_wait_for_graph_visitor(); MDL_wait_for_graph_visitor()643 MDL_wait_for_graph_visitor() {} 644 }; 645 646 /** 647 Abstract class representing an edge in the waiters graph 648 to be traversed by deadlock detection algorithm. 649 */ 650 651 class MDL_wait_for_subgraph 652 { 653 public: 654 virtual ~MDL_wait_for_subgraph(); 655 656 /** 657 Accept a wait-for graph visitor to inspect the node 658 this edge is leading to. 659 */ 660 virtual bool accept_visitor(MDL_wait_for_graph_visitor *gvisitor) = 0; 661 662 enum enum_deadlock_weight 663 { 664 DEADLOCK_WEIGHT_FTWRL1= 0, 665 DEADLOCK_WEIGHT_DML= 1, 666 DEADLOCK_WEIGHT_DDL= 100 667 }; 668 /* A helper used to determine which lock request should be aborted. */ 669 virtual uint get_deadlock_weight() const = 0; 670 }; 671 672 673 /** 674 A granted metadata lock. 675 676 @warning MDL_ticket members are private to the MDL subsystem. 677 678 @note Multiple shared locks on a same object are represented by a 679 single ticket. The same does not apply for other lock types. 680 681 @note There are two groups of MDL_ticket members: 682 - "Externally accessible". These members can be accessed from 683 threads/contexts different than ticket owner in cases when 684 ticket participates in some list of granted or waiting tickets 685 for a lock. Therefore one should change these members before 686 including then to waiting/granted lists or while holding lock 687 protecting those lists. 688 - "Context private". Such members are private to thread/context 689 owning this ticket. I.e. they should not be accessed from other 690 threads/contexts. 691 */ 692 693 class MDL_ticket : public MDL_wait_for_subgraph, public ilist_node<> 694 { 695 public: 696 /** 697 Pointers for participating in the list of lock requests for this context. 698 Context private. 699 */ 700 MDL_ticket *next_in_context; 701 MDL_ticket **prev_in_context; 702 public: 703 #ifdef WITH_WSREP 704 void wsrep_report(bool debug) const; 705 #endif /* WITH_WSREP */ 706 bool has_pending_conflicting_lock() const; 707 get_ctx()708 MDL_context *get_ctx() const { return m_ctx; } is_upgradable_or_exclusive()709 bool is_upgradable_or_exclusive() const 710 { 711 return m_type == MDL_SHARED_UPGRADABLE || 712 m_type == MDL_SHARED_NO_WRITE || 713 m_type == MDL_SHARED_NO_READ_WRITE || 714 m_type == MDL_EXCLUSIVE; 715 } get_type()716 enum_mdl_type get_type() const { return m_type; } 717 const LEX_STRING *get_type_name() const; 718 const LEX_STRING *get_type_name(enum_mdl_type type) const; get_lock()719 MDL_lock *get_lock() const { return m_lock; } 720 MDL_key *get_key() const; 721 void downgrade_lock(enum_mdl_type type); 722 723 bool has_stronger_or_equal_type(enum_mdl_type type) const; 724 725 bool is_incompatible_when_granted(enum_mdl_type type) const; 726 bool is_incompatible_when_waiting(enum_mdl_type type) const; 727 728 /** Implement MDL_wait_for_subgraph interface. */ 729 virtual bool accept_visitor(MDL_wait_for_graph_visitor *dvisitor); 730 virtual uint get_deadlock_weight() const; 731 /** 732 Status of lock request represented by the ticket as reflected in P_S. 733 */ 734 enum enum_psi_status { PENDING = 0, GRANTED, 735 PRE_ACQUIRE_NOTIFY, POST_RELEASE_NOTIFY }; 736 private: 737 friend class MDL_context; 738 MDL_ticket(MDL_context * ctx_arg,enum_mdl_type type_arg,enum_mdl_duration duration_arg)739 MDL_ticket(MDL_context *ctx_arg, enum_mdl_type type_arg 740 #ifndef DBUG_OFF 741 , enum_mdl_duration duration_arg 742 #endif 743 ) 744 : m_type(type_arg), 745 #ifndef DBUG_OFF 746 m_duration(duration_arg), 747 #endif 748 m_ctx(ctx_arg), 749 m_lock(NULL), 750 m_psi(NULL) 751 {} 752 ~MDL_ticket()753 virtual ~MDL_ticket() 754 { 755 DBUG_ASSERT(m_psi == NULL); 756 } 757 758 static MDL_ticket *create(MDL_context *ctx_arg, enum_mdl_type type_arg 759 #ifndef DBUG_OFF 760 , enum_mdl_duration duration_arg 761 #endif 762 ); 763 static void destroy(MDL_ticket *ticket); 764 private: 765 /** Type of metadata lock. Externally accessible. */ 766 enum enum_mdl_type m_type; 767 #ifndef DBUG_OFF 768 /** 769 Duration of lock represented by this ticket. 770 Context private. Debug-only. 771 */ 772 enum_mdl_duration m_duration; 773 #endif 774 /** 775 Context of the owner of the metadata lock ticket. Externally accessible. 776 */ 777 MDL_context *m_ctx; 778 779 /** 780 Pointer to the lock object for this lock ticket. Externally accessible. 781 */ 782 MDL_lock *m_lock; 783 784 PSI_metadata_lock *m_psi; 785 786 private: 787 MDL_ticket(const MDL_ticket &); /* not implemented */ 788 MDL_ticket &operator=(const MDL_ticket &); /* not implemented */ 789 }; 790 791 792 /** 793 Savepoint for MDL context. 794 795 Doesn't include metadata locks with explicit duration as 796 they are not released during rollback to savepoint. 797 */ 798 799 class MDL_savepoint 800 { 801 public: MDL_savepoint()802 MDL_savepoint() {}; 803 804 private: MDL_savepoint(MDL_ticket * stmt_ticket,MDL_ticket * trans_ticket)805 MDL_savepoint(MDL_ticket *stmt_ticket, MDL_ticket *trans_ticket) 806 : m_stmt_ticket(stmt_ticket), m_trans_ticket(trans_ticket) 807 {} 808 809 friend class MDL_context; 810 811 private: 812 /** 813 Pointer to last lock with statement duration which was taken 814 before creation of savepoint. 815 */ 816 MDL_ticket *m_stmt_ticket; 817 /** 818 Pointer to last lock with transaction duration which was taken 819 before creation of savepoint. 820 */ 821 MDL_ticket *m_trans_ticket; 822 }; 823 824 825 /** 826 A reliable way to wait on an MDL lock. 827 */ 828 829 class MDL_wait 830 { 831 public: 832 MDL_wait(); 833 ~MDL_wait(); 834 835 enum enum_wait_status { EMPTY = 0, GRANTED, VICTIM, TIMEOUT, KILLED }; 836 837 bool set_status(enum_wait_status result_arg); 838 enum_wait_status get_status(); 839 void reset_status(); 840 enum_wait_status timed_wait(MDL_context_owner *owner, 841 struct timespec *abs_timeout, 842 bool signal_timeout, 843 const PSI_stage_info *wait_state_name); 844 private: 845 /** 846 Condvar which is used for waiting until this context's pending 847 request can be satisfied or this thread has to perform actions 848 to resolve a potential deadlock (we subscribe to such 849 notification by adding a ticket corresponding to the request 850 to an appropriate queue of waiters). 851 */ 852 mysql_mutex_t m_LOCK_wait_status; 853 mysql_cond_t m_COND_wait_status; 854 enum_wait_status m_wait_status; 855 }; 856 857 858 typedef I_P_List<MDL_request, I_P_List_adapter<MDL_request, 859 &MDL_request::next_in_list, 860 &MDL_request::prev_in_list>, 861 I_P_List_counter> 862 MDL_request_list; 863 864 /** 865 Context of the owner of metadata locks. I.e. each server 866 connection has such a context. 867 */ 868 869 class MDL_context 870 { 871 public: 872 typedef I_P_List<MDL_ticket, 873 I_P_List_adapter<MDL_ticket, 874 &MDL_ticket::next_in_context, 875 &MDL_ticket::prev_in_context> > 876 Ticket_list; 877 878 typedef Ticket_list::Iterator Ticket_iterator; 879 880 MDL_context(); 881 void destroy(); 882 883 bool try_acquire_lock(MDL_request *mdl_request); 884 bool acquire_lock(MDL_request *mdl_request, double lock_wait_timeout); 885 bool acquire_locks(MDL_request_list *requests, double lock_wait_timeout); 886 bool upgrade_shared_lock(MDL_ticket *mdl_ticket, 887 enum_mdl_type new_type, 888 double lock_wait_timeout); 889 890 bool clone_ticket(MDL_request *mdl_request); 891 892 void release_all_locks_for_name(MDL_ticket *ticket); 893 void release_lock(MDL_ticket *ticket); 894 895 bool is_lock_owner(MDL_key::enum_mdl_namespace mdl_namespace, 896 const char *db, const char *name, 897 enum_mdl_type mdl_type); 898 unsigned long get_lock_owner(MDL_key *mdl_key); 899 900 bool has_lock(const MDL_savepoint &mdl_savepoint, MDL_ticket *mdl_ticket); 901 has_locks()902 inline bool has_locks() const 903 { 904 return !(m_tickets[MDL_STATEMENT].is_empty() && 905 m_tickets[MDL_TRANSACTION].is_empty() && 906 m_tickets[MDL_EXPLICIT].is_empty()); 907 } has_explicit_locks()908 bool has_explicit_locks() const 909 { 910 return !m_tickets[MDL_EXPLICIT].is_empty(); 911 } has_transactional_locks()912 inline bool has_transactional_locks() const 913 { 914 return !m_tickets[MDL_TRANSACTION].is_empty(); 915 } 916 mdl_savepoint()917 MDL_savepoint mdl_savepoint() 918 { 919 return MDL_savepoint(m_tickets[MDL_STATEMENT].front(), 920 m_tickets[MDL_TRANSACTION].front()); 921 } 922 923 void set_explicit_duration_for_all_locks(); 924 void set_transaction_duration_for_all_locks(); 925 void set_lock_duration(MDL_ticket *mdl_ticket, enum_mdl_duration duration); 926 927 void release_statement_locks(); 928 void release_transactional_locks(THD *thd); 929 void release_explicit_locks(); 930 void rollback_to_savepoint(const MDL_savepoint &mdl_savepoint); 931 get_owner()932 MDL_context_owner *get_owner() { return m_owner; } 933 934 /** @pre Only valid if we started waiting for lock. */ get_deadlock_weight()935 inline uint get_deadlock_weight() const 936 { return m_waiting_for->get_deadlock_weight() + m_deadlock_overweight; } inc_deadlock_overweight()937 void inc_deadlock_overweight() { m_deadlock_overweight++; } 938 /** 939 Post signal to the context (and wake it up if necessary). 940 941 @retval FALSE - Success, signal was posted. 942 @retval TRUE - Failure, signal was not posted since context 943 already has received some signal or closed 944 signal slot. 945 */ init(MDL_context_owner * arg)946 void init(MDL_context_owner *arg) { m_owner= arg; } 947 set_needs_thr_lock_abort(bool needs_thr_lock_abort)948 void set_needs_thr_lock_abort(bool needs_thr_lock_abort) 949 { 950 /* 951 @note In theory, this member should be modified under protection 952 of some lock since it can be accessed from different threads. 953 In practice, this is not necessary as code which reads this 954 value and so might miss the fact that value was changed will 955 always re-try reading it after small timeout and therefore 956 will see the new value eventually. 957 */ 958 m_needs_thr_lock_abort= needs_thr_lock_abort; 959 } get_needs_thr_lock_abort()960 bool get_needs_thr_lock_abort() const 961 { 962 return m_needs_thr_lock_abort; 963 } 964 public: 965 /** 966 If our request for a lock is scheduled, or aborted by the deadlock 967 detector, the result is recorded in this class. 968 */ 969 MDL_wait m_wait; 970 private: 971 /** 972 Lists of all MDL tickets acquired by this connection. 973 974 Lists of MDL tickets: 975 --------------------- 976 The entire set of locks acquired by a connection can be separated 977 in three subsets according to their duration: locks released at 978 the end of statement, at the end of transaction and locks are 979 released explicitly. 980 981 Statement and transactional locks are locks with automatic scope. 982 They are accumulated in the course of a transaction, and released 983 either at the end of uppermost statement (for statement locks) or 984 on COMMIT, ROLLBACK or ROLLBACK TO SAVEPOINT (for transactional 985 locks). They must not be (and never are) released manually, 986 i.e. with release_lock() call. 987 988 Tickets with explicit duration are taken for locks that span 989 multiple transactions or savepoints. 990 These are: HANDLER SQL locks (HANDLER SQL is 991 transaction-agnostic), LOCK TABLES locks (you can COMMIT/etc 992 under LOCK TABLES, and the locked tables stay locked), user level 993 locks (GET_LOCK()/RELEASE_LOCK() functions) and 994 locks implementing "global read lock". 995 996 Statement/transactional locks are always prepended to the 997 beginning of the appropriate list. In other words, they are 998 stored in reverse temporal order. Thus, when we rollback to 999 a savepoint, we start popping and releasing tickets from the 1000 front until we reach the last ticket acquired after the savepoint. 1001 1002 Locks with explicit duration are not stored in any 1003 particular order, and among each other can be split into 1004 four sets: 1005 1006 [LOCK TABLES locks] [USER locks] [HANDLER locks] [GLOBAL READ LOCK locks] 1007 1008 The following is known about these sets: 1009 1010 * GLOBAL READ LOCK locks are always stored last. 1011 This is because one can't say SET GLOBAL read_only=1 or 1012 FLUSH TABLES WITH READ LOCK if one has locked tables. One can, 1013 however, LOCK TABLES after having entered the read only mode. 1014 Note, that subsequent LOCK TABLES statement will unlock the previous 1015 set of tables, but not the GRL! 1016 There are no HANDLER locks after GRL locks because 1017 SET GLOBAL read_only performs a FLUSH TABLES WITH 1018 READ LOCK internally, and FLUSH TABLES, in turn, implicitly 1019 closes all open HANDLERs. 1020 However, one can open a few HANDLERs after entering the 1021 read only mode. 1022 * LOCK TABLES locks include intention exclusive locks on 1023 involved schemas and global intention exclusive lock. 1024 */ 1025 Ticket_list m_tickets[MDL_DURATION_END]; 1026 MDL_context_owner *m_owner; 1027 /** 1028 TRUE - if for this context we will break protocol and try to 1029 acquire table-level locks while having only S lock on 1030 some table. 1031 To avoid deadlocks which might occur during concurrent 1032 upgrade of SNRW lock on such object to X lock we have to 1033 abort waits for table-level locks for such connections. 1034 FALSE - Otherwise. 1035 */ 1036 bool m_needs_thr_lock_abort; 1037 1038 /** 1039 Read-write lock protecting m_waiting_for member. 1040 1041 @note The fact that this read-write lock prefers readers is 1042 important as deadlock detector won't work correctly 1043 otherwise. @sa Comment for MDL_lock::m_rwlock. 1044 */ 1045 mysql_prlock_t m_LOCK_waiting_for; 1046 /** 1047 Tell the deadlock detector what metadata lock or table 1048 definition cache entry this session is waiting for. 1049 In principle, this is redundant, as information can be found 1050 by inspecting waiting queues, but we'd very much like it to be 1051 readily available to the wait-for graph iterator. 1052 */ 1053 MDL_wait_for_subgraph *m_waiting_for; 1054 LF_PINS *m_pins; 1055 uint m_deadlock_overweight= 0; 1056 private: 1057 MDL_ticket *find_ticket(MDL_request *mdl_req, 1058 enum_mdl_duration *duration); 1059 void release_locks_stored_before(enum_mdl_duration duration, MDL_ticket *sentinel); 1060 void release_lock(enum_mdl_duration duration, MDL_ticket *ticket); 1061 bool try_acquire_lock_impl(MDL_request *mdl_request, 1062 MDL_ticket **out_ticket); 1063 bool fix_pins(); 1064 1065 public: get_thd()1066 THD *get_thd() const { return m_owner->get_thd(); } 1067 bool has_explicit_locks(); 1068 void find_deadlock(); 1069 get_thread_id()1070 ulong get_thread_id() const { return thd_get_thread_id(get_thd()); } 1071 1072 bool visit_subgraph(MDL_wait_for_graph_visitor *dvisitor); 1073 1074 /** Inform the deadlock detector there is an edge in the wait-for graph. */ will_wait_for(MDL_wait_for_subgraph * waiting_for_arg)1075 void will_wait_for(MDL_wait_for_subgraph *waiting_for_arg) 1076 { 1077 mysql_prlock_wrlock(&m_LOCK_waiting_for); 1078 m_waiting_for= waiting_for_arg; 1079 mysql_prlock_unlock(&m_LOCK_waiting_for); 1080 } 1081 1082 /** Remove the wait-for edge from the graph after we're done waiting. */ done_waiting_for()1083 void done_waiting_for() 1084 { 1085 mysql_prlock_wrlock(&m_LOCK_waiting_for); 1086 m_waiting_for= NULL; 1087 mysql_prlock_unlock(&m_LOCK_waiting_for); 1088 } lock_deadlock_victim()1089 void lock_deadlock_victim() 1090 { 1091 mysql_prlock_rdlock(&m_LOCK_waiting_for); 1092 } unlock_deadlock_victim()1093 void unlock_deadlock_victim() 1094 { 1095 mysql_prlock_unlock(&m_LOCK_waiting_for); 1096 } 1097 private: 1098 MDL_context(const MDL_context &rhs); /* not implemented */ 1099 MDL_context &operator=(MDL_context &rhs); /* not implemented */ 1100 1101 /* metadata_lock_info plugin */ 1102 friend int i_s_metadata_lock_info_fill_row(MDL_ticket*, void*); 1103 }; 1104 1105 1106 void mdl_init(); 1107 void mdl_destroy(); 1108 1109 extern "C" unsigned long thd_get_thread_id(const MYSQL_THD thd); 1110 1111 /** 1112 Check if a connection in question is no longer connected. 1113 1114 @details 1115 Replication apply thread is always connected. Otherwise, 1116 does a poll on the associated socket to check if the client 1117 is gone. 1118 */ 1119 extern "C" int thd_is_connected(MYSQL_THD thd); 1120 1121 1122 /* 1123 Metadata locking subsystem tries not to grant more than 1124 max_write_lock_count high-prio, strong locks successively, 1125 to avoid starving out weak, low-prio locks. 1126 */ 1127 extern "C" ulong max_write_lock_count; 1128 1129 typedef int (*mdl_iterator_callback)(MDL_ticket *ticket, void *arg, 1130 bool granted); 1131 extern MYSQL_PLUGIN_IMPORT 1132 int mdl_iterate(mdl_iterator_callback callback, void *arg); 1133 #endif /* MDL_H */ 1134