1 #ifndef MDL_H 2 #define MDL_H 3 /* Copyright (c) 2009, 2021, Oracle and/or its affiliates. 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 22 along with this program; if not, write to the Free Software Foundation, 23 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */ 24 25 #include "sql_plist.h" 26 #include <my_sys.h> 27 #include <m_string.h> 28 #include <mysql_com.h> 29 30 #include <algorithm> 31 32 class THD; 33 34 struct MDL_key; 35 class MDL_context; 36 class MDL_lock; 37 class MDL_ticket; 38 typedef struct st_lf_pins LF_PINS; 39 40 /** 41 @def ENTER_COND(C, M, S, O) 42 Start a wait on a condition. 43 @param C the condition to wait on 44 @param M the associated mutex 45 @param S the new stage to enter 46 @param O the previous stage 47 @sa EXIT_COND(). 48 */ 49 #define ENTER_COND(C, M, S, O) enter_cond(C, M, S, O, __func__, __FILE__, __LINE__) 50 51 /** 52 @def EXIT_COND(S) 53 End a wait on a condition 54 @param S the new stage to enter 55 */ 56 #define EXIT_COND(S) exit_cond(S, __func__, __FILE__, __LINE__) 57 58 /** 59 An interface to separate the MDL module from the THD, and the rest of the 60 server code. 61 */ 62 63 class MDL_context_owner 64 { 65 public: ~MDL_context_owner()66 virtual ~MDL_context_owner() {} 67 68 /** 69 Enter a condition wait. 70 For @c enter_cond() / @c exit_cond() to work the mutex must be held before 71 @c enter_cond(); this mutex must then be released before @c exit_cond(). 72 Usage must be: lock mutex; enter_cond(); your code; unlock mutex; exit_cond(). 73 @param cond the condition to wait on 74 @param mutex the associated mutex 75 @param [in] stage the stage to enter, or NULL 76 @param [out] old_stage the previous stage, or NULL 77 @param src_function function name of the caller 78 @param src_file file name of the caller 79 @param src_line line number of the caller 80 @sa ENTER_COND(), THD::enter_cond() 81 @sa EXIT_COND(), THD::exit_cond() 82 */ 83 virtual void enter_cond(mysql_cond_t *cond, mysql_mutex_t *mutex, 84 const PSI_stage_info *stage, PSI_stage_info *old_stage, 85 const char *src_function, const char *src_file, 86 int src_line) = 0; 87 88 /** 89 @def EXIT_COND(S) 90 End a wait on a condition 91 @param [in] stage the new stage to enter 92 @param src_function function name of the caller 93 @param src_file file name of the caller 94 @param src_line line number of the caller 95 @sa ENTER_COND(), THD::enter_cond() 96 @sa EXIT_COND(), THD::exit_cond() 97 */ 98 virtual void exit_cond(const PSI_stage_info *stage, 99 const char *src_function, const char *src_file, 100 int src_line) = 0; 101 /** 102 Has the owner thread been killed? 103 */ 104 virtual int is_killed() = 0; 105 106 /** 107 Does the owner still have connection to the client? 108 */ 109 virtual bool is_connected() = 0; 110 111 /** 112 Within MDL subsystem this one is only used for DEBUG_SYNC. 113 Do not use it to peek/poke into other parts of THD from MDL. 114 However it is OK to use this method in callbacks provided 115 by SQL-layer to MDL subsystem (since SQL-layer has full 116 access to THD anyway). 117 */ 118 virtual THD* get_thd() = 0; 119 120 /** 121 @see THD::notify_shared_lock() 122 */ 123 virtual void notify_shared_lock(MDL_context_owner *in_use, 124 bool needs_thr_lock_abort) = 0; 125 126 /** 127 Notify/get permission from interested storage engines before acquiring 128 exclusive lock for the key. 129 130 The returned argument 'victimized' specify reason for lock 131 not granted. If 'true', lock was refused in an attempt to 132 resolve a possible MDL->GSL deadlock. Locking may then be retried. 133 134 @return False if notification was successful and it is OK to acquire lock, 135 True if one of SEs asks to abort lock acquisition. 136 */ 137 virtual bool notify_hton_pre_acquire_exclusive(const MDL_key *mdl_key, 138 bool *victimized) = 0; 139 /** 140 Notify interested storage engines that we have just released exclusive 141 lock for the key. 142 */ 143 virtual void notify_hton_post_release_exclusive(const MDL_key *mdl_key) = 0; 144 145 /** 146 Get random seed specific to this THD to be used for initialization 147 of PRNG for the MDL_context. 148 */ 149 virtual uint get_rand_seed() = 0; 150 }; 151 152 /** 153 Type of metadata lock request. 154 155 @sa Comments for MDL_object_lock::can_grant_lock() and 156 MDL_scoped_lock::can_grant_lock() for details. 157 */ 158 159 enum enum_mdl_type { 160 /* 161 An intention exclusive metadata lock. Used only for scoped locks. 162 Owner of this type of lock can acquire upgradable exclusive locks on 163 individual objects. 164 Compatible with other IX locks, but is incompatible with scoped S and 165 X locks. 166 */ 167 MDL_INTENTION_EXCLUSIVE= 0, 168 /* 169 A shared metadata lock. 170 To be used in cases when we are interested in object metadata only 171 and there is no intention to access object data (e.g. for stored 172 routines or during preparing prepared statements). 173 We also mis-use this type of lock for open HANDLERs, since lock 174 acquired by this statement has to be compatible with lock acquired 175 by LOCK TABLES ... WRITE statement, i.e. SNRW (We can't get by by 176 acquiring S lock at HANDLER ... OPEN time and upgrading it to SR 177 lock for HANDLER ... READ as it doesn't solve problem with need 178 to abort DML statements which wait on table level lock while having 179 open HANDLER in the same connection). 180 To avoid deadlock which may occur when SNRW lock is being upgraded to 181 X lock for table on which there is an active S lock which is owned by 182 thread which waits in its turn for table-level lock owned by thread 183 performing upgrade we have to use thr_abort_locks_for_thread() 184 facility in such situation. 185 This problem does not arise for locks on stored routines as we don't 186 use SNRW locks for them. It also does not arise when S locks are used 187 during PREPARE calls as table-level locks are not acquired in this 188 case. 189 */ 190 MDL_SHARED, 191 /* 192 A high priority shared metadata lock. 193 Used for cases when there is no intention to access object data (i.e. 194 data in the table). 195 "High priority" means that, unlike other shared locks, it is granted 196 ignoring pending requests for exclusive locks. Intended for use in 197 cases when we only need to access metadata and not data, e.g. when 198 filling an INFORMATION_SCHEMA table. 199 Since SH lock is compatible with SNRW lock, the connection that 200 holds SH lock lock should not try to acquire any kind of table-level 201 or row-level lock, as this can lead to a deadlock. Moreover, after 202 acquiring SH lock, the connection should not wait for any other 203 resource, as it might cause starvation for X locks and a potential 204 deadlock during upgrade of SNW or SNRW to X lock (e.g. if the 205 upgrading connection holds the resource that is being waited for). 206 */ 207 MDL_SHARED_HIGH_PRIO, 208 /* 209 A shared metadata lock for cases when there is an intention to read data 210 from table. 211 A connection holding this kind of lock can read table metadata and read 212 table data (after acquiring appropriate table and row-level locks). 213 This means that one can only acquire TL_READ, TL_READ_NO_INSERT, and 214 similar table-level locks on table if one holds SR MDL lock on it. 215 To be used for tables in SELECTs, subqueries, and LOCK TABLE ... READ 216 statements. 217 */ 218 MDL_SHARED_READ, 219 /* 220 A shared metadata lock for cases when there is an intention to modify 221 (and not just read) data in the table. 222 A connection holding SW lock can read table metadata and modify or read 223 table data (after acquiring appropriate table and row-level locks). 224 To be used for tables to be modified by INSERT, UPDATE, DELETE 225 statements, but not LOCK TABLE ... WRITE or DDL). Also taken by 226 SELECT ... FOR UPDATE. 227 */ 228 MDL_SHARED_WRITE, 229 /* 230 A version of MDL_SHARED_WRITE lock which has lower priority than 231 MDL_SHARED_READ_ONLY locks. Used by DML statements modifying 232 tables and using the LOW_PRIORITY clause. 233 */ 234 MDL_SHARED_WRITE_LOW_PRIO, 235 /* 236 An upgradable shared metadata lock which allows concurrent updates and 237 reads of table data. 238 A connection holding this kind of lock can read table metadata and read 239 table data. It should not modify data as this lock is compatible with 240 SRO locks. 241 Can be upgraded to SNW, SNRW and X locks. Once SU lock is upgraded to X 242 or SNRW lock data modification can happen freely. 243 To be used for the first phase of ALTER TABLE. 244 */ 245 MDL_SHARED_UPGRADABLE, 246 /* 247 A shared metadata lock for cases when we need to read data from table 248 and block all concurrent modifications to it (for both data and metadata). 249 Used by LOCK TABLES READ statement. 250 */ 251 MDL_SHARED_READ_ONLY, 252 /* 253 An upgradable shared metadata lock which blocks all attempts to update 254 table data, allowing reads. 255 A connection holding this kind of lock can read table metadata and read 256 table data. 257 Can be upgraded to X metadata lock. 258 Note, that since this type of lock is not compatible with SNRW or SW 259 lock types, acquiring appropriate engine-level locks for reading 260 (TL_READ* for MyISAM, shared row locks in InnoDB) should be 261 contention-free. 262 To be used for the first phase of ALTER TABLE, when copying data between 263 tables, to allow concurrent SELECTs from the table, but not UPDATEs. 264 */ 265 MDL_SHARED_NO_WRITE, 266 /* 267 An upgradable shared metadata lock which allows other connections 268 to access table metadata, but not data. 269 It blocks all attempts to read or update table data, while allowing 270 INFORMATION_SCHEMA and SHOW queries. 271 A connection holding this kind of lock can read table metadata modify and 272 read table data. 273 Can be upgraded to X metadata lock. 274 To be used for LOCK TABLES WRITE statement. 275 Not compatible with any other lock type except S and SH. 276 */ 277 MDL_SHARED_NO_READ_WRITE, 278 /* 279 An exclusive metadata lock. 280 A connection holding this lock can modify both table's metadata and data. 281 No other type of metadata lock can be granted while this lock is held. 282 To be used for CREATE/DROP/RENAME TABLE statements and for execution of 283 certain phases of other DDL statements. 284 */ 285 MDL_EXCLUSIVE, 286 /* This should be the last !!! */ 287 MDL_TYPE_END}; 288 289 290 /** Duration of metadata lock. */ 291 292 enum enum_mdl_duration { 293 /** 294 Locks with statement duration are automatically released at the end 295 of statement or transaction. 296 */ 297 MDL_STATEMENT= 0, 298 /** 299 Locks with transaction duration are automatically released at the end 300 of transaction. 301 */ 302 MDL_TRANSACTION, 303 /** 304 Locks with explicit duration survive the end of statement and transaction. 305 They have to be released explicitly by calling MDL_context::release_lock(). 306 */ 307 MDL_EXPLICIT, 308 /* This should be the last ! */ 309 MDL_DURATION_END }; 310 311 312 /** Maximal length of key for metadata locking subsystem. */ 313 #define MAX_MDLKEY_LENGTH (1 + NAME_LEN + 1 + NAME_LEN + 1) 314 315 316 /** 317 Metadata lock object key. 318 319 A lock is requested or granted based on a fully qualified name and type. 320 E.g. They key for a table consists of <0 (=table)>+<database>+<table name>. 321 Elsewhere in the comments this triple will be referred to simply as "key" 322 or "name". 323 */ 324 325 struct MDL_key 326 { 327 public: 328 #ifdef HAVE_PSI_INTERFACE 329 static void init_psi_keys(); 330 #endif 331 332 /** 333 Object namespaces. 334 Sic: when adding a new member to this enum make sure to 335 update m_namespace_to_wait_state_name array in mdl.cc! 336 337 Different types of objects exist in different namespaces 338 - GLOBAL is used for the global read lock. 339 - TABLESPACE is for tablespaces. 340 - SCHEMA is for schemas (aka databases). 341 - TABLE is for tables and views. 342 - FUNCTION is for stored functions. 343 - PROCEDURE is for stored procedures. 344 - TRIGGER is for triggers. 345 - EVENT is for event scheduler events. 346 - COMMIT is for enabling the global read lock to block commits. 347 - USER_LEVEL_LOCK is for user-level locks. 348 - LOCKING_SERVICE is for the name plugin RW-lock service 349 Note that although there isn't metadata locking on triggers, 350 it's necessary to have a separate namespace for them since 351 MDL_key is also used outside of the MDL subsystem. 352 Also note that requests waiting for user-level locks get special 353 treatment - waiting is aborted if connection to client is lost. 354 */ 355 enum enum_mdl_namespace { GLOBAL=0, 356 TABLESPACE, 357 SCHEMA, 358 TABLE, 359 FUNCTION, 360 PROCEDURE, 361 TRIGGER, 362 EVENT, 363 COMMIT, 364 USER_LEVEL_LOCK, 365 LOCKING_SERVICE, 366 BACKUP, 367 BINLOG, 368 /* This should be the last ! */ 369 NAMESPACE_END }; 370 ptrMDL_key371 const uchar *ptr() const { return (uchar*) m_ptr; } lengthMDL_key372 uint length() const { return m_length; } 373 db_nameMDL_key374 const char *db_name() const { return m_ptr + 1; } db_name_lengthMDL_key375 uint db_name_length() const { return m_db_name_length; } 376 nameMDL_key377 const char *name() const { return m_ptr + m_db_name_length + 2; } name_lengthMDL_key378 uint name_length() const { return m_length - m_db_name_length - 3; } 379 mdl_namespaceMDL_key380 enum_mdl_namespace mdl_namespace() const 381 { return (enum_mdl_namespace)(m_ptr[0]); } 382 383 /** 384 Construct a metadata lock key from a triplet (mdl_namespace, 385 database and name). 386 387 @remark The key for a table is <mdl_namespace>+<database name>+<table name> 388 389 @param mdl_namespace Id of namespace of object to be locked 390 @param db Name of database to which the object belongs 391 @param name Name of of the object 392 */ mdl_key_initMDL_key393 void mdl_key_init(enum_mdl_namespace mdl_namespace, 394 const char *db, const char *name) 395 { 396 m_ptr[0]= (char) mdl_namespace; 397 /* 398 It is responsibility of caller to ensure that db and object names 399 are not longer than NAME_LEN. Still we play safe and try to avoid 400 buffer overruns. 401 */ 402 assert(strlen(db) <= NAME_LEN && strlen(name) <= NAME_LEN); 403 m_db_name_length= static_cast<uint16>(strmake(m_ptr + 1, db, NAME_LEN) - 404 m_ptr - 1); 405 m_length= static_cast<uint16>(strmake(m_ptr + m_db_name_length + 2, name, 406 NAME_LEN) - m_ptr + 1); 407 } mdl_key_initMDL_key408 void mdl_key_init(const MDL_key *rhs) 409 { 410 memcpy(m_ptr, rhs->m_ptr, rhs->m_length); 411 m_length= rhs->m_length; 412 m_db_name_length= rhs->m_db_name_length; 413 } resetMDL_key414 void reset() 415 { 416 m_ptr[0]= NAMESPACE_END; 417 m_db_name_length= 0; 418 m_length= 0; 419 } is_equalMDL_key420 bool is_equal(const MDL_key *rhs) const 421 { 422 return (m_length == rhs->m_length && 423 memcmp(m_ptr, rhs->m_ptr, m_length) == 0); 424 } 425 /** 426 Compare two MDL keys lexicographically. 427 */ cmpMDL_key428 int cmp(const MDL_key *rhs) const 429 { 430 /* 431 The key buffer is always '\0'-terminated. Since key 432 character set is utf-8, we can safely assume that no 433 character starts with a zero byte. 434 */ 435 return memcmp(m_ptr, rhs->m_ptr, std::min(m_length, rhs->m_length)); 436 } 437 MDL_keyMDL_key438 MDL_key(const MDL_key *rhs) 439 { 440 mdl_key_init(rhs); 441 } MDL_keyMDL_key442 MDL_key(enum_mdl_namespace namespace_arg, 443 const char *db_arg, const char *name_arg) 444 { 445 mdl_key_init(namespace_arg, db_arg, name_arg); 446 } MDL_keyMDL_key447 MDL_key() {} /* To use when part of MDL_request. */ 448 449 /** 450 Get thread state name to be used in case when we have to 451 wait on resource identified by key. 452 */ get_wait_state_nameMDL_key453 const PSI_stage_info * get_wait_state_name() const 454 { 455 return & m_namespace_to_wait_state_name[(int)mdl_namespace()]; 456 } 457 458 private: 459 uint16 m_length; 460 uint16 m_db_name_length; 461 char m_ptr[MAX_MDLKEY_LENGTH]; 462 static PSI_stage_info m_namespace_to_wait_state_name[NAMESPACE_END]; 463 private: 464 MDL_key(const MDL_key &); /* not implemented */ 465 MDL_key &operator=(const MDL_key &); /* not implemented */ 466 }; 467 468 469 /** 470 A pending metadata lock request. 471 472 A lock request and a granted metadata lock are represented by 473 different classes because they have different allocation 474 sites and hence different lifetimes. The allocation of lock requests is 475 controlled from outside of the MDL subsystem, while allocation of granted 476 locks (tickets) is controlled within the MDL subsystem. 477 478 MDL_request is a C structure, you don't need to call a constructor 479 or destructor for it. 480 */ 481 482 class MDL_request 483 { 484 public: 485 /** Type of metadata lock. */ 486 enum enum_mdl_type type; 487 /** Duration for requested lock. */ 488 enum enum_mdl_duration duration; 489 490 /** 491 Pointers for participating in the list of lock requests for this context. 492 */ 493 MDL_request *next_in_list; 494 MDL_request **prev_in_list; 495 /** 496 Pointer to the lock ticket object for this lock request. 497 Valid only if this lock request is satisfied. 498 */ 499 MDL_ticket *ticket; 500 501 /** A lock is requested based on a fully qualified name and type. */ 502 MDL_key key; 503 504 const char *m_src_file; 505 uint m_src_line; 506 507 public: new(size_t size,MEM_ROOT * mem_root)508 static void *operator new(size_t size, MEM_ROOT *mem_root) throw () 509 { return alloc_root(mem_root, size); } delete(void * ptr,MEM_ROOT * mem_root)510 static void operator delete(void *ptr, MEM_ROOT *mem_root) {} 511 512 void init_with_source(MDL_key::enum_mdl_namespace namespace_arg, 513 const char *db_arg, const char *name_arg, 514 enum_mdl_type mdl_type_arg, 515 enum_mdl_duration mdl_duration_arg, 516 const char *src_file, uint src_line); 517 void init_by_key_with_source(const MDL_key *key_arg, enum_mdl_type mdl_type_arg, 518 enum_mdl_duration mdl_duration_arg, 519 const char *src_file, uint src_line); 520 /** Set type of lock request. Can be only applied to pending locks. */ set_type(enum_mdl_type type_arg)521 inline void set_type(enum_mdl_type type_arg) 522 { 523 assert(ticket == NULL); 524 type= type_arg; 525 } 526 527 /** 528 Is this a request for a lock which allow data to be updated? 529 530 @note This method returns true for MDL_SHARED_UPGRADABLE type of 531 lock. Even though this type of lock doesn't allow updates 532 it will always be upgraded to one that does. 533 */ is_write_lock_request()534 bool is_write_lock_request() const 535 { 536 return (type >= MDL_SHARED_WRITE && 537 type != MDL_SHARED_READ_ONLY); 538 } 539 540 /** Is this a request for a strong, DDL/LOCK TABLES-type, of lock? */ is_ddl_or_lock_tables_lock_request()541 bool is_ddl_or_lock_tables_lock_request() const 542 { 543 return type >= MDL_SHARED_UPGRADABLE; 544 } 545 546 /* 547 This is to work around the ugliness of TABLE_LIST 548 compiler-generated assignment operator. It is currently used 549 in several places to quickly copy "most" of the members of the 550 table list. These places currently never assume that the mdl 551 request is carried over to the new TABLE_LIST, or shared 552 between lists. 553 554 This method does not initialize the instance being assigned! 555 Use of init() for initialization after this assignment operator 556 is mandatory. Can only be used before the request has been 557 granted. 558 */ 559 MDL_request& operator=(const MDL_request &rhs) 560 { 561 ticket= NULL; 562 /* Do nothing, in particular, don't try to copy the key. */ 563 return *this; 564 } 565 /* Another piece of ugliness for TABLE_LIST constructor */ MDL_request()566 MDL_request() {} 567 MDL_request(const MDL_request * rhs)568 MDL_request(const MDL_request *rhs) 569 :type(rhs->type), 570 duration(rhs->duration), 571 ticket(NULL), 572 key(&rhs->key) 573 {} 574 }; 575 576 #define MDL_REQUEST_INIT(R, P1, P2, P3, P4, P5) \ 577 (*R).init_with_source(P1, P2, P3, P4, P5, __FILE__, __LINE__) 578 579 #define MDL_REQUEST_INIT_BY_KEY(R, P1, P2, P3) \ 580 (*R).init_by_key_with_source(P1, P2, P3, __FILE__, __LINE__) 581 582 583 /** 584 An abstract class for inspection of a connected 585 subgraph of the wait-for graph. 586 */ 587 588 class MDL_wait_for_graph_visitor 589 { 590 public: 591 virtual bool enter_node(MDL_context *node) = 0; 592 virtual void leave_node(MDL_context *node) = 0; 593 594 virtual bool inspect_edge(MDL_context *dest) = 0; 595 virtual ~MDL_wait_for_graph_visitor(); MDL_wait_for_graph_visitor()596 MDL_wait_for_graph_visitor() :m_lock_open_count(0) {} 597 public: 598 /** 599 XXX, hack: During deadlock search, we may need to 600 inspect TABLE_SHAREs and acquire LOCK_open. Since 601 LOCK_open is not a recursive mutex, count here how many 602 times we "took" it (but only take and release once). 603 Not using a native recursive mutex or rwlock in 5.5 for 604 LOCK_open since it has significant performance impacts. 605 */ 606 uint m_lock_open_count; 607 }; 608 609 /** 610 Abstract class representing an edge in the waiters graph 611 to be traversed by deadlock detection algorithm. 612 */ 613 614 class MDL_wait_for_subgraph 615 { 616 public: 617 virtual ~MDL_wait_for_subgraph(); 618 619 /** 620 Accept a wait-for graph visitor to inspect the node 621 this edge is leading to. 622 */ 623 virtual bool accept_visitor(MDL_wait_for_graph_visitor *gvisitor) = 0; 624 625 static const uint DEADLOCK_WEIGHT_DML= 0; 626 static const uint DEADLOCK_WEIGHT_ULL= 50; 627 static const uint DEADLOCK_WEIGHT_DDL= 100; 628 629 /* A helper used to determine which lock request should be aborted. */ 630 virtual uint get_deadlock_weight() const = 0; 631 }; 632 633 634 /** 635 A granted metadata lock. 636 637 @warning MDL_ticket members are private to the MDL subsystem. 638 639 @note Multiple shared locks on a same object are represented by a 640 single ticket. The same does not apply for other lock types. 641 642 @note There are two groups of MDL_ticket members: 643 - "Externally accessible". These members can be accessed from 644 threads/contexts different than ticket owner in cases when 645 ticket participates in some list of granted or waiting tickets 646 for a lock. Therefore one should change these members before 647 including then to waiting/granted lists or while holding lock 648 protecting those lists. 649 - "Context private". Such members are private to thread/context 650 owning this ticket. I.e. they should not be accessed from other 651 threads/contexts. 652 */ 653 654 class MDL_ticket : public MDL_wait_for_subgraph 655 { 656 public: 657 /** 658 Pointers for participating in the list of lock requests for this context. 659 Context private. 660 */ 661 MDL_ticket *next_in_context; 662 MDL_ticket **prev_in_context; 663 /** 664 Pointers for participating in the list of satisfied/pending requests 665 for the lock. Externally accessible. 666 */ 667 MDL_ticket *next_in_lock; 668 MDL_ticket **prev_in_lock; 669 public: 670 bool has_pending_conflicting_lock() const; 671 get_ctx()672 MDL_context *get_ctx() const { return m_ctx; } is_upgradable_or_exclusive()673 bool is_upgradable_or_exclusive() const 674 { 675 return m_type == MDL_SHARED_UPGRADABLE || 676 m_type == MDL_SHARED_NO_WRITE || 677 m_type == MDL_SHARED_NO_READ_WRITE || 678 m_type == MDL_EXCLUSIVE; 679 } get_type()680 enum_mdl_type get_type() const { return m_type; } get_lock()681 MDL_lock *get_lock() const { return m_lock; } 682 const MDL_key *get_key() const; 683 void downgrade_lock(enum_mdl_type type); 684 685 bool has_stronger_or_equal_type(enum_mdl_type type) const; 686 687 bool is_incompatible_when_granted(enum_mdl_type type) const; 688 bool is_incompatible_when_waiting(enum_mdl_type type) const; 689 690 /** Implement MDL_wait_for_subgraph interface. */ 691 virtual bool accept_visitor(MDL_wait_for_graph_visitor *dvisitor); 692 virtual uint get_deadlock_weight() const; 693 694 public: 695 /** 696 Status of lock request represented by the ticket as reflected in P_S. 697 */ 698 enum enum_psi_status { PENDING = 0, GRANTED, 699 PRE_ACQUIRE_NOTIFY, POST_RELEASE_NOTIFY }; 700 701 private: 702 friend class MDL_context; 703 MDL_ticket(MDL_context * ctx_arg,enum_mdl_type type_arg,enum_mdl_duration duration_arg)704 MDL_ticket(MDL_context *ctx_arg, enum_mdl_type type_arg 705 #ifndef NDEBUG 706 , enum_mdl_duration duration_arg 707 #endif 708 ) 709 : m_type(type_arg), 710 #ifndef NDEBUG 711 m_duration(duration_arg), 712 #endif 713 m_ctx(ctx_arg), 714 m_lock(NULL), 715 m_is_fast_path(false), 716 m_hton_notified(false), 717 m_psi(NULL) 718 {} 719 ~MDL_ticket()720 virtual ~MDL_ticket() 721 { 722 assert(m_psi == NULL); 723 } 724 725 static MDL_ticket *create(MDL_context *ctx_arg, enum_mdl_type type_arg 726 #ifndef NDEBUG 727 , enum_mdl_duration duration_arg 728 #endif 729 ); 730 static void destroy(MDL_ticket *ticket); 731 private: 732 /** Type of metadata lock. Externally accessible. */ 733 enum enum_mdl_type m_type; 734 #ifndef NDEBUG 735 /** 736 Duration of lock represented by this ticket. 737 Context private. Debug-only. 738 */ 739 enum_mdl_duration m_duration; 740 #endif 741 /** 742 Context of the owner of the metadata lock ticket. Externally accessible. 743 */ 744 MDL_context *m_ctx; 745 746 /** 747 Pointer to the lock object for this lock ticket. Externally accessible. 748 */ 749 MDL_lock *m_lock; 750 751 /** 752 Indicates that ticket corresponds to lock acquired using "fast path" 753 algorithm. Particularly this means that it was not included into 754 MDL_lock::m_granted bitmap/list and instead is accounted for by 755 MDL_lock::m_fast_path_locks_granted_counter 756 */ 757 bool m_is_fast_path; 758 759 /** 760 Indicates that ticket corresponds to lock request which required 761 storage engine notification during its acquisition and requires 762 storage engine notification after its release. 763 */ 764 bool m_hton_notified; 765 766 PSI_metadata_lock *m_psi; 767 768 private: 769 MDL_ticket(const MDL_ticket &); /* not implemented */ 770 MDL_ticket &operator=(const MDL_ticket &); /* not implemented */ 771 }; 772 773 774 /** 775 Savepoint for MDL context. 776 777 Doesn't include metadata locks with explicit duration as 778 they are not released during rollback to savepoint. 779 */ 780 781 class MDL_savepoint 782 { 783 public: MDL_savepoint()784 MDL_savepoint() {}; 785 786 private: MDL_savepoint(MDL_ticket * stmt_ticket,MDL_ticket * trans_ticket)787 MDL_savepoint(MDL_ticket *stmt_ticket, MDL_ticket *trans_ticket) 788 : m_stmt_ticket(stmt_ticket), m_trans_ticket(trans_ticket) 789 {} 790 791 friend class MDL_context; 792 793 private: 794 /** 795 Pointer to last lock with statement duration which was taken 796 before creation of savepoint. 797 */ 798 MDL_ticket *m_stmt_ticket; 799 /** 800 Pointer to last lock with transaction duration which was taken 801 before creation of savepoint. 802 */ 803 MDL_ticket *m_trans_ticket; 804 }; 805 806 807 /** 808 A reliable way to wait on an MDL lock. 809 */ 810 811 class MDL_wait 812 { 813 public: 814 MDL_wait(); 815 ~MDL_wait(); 816 817 enum enum_wait_status { EMPTY = 0, GRANTED, VICTIM, TIMEOUT, KILLED }; 818 819 bool set_status(enum_wait_status result_arg); 820 enum_wait_status get_status(); 821 void reset_status(); 822 enum_wait_status timed_wait(MDL_context_owner *owner, 823 struct timespec *abs_timeout, 824 bool signal_timeout, 825 const PSI_stage_info *wait_state_name); 826 private: 827 828 /** 829 Condvar which is used for waiting until this context's pending 830 request can be satisfied or this thread has to perform actions 831 to resolve a potential deadlock (we subscribe to such 832 notification by adding a ticket corresponding to the request 833 to an appropriate queue of waiters). 834 */ 835 mysql_mutex_t m_LOCK_wait_status; 836 mysql_cond_t m_COND_wait_status; 837 enum_wait_status m_wait_status; 838 }; 839 840 841 /** 842 Base class to find out if the lock represented by a given ticket 843 should be released. Users of release_locks() need to subclass 844 this and specify an implementation of release(). Only for locks 845 with explicit duration. 846 */ 847 848 class MDL_release_locks_visitor 849 { 850 public: ~MDL_release_locks_visitor()851 virtual ~MDL_release_locks_visitor() {} 852 /** 853 Check if the given ticket represents a lock that should be released. 854 855 @retval true if the lock should be released, false otherwise. 856 */ 857 virtual bool release(MDL_ticket *ticket) = 0; 858 }; 859 860 861 /** 862 Abstract visitor class for inspecting MDL_context. 863 */ 864 865 class MDL_context_visitor 866 { 867 public: ~MDL_context_visitor()868 virtual ~MDL_context_visitor() {} 869 virtual void visit_context(const MDL_context *ctx) = 0; 870 }; 871 872 873 typedef I_P_List<MDL_request, I_P_List_adapter<MDL_request, 874 &MDL_request::next_in_list, 875 &MDL_request::prev_in_list>, 876 I_P_List_counter> 877 MDL_request_list; 878 879 /** 880 Context of the owner of metadata locks. I.e. each server 881 connection has such a context. 882 */ 883 884 class MDL_context 885 { 886 public: 887 typedef I_P_List<MDL_ticket, 888 I_P_List_adapter<MDL_ticket, 889 &MDL_ticket::next_in_context, 890 &MDL_ticket::prev_in_context> > 891 Ticket_list; 892 893 typedef Ticket_list::Iterator Ticket_iterator; 894 895 MDL_context(); 896 void destroy(); 897 898 bool try_acquire_lock(MDL_request *mdl_request); 899 bool acquire_lock(MDL_request *mdl_request, ulong lock_wait_timeout); 900 bool acquire_locks(MDL_request_list *requests, ulong lock_wait_timeout); 901 bool upgrade_shared_lock(MDL_ticket *mdl_ticket, 902 enum_mdl_type new_type, 903 ulong lock_wait_timeout); 904 905 bool clone_ticket(MDL_request *mdl_request); 906 907 void release_all_locks_for_name(MDL_ticket *ticket); 908 void release_locks(MDL_release_locks_visitor *visitor); 909 void release_lock(MDL_ticket *ticket); 910 911 bool owns_equal_or_stronger_lock(MDL_key::enum_mdl_namespace mdl_namespace, 912 const char *db, const char *name, 913 enum_mdl_type mdl_type); 914 915 bool find_lock_owner(const MDL_key *mdl_key, MDL_context_visitor *visitor); 916 917 bool has_lock(const MDL_savepoint &mdl_savepoint, MDL_ticket *mdl_ticket); 918 has_locks()919 inline bool has_locks() const 920 { 921 return !(m_tickets[MDL_STATEMENT].is_empty() && 922 m_tickets[MDL_TRANSACTION].is_empty() && 923 m_tickets[MDL_EXPLICIT].is_empty()); 924 } 925 926 bool has_locks(MDL_key::enum_mdl_namespace mdl_namespace) const; 927 928 bool has_locks_waited_for() const; 929 mdl_savepoint()930 MDL_savepoint mdl_savepoint() 931 { 932 return MDL_savepoint(m_tickets[MDL_STATEMENT].front(), 933 m_tickets[MDL_TRANSACTION].front()); 934 } 935 936 void set_explicit_duration_for_all_locks(); 937 void set_transaction_duration_for_all_locks(); 938 void set_lock_duration(MDL_ticket *mdl_ticket, enum_mdl_duration duration); 939 940 void release_statement_locks(); 941 void release_transactional_locks(); 942 void rollback_to_savepoint(const MDL_savepoint &mdl_savepoint); 943 get_owner()944 MDL_context_owner *get_owner() const { return m_owner; } 945 946 /** @pre Only valid if we started waiting for lock. */ get_deadlock_weight()947 inline uint get_deadlock_weight() const 948 { 949 return m_force_dml_deadlock_weight ? 950 MDL_wait_for_subgraph::DEADLOCK_WEIGHT_DML : 951 m_waiting_for->get_deadlock_weight(); 952 } 953 init(MDL_context_owner * arg)954 void init(MDL_context_owner *arg) { m_owner= arg; } 955 set_needs_thr_lock_abort(bool needs_thr_lock_abort)956 void set_needs_thr_lock_abort(bool needs_thr_lock_abort) 957 { 958 /* 959 @note In theory, this member should be modified under protection 960 of some lock since it can be accessed from different threads. 961 In practice, this is not necessary as code which reads this 962 value and so might miss the fact that value was changed will 963 always re-try reading it after small timeout and therefore 964 will see the new value eventually. 965 */ 966 m_needs_thr_lock_abort= needs_thr_lock_abort; 967 968 if (m_needs_thr_lock_abort) 969 { 970 /* 971 For MDL_object_lock::notify_conflicting_locks() to work properly 972 all context requiring thr_lock aborts should not have any "fast 973 path" locks. 974 */ 975 materialize_fast_path_locks(); 976 } 977 } get_needs_thr_lock_abort()978 bool get_needs_thr_lock_abort() const 979 { 980 return m_needs_thr_lock_abort; 981 } 982 set_force_dml_deadlock_weight(bool force_dml_deadlock_weight)983 void set_force_dml_deadlock_weight(bool force_dml_deadlock_weight) 984 { 985 m_force_dml_deadlock_weight= force_dml_deadlock_weight; 986 } 987 988 /** 989 Get pseudo random value in [0 .. 2^31-1] range. 990 991 @note We use Linear Congruential Generator with venerable constant 992 parameters for this. 993 It is known to have problems with its lower bits are not being 994 very random so probably is not good enough for generic use. 995 However, we only use it to do random dives into MDL_lock objects 996 hash when searching for unused objects to be freed, and for this 997 purposes it is sufficient. 998 We rely on values of "get_random() % 2^k" expression having "2^k" 999 as a period to ensure that random dives eventually cover all hash 1000 (the former can be proven to be true). This also means that there 1001 is no bias towards any specific objects to be expelled (as hash 1002 values don't repeat), which is nice for performance. 1003 */ get_random()1004 uint get_random() 1005 { 1006 if (m_rand_state > INT_MAX32) 1007 { 1008 /* 1009 Perform lazy initialization of LCG. We can't initialize it at the 1010 point when MDL_context is created since THD represented through 1011 MDL_context_owner interface is not fully initialized at this point 1012 itself. 1013 */ 1014 m_rand_state= m_owner->get_rand_seed() & INT_MAX32; 1015 } 1016 m_rand_state= (m_rand_state * 1103515245 + 12345) & INT_MAX32; 1017 return m_rand_state; 1018 } 1019 1020 /** 1021 Within MDL subsystem this one is only used for DEBUG_SYNC. 1022 Do not use it to peek/poke into other parts of THD from MDL. 1023 @sa MDL_context_owner::get_thd(). 1024 */ get_thd()1025 THD *get_thd() const { return m_owner->get_thd(); } 1026 1027 public: 1028 /** 1029 If our request for a lock is scheduled, or aborted by the deadlock 1030 detector, the result is recorded in this class. 1031 */ 1032 MDL_wait m_wait; 1033 private: 1034 /** 1035 Lists of all MDL tickets acquired by this connection. 1036 1037 Lists of MDL tickets: 1038 --------------------- 1039 The entire set of locks acquired by a connection can be separated 1040 in three subsets according to their duration: locks released at 1041 the end of statement, at the end of transaction and locks are 1042 released explicitly. 1043 1044 Statement and transactional locks are locks with automatic scope. 1045 They are accumulated in the course of a transaction, and released 1046 either at the end of uppermost statement (for statement locks) or 1047 on COMMIT, ROLLBACK or ROLLBACK TO SAVEPOINT (for transactional 1048 locks). They must not be (and never are) released manually, 1049 i.e. with release_lock() call. 1050 1051 Tickets with explicit duration are taken for locks that span 1052 multiple transactions or savepoints. 1053 These are: HANDLER SQL locks (HANDLER SQL is 1054 transaction-agnostic), LOCK TABLES locks (you can COMMIT/etc 1055 under LOCK TABLES, and the locked tables stay locked), user level 1056 locks (GET_LOCK()/RELEASE_LOCK() functions) and 1057 locks implementing "global read lock". 1058 1059 Statement/transactional locks are always prepended to the 1060 beginning of the appropriate list. In other words, they are 1061 stored in reverse temporal order. Thus, when we rollback to 1062 a savepoint, we start popping and releasing tickets from the 1063 front until we reach the last ticket acquired after the savepoint. 1064 1065 Locks with explicit duration are not stored in any 1066 particular order, and among each other can be split into 1067 four sets: 1068 - LOCK TABLES locks 1069 - User-level locks 1070 - HANDLER locks 1071 - GLOBAL READ LOCK locks 1072 */ 1073 Ticket_list m_tickets[MDL_DURATION_END]; 1074 MDL_context_owner *m_owner; 1075 /** 1076 TRUE - if for this context we will break protocol and try to 1077 acquire table-level locks while having only S lock on 1078 some table. 1079 To avoid deadlocks which might occur during concurrent 1080 upgrade of SNRW lock on such object to X lock we have to 1081 abort waits for table-level locks for such connections. 1082 FALSE - Otherwise. 1083 */ 1084 bool m_needs_thr_lock_abort; 1085 1086 /** 1087 Indicates that we need to use DEADLOCK_WEIGHT_DML deadlock 1088 weight for this context and ignore the deadlock weight provided 1089 by the MDL_wait_for_subgraph object which we are waiting for. 1090 1091 @note Can be changed only when there is a guarantee that this 1092 MDL_context is not waiting for a metadata lock or table 1093 definition entry. 1094 */ 1095 bool m_force_dml_deadlock_weight; 1096 1097 /** 1098 Read-write lock protecting m_waiting_for member. 1099 1100 @note The fact that this read-write lock prefers readers is 1101 important as deadlock detector won't work correctly 1102 otherwise. @sa Comment for MDL_lock::m_rwlock. 1103 */ 1104 mysql_prlock_t m_LOCK_waiting_for; 1105 /** 1106 Tell the deadlock detector what metadata lock or table 1107 definition cache entry this session is waiting for. 1108 In principle, this is redundant, as information can be found 1109 by inspecting waiting queues, but we'd very much like it to be 1110 readily available to the wait-for graph iterator. 1111 */ 1112 MDL_wait_for_subgraph *m_waiting_for; 1113 /** 1114 Thread's pins (a.k.a. hazard pointers) to be used by lock-free 1115 implementation of MDL_map::m_locks container. NULL if pins are 1116 not yet allocated from container's pinbox. 1117 */ 1118 LF_PINS *m_pins; 1119 /** 1120 State for pseudo random numbers generator (PRNG) which output 1121 is used to perform random dives into MDL_lock objects hash 1122 when searching for unused objects to free. 1123 */ 1124 uint m_rand_state; 1125 1126 private: 1127 MDL_ticket *find_ticket(MDL_request *mdl_req, 1128 enum_mdl_duration *duration); 1129 void release_locks_stored_before(enum_mdl_duration duration, MDL_ticket *sentinel); 1130 void release_lock(enum_mdl_duration duration, MDL_ticket *ticket); 1131 bool try_acquire_lock_impl(MDL_request *mdl_request, 1132 MDL_ticket **out_ticket); 1133 void materialize_fast_path_locks(); 1134 inline bool fix_pins(); 1135 1136 public: 1137 void find_deadlock(); 1138 1139 bool visit_subgraph(MDL_wait_for_graph_visitor *dvisitor); 1140 1141 /** Inform the deadlock detector there is an edge in the wait-for graph. */ will_wait_for(MDL_wait_for_subgraph * waiting_for_arg)1142 void will_wait_for(MDL_wait_for_subgraph *waiting_for_arg) 1143 { 1144 /* 1145 Before starting wait for any resource we need to materialize 1146 all "fast path" tickets belonging to this thread. Otherwise 1147 locks acquired which are represented by these tickets won't 1148 be present in wait-for graph and could cause missed deadlocks. 1149 1150 It is OK for context which doesn't wait for any resource to 1151 have "fast path" tickets, as such context can't participate 1152 in any deadlock. 1153 */ 1154 materialize_fast_path_locks(); 1155 1156 mysql_prlock_wrlock(&m_LOCK_waiting_for); 1157 m_waiting_for= waiting_for_arg; 1158 mysql_prlock_unlock(&m_LOCK_waiting_for); 1159 } 1160 1161 /** Remove the wait-for edge from the graph after we're done waiting. */ done_waiting_for()1162 void done_waiting_for() 1163 { 1164 mysql_prlock_wrlock(&m_LOCK_waiting_for); 1165 m_waiting_for= NULL; 1166 mysql_prlock_unlock(&m_LOCK_waiting_for); 1167 } lock_deadlock_victim()1168 void lock_deadlock_victim() 1169 { 1170 mysql_prlock_rdlock(&m_LOCK_waiting_for); 1171 } unlock_deadlock_victim()1172 void unlock_deadlock_victim() 1173 { 1174 mysql_prlock_unlock(&m_LOCK_waiting_for); 1175 } 1176 private: 1177 MDL_context(const MDL_context &rhs); /* not implemented */ 1178 MDL_context &operator=(MDL_context &rhs); /* not implemented */ 1179 }; 1180 1181 1182 void mdl_init(); 1183 void mdl_destroy(); 1184 1185 1186 #ifndef NDEBUG 1187 extern mysql_mutex_t LOCK_open; 1188 #endif 1189 1190 1191 /* 1192 Metadata locking subsystem tries not to grant more than 1193 max_write_lock_count high priority, strong locks successively, 1194 to avoid starving out weak, lower priority locks. 1195 */ 1196 extern "C" ulong max_write_lock_count; 1197 1198 extern int32 mdl_locks_unused_locks_low_water; 1199 1200 /** 1201 Default value for threshold for number of unused MDL_lock objects after 1202 exceeding which we start considering freeing them. Only unit tests use 1203 different threshold value. 1204 */ 1205 const int32 MDL_LOCKS_UNUSED_LOCKS_LOW_WATER_DEFAULT= 1000; 1206 1207 /** 1208 Ratio of unused/total MDL_lock objects after exceeding which we 1209 start trying to free unused MDL_lock objects (assuming that 1210 mdl_locks_unused_locks_low_water threshold is passed as well). 1211 Note that this value should be high enough for our algorithm 1212 using random dives into hash to work well. 1213 */ 1214 const double MDL_LOCKS_UNUSED_LOCKS_MIN_RATIO= 0.25; 1215 1216 int32 mdl_get_unused_locks_count(); 1217 1218 #endif 1219