1 #ifndef MDL_H 2 #define MDL_H 3 /* Copyright (c) 2009, 2016, 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 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 /* This should be the last ! */ 367 NAMESPACE_END }; 368 ptrMDL_key369 const uchar *ptr() const { return (uchar*) m_ptr; } lengthMDL_key370 uint length() const { return m_length; } 371 db_nameMDL_key372 const char *db_name() const { return m_ptr + 1; } db_name_lengthMDL_key373 uint db_name_length() const { return m_db_name_length; } 374 nameMDL_key375 const char *name() const { return m_ptr + m_db_name_length + 2; } name_lengthMDL_key376 uint name_length() const { return m_length - m_db_name_length - 3; } 377 mdl_namespaceMDL_key378 enum_mdl_namespace mdl_namespace() const 379 { return (enum_mdl_namespace)(m_ptr[0]); } 380 381 /** 382 Construct a metadata lock key from a triplet (mdl_namespace, 383 database and name). 384 385 @remark The key for a table is <mdl_namespace>+<database name>+<table name> 386 387 @param mdl_namespace Id of namespace of object to be locked 388 @param db Name of database to which the object belongs 389 @param name Name of of the object 390 */ mdl_key_initMDL_key391 void mdl_key_init(enum_mdl_namespace mdl_namespace, 392 const char *db, const char *name) 393 { 394 m_ptr[0]= (char) mdl_namespace; 395 /* 396 It is responsibility of caller to ensure that db and object names 397 are not longer than NAME_LEN. Still we play safe and try to avoid 398 buffer overruns. 399 */ 400 DBUG_ASSERT(strlen(db) <= NAME_LEN && strlen(name) <= NAME_LEN); 401 m_db_name_length= static_cast<uint16>(strmake(m_ptr + 1, db, NAME_LEN) - 402 m_ptr - 1); 403 m_length= static_cast<uint16>(strmake(m_ptr + m_db_name_length + 2, name, 404 NAME_LEN) - m_ptr + 1); 405 } mdl_key_initMDL_key406 void mdl_key_init(const MDL_key *rhs) 407 { 408 memcpy(m_ptr, rhs->m_ptr, rhs->m_length); 409 m_length= rhs->m_length; 410 m_db_name_length= rhs->m_db_name_length; 411 } resetMDL_key412 void reset() 413 { 414 m_ptr[0]= NAMESPACE_END; 415 m_db_name_length= 0; 416 m_length= 0; 417 } is_equalMDL_key418 bool is_equal(const MDL_key *rhs) const 419 { 420 return (m_length == rhs->m_length && 421 memcmp(m_ptr, rhs->m_ptr, m_length) == 0); 422 } 423 /** 424 Compare two MDL keys lexicographically. 425 */ cmpMDL_key426 int cmp(const MDL_key *rhs) const 427 { 428 /* 429 The key buffer is always '\0'-terminated. Since key 430 character set is utf-8, we can safely assume that no 431 character starts with a zero byte. 432 */ 433 return memcmp(m_ptr, rhs->m_ptr, std::min(m_length, rhs->m_length)); 434 } 435 MDL_keyMDL_key436 MDL_key(const MDL_key *rhs) 437 { 438 mdl_key_init(rhs); 439 } MDL_keyMDL_key440 MDL_key(enum_mdl_namespace namespace_arg, 441 const char *db_arg, const char *name_arg) 442 { 443 mdl_key_init(namespace_arg, db_arg, name_arg); 444 } MDL_keyMDL_key445 MDL_key() {} /* To use when part of MDL_request. */ 446 447 /** 448 Get thread state name to be used in case when we have to 449 wait on resource identified by key. 450 */ get_wait_state_nameMDL_key451 const PSI_stage_info * get_wait_state_name() const 452 { 453 return & m_namespace_to_wait_state_name[(int)mdl_namespace()]; 454 } 455 456 private: 457 uint16 m_length; 458 uint16 m_db_name_length; 459 char m_ptr[MAX_MDLKEY_LENGTH]; 460 static PSI_stage_info m_namespace_to_wait_state_name[NAMESPACE_END]; 461 private: 462 MDL_key(const MDL_key &); /* not implemented */ 463 MDL_key &operator=(const MDL_key &); /* not implemented */ 464 }; 465 466 467 /** 468 A pending metadata lock request. 469 470 A lock request and a granted metadata lock are represented by 471 different classes because they have different allocation 472 sites and hence different lifetimes. The allocation of lock requests is 473 controlled from outside of the MDL subsystem, while allocation of granted 474 locks (tickets) is controlled within the MDL subsystem. 475 476 MDL_request is a C structure, you don't need to call a constructor 477 or destructor for it. 478 */ 479 480 class MDL_request 481 { 482 public: 483 /** Type of metadata lock. */ 484 enum enum_mdl_type type; 485 /** Duration for requested lock. */ 486 enum enum_mdl_duration duration; 487 488 /** 489 Pointers for participating in the list of lock requests for this context. 490 */ 491 MDL_request *next_in_list; 492 MDL_request **prev_in_list; 493 /** 494 Pointer to the lock ticket object for this lock request. 495 Valid only if this lock request is satisfied. 496 */ 497 MDL_ticket *ticket; 498 499 /** A lock is requested based on a fully qualified name and type. */ 500 MDL_key key; 501 502 const char *m_src_file; 503 uint m_src_line; 504 505 public: new(size_t size,MEM_ROOT * mem_root)506 static void *operator new(size_t size, MEM_ROOT *mem_root) throw () 507 { return alloc_root(mem_root, size); } delete(void * ptr,MEM_ROOT * mem_root)508 static void operator delete(void *ptr, MEM_ROOT *mem_root) {} 509 510 void init_with_source(MDL_key::enum_mdl_namespace namespace_arg, 511 const char *db_arg, const char *name_arg, 512 enum_mdl_type mdl_type_arg, 513 enum_mdl_duration mdl_duration_arg, 514 const char *src_file, uint src_line); 515 void init_by_key_with_source(const MDL_key *key_arg, enum_mdl_type mdl_type_arg, 516 enum_mdl_duration mdl_duration_arg, 517 const char *src_file, uint src_line); 518 /** Set type of lock request. Can be only applied to pending locks. */ set_type(enum_mdl_type type_arg)519 inline void set_type(enum_mdl_type type_arg) 520 { 521 DBUG_ASSERT(ticket == NULL); 522 type= type_arg; 523 } 524 525 /** 526 Is this a request for a lock which allow data to be updated? 527 528 @note This method returns true for MDL_SHARED_UPGRADABLE type of 529 lock. Even though this type of lock doesn't allow updates 530 it will always be upgraded to one that does. 531 */ is_write_lock_request()532 bool is_write_lock_request() const 533 { 534 return (type >= MDL_SHARED_WRITE && 535 type != MDL_SHARED_READ_ONLY); 536 } 537 538 /** Is this a request for a strong, DDL/LOCK TABLES-type, of lock? */ is_ddl_or_lock_tables_lock_request()539 bool is_ddl_or_lock_tables_lock_request() const 540 { 541 return type >= MDL_SHARED_UPGRADABLE; 542 } 543 544 /* 545 This is to work around the ugliness of TABLE_LIST 546 compiler-generated assignment operator. It is currently used 547 in several places to quickly copy "most" of the members of the 548 table list. These places currently never assume that the mdl 549 request is carried over to the new TABLE_LIST, or shared 550 between lists. 551 552 This method does not initialize the instance being assigned! 553 Use of init() for initialization after this assignment operator 554 is mandatory. Can only be used before the request has been 555 granted. 556 */ 557 MDL_request& operator=(const MDL_request &rhs) 558 { 559 ticket= NULL; 560 /* Do nothing, in particular, don't try to copy the key. */ 561 return *this; 562 } 563 /* Another piece of ugliness for TABLE_LIST constructor */ MDL_request()564 MDL_request() {} 565 MDL_request(const MDL_request * rhs)566 MDL_request(const MDL_request *rhs) 567 :type(rhs->type), 568 duration(rhs->duration), 569 ticket(NULL), 570 key(&rhs->key) 571 {} 572 }; 573 574 #define MDL_REQUEST_INIT(R, P1, P2, P3, P4, P5) \ 575 (*R).init_with_source(P1, P2, P3, P4, P5, __FILE__, __LINE__) 576 577 #define MDL_REQUEST_INIT_BY_KEY(R, P1, P2, P3) \ 578 (*R).init_by_key_with_source(P1, P2, P3, __FILE__, __LINE__) 579 580 581 /** 582 An abstract class for inspection of a connected 583 subgraph of the wait-for graph. 584 */ 585 586 class MDL_wait_for_graph_visitor 587 { 588 public: 589 virtual bool enter_node(MDL_context *node) = 0; 590 virtual void leave_node(MDL_context *node) = 0; 591 592 virtual bool inspect_edge(MDL_context *dest) = 0; 593 virtual ~MDL_wait_for_graph_visitor(); MDL_wait_for_graph_visitor()594 MDL_wait_for_graph_visitor() :m_lock_open_count(0) {} 595 public: 596 /** 597 XXX, hack: During deadlock search, we may need to 598 inspect TABLE_SHAREs and acquire LOCK_open. Since 599 LOCK_open is not a recursive mutex, count here how many 600 times we "took" it (but only take and release once). 601 Not using a native recursive mutex or rwlock in 5.5 for 602 LOCK_open since it has significant performance impacts. 603 */ 604 uint m_lock_open_count; 605 }; 606 607 /** 608 Abstract class representing an edge in the waiters graph 609 to be traversed by deadlock detection algorithm. 610 */ 611 612 class MDL_wait_for_subgraph 613 { 614 public: 615 virtual ~MDL_wait_for_subgraph(); 616 617 /** 618 Accept a wait-for graph visitor to inspect the node 619 this edge is leading to. 620 */ 621 virtual bool accept_visitor(MDL_wait_for_graph_visitor *gvisitor) = 0; 622 623 static const uint DEADLOCK_WEIGHT_DML= 0; 624 static const uint DEADLOCK_WEIGHT_ULL= 50; 625 static const uint DEADLOCK_WEIGHT_DDL= 100; 626 627 /* A helper used to determine which lock request should be aborted. */ 628 virtual uint get_deadlock_weight() const = 0; 629 }; 630 631 632 /** 633 A granted metadata lock. 634 635 @warning MDL_ticket members are private to the MDL subsystem. 636 637 @note Multiple shared locks on a same object are represented by a 638 single ticket. The same does not apply for other lock types. 639 640 @note There are two groups of MDL_ticket members: 641 - "Externally accessible". These members can be accessed from 642 threads/contexts different than ticket owner in cases when 643 ticket participates in some list of granted or waiting tickets 644 for a lock. Therefore one should change these members before 645 including then to waiting/granted lists or while holding lock 646 protecting those lists. 647 - "Context private". Such members are private to thread/context 648 owning this ticket. I.e. they should not be accessed from other 649 threads/contexts. 650 */ 651 652 class MDL_ticket : public MDL_wait_for_subgraph 653 { 654 public: 655 /** 656 Pointers for participating in the list of lock requests for this context. 657 Context private. 658 */ 659 MDL_ticket *next_in_context; 660 MDL_ticket **prev_in_context; 661 /** 662 Pointers for participating in the list of satisfied/pending requests 663 for the lock. Externally accessible. 664 */ 665 MDL_ticket *next_in_lock; 666 MDL_ticket **prev_in_lock; 667 public: 668 bool has_pending_conflicting_lock() const; 669 get_ctx()670 MDL_context *get_ctx() const { return m_ctx; } is_upgradable_or_exclusive()671 bool is_upgradable_or_exclusive() const 672 { 673 return m_type == MDL_SHARED_UPGRADABLE || 674 m_type == MDL_SHARED_NO_WRITE || 675 m_type == MDL_SHARED_NO_READ_WRITE || 676 m_type == MDL_EXCLUSIVE; 677 } get_type()678 enum_mdl_type get_type() const { return m_type; } get_lock()679 MDL_lock *get_lock() const { return m_lock; } 680 const MDL_key *get_key() const; 681 void downgrade_lock(enum_mdl_type type); 682 683 bool has_stronger_or_equal_type(enum_mdl_type type) const; 684 685 bool is_incompatible_when_granted(enum_mdl_type type) const; 686 bool is_incompatible_when_waiting(enum_mdl_type type) const; 687 688 /** Implement MDL_wait_for_subgraph interface. */ 689 virtual bool accept_visitor(MDL_wait_for_graph_visitor *dvisitor); 690 virtual uint get_deadlock_weight() const; 691 692 public: 693 /** 694 Status of lock request represented by the ticket as reflected in P_S. 695 */ 696 enum enum_psi_status { PENDING = 0, GRANTED, 697 PRE_ACQUIRE_NOTIFY, POST_RELEASE_NOTIFY }; 698 699 private: 700 friend class MDL_context; 701 MDL_ticket(MDL_context * ctx_arg,enum_mdl_type type_arg,enum_mdl_duration duration_arg)702 MDL_ticket(MDL_context *ctx_arg, enum_mdl_type type_arg 703 #ifndef DBUG_OFF 704 , enum_mdl_duration duration_arg 705 #endif 706 ) 707 : m_type(type_arg), 708 #ifndef DBUG_OFF 709 m_duration(duration_arg), 710 #endif 711 m_ctx(ctx_arg), 712 m_lock(NULL), 713 m_is_fast_path(false), 714 m_hton_notified(false), 715 m_psi(NULL) 716 {} 717 ~MDL_ticket()718 virtual ~MDL_ticket() 719 { 720 DBUG_ASSERT(m_psi == NULL); 721 } 722 723 static MDL_ticket *create(MDL_context *ctx_arg, enum_mdl_type type_arg 724 #ifndef DBUG_OFF 725 , enum_mdl_duration duration_arg 726 #endif 727 ); 728 static void destroy(MDL_ticket *ticket); 729 private: 730 /** Type of metadata lock. Externally accessible. */ 731 enum enum_mdl_type m_type; 732 #ifndef DBUG_OFF 733 /** 734 Duration of lock represented by this ticket. 735 Context private. Debug-only. 736 */ 737 enum_mdl_duration m_duration; 738 #endif 739 /** 740 Context of the owner of the metadata lock ticket. Externally accessible. 741 */ 742 MDL_context *m_ctx; 743 744 /** 745 Pointer to the lock object for this lock ticket. Externally accessible. 746 */ 747 MDL_lock *m_lock; 748 749 /** 750 Indicates that ticket corresponds to lock acquired using "fast path" 751 algorithm. Particularly this means that it was not included into 752 MDL_lock::m_granted bitmap/list and instead is accounted for by 753 MDL_lock::m_fast_path_locks_granted_counter 754 */ 755 bool m_is_fast_path; 756 757 /** 758 Indicates that ticket corresponds to lock request which required 759 storage engine notification during its acquisition and requires 760 storage engine notification after its release. 761 */ 762 bool m_hton_notified; 763 764 PSI_metadata_lock *m_psi; 765 766 private: 767 MDL_ticket(const MDL_ticket &); /* not implemented */ 768 MDL_ticket &operator=(const MDL_ticket &); /* not implemented */ 769 }; 770 771 772 /** 773 Savepoint for MDL context. 774 775 Doesn't include metadata locks with explicit duration as 776 they are not released during rollback to savepoint. 777 */ 778 779 class MDL_savepoint 780 { 781 public: MDL_savepoint()782 MDL_savepoint() {}; 783 784 private: MDL_savepoint(MDL_ticket * stmt_ticket,MDL_ticket * trans_ticket)785 MDL_savepoint(MDL_ticket *stmt_ticket, MDL_ticket *trans_ticket) 786 : m_stmt_ticket(stmt_ticket), m_trans_ticket(trans_ticket) 787 {} 788 789 friend class MDL_context; 790 791 private: 792 /** 793 Pointer to last lock with statement duration which was taken 794 before creation of savepoint. 795 */ 796 MDL_ticket *m_stmt_ticket; 797 /** 798 Pointer to last lock with transaction duration which was taken 799 before creation of savepoint. 800 */ 801 MDL_ticket *m_trans_ticket; 802 }; 803 804 805 /** 806 A reliable way to wait on an MDL lock. 807 */ 808 809 class MDL_wait 810 { 811 public: 812 MDL_wait(); 813 ~MDL_wait(); 814 815 enum enum_wait_status { EMPTY = 0, GRANTED, VICTIM, TIMEOUT, KILLED }; 816 817 bool set_status(enum_wait_status result_arg); 818 enum_wait_status get_status(); 819 void reset_status(); 820 enum_wait_status timed_wait(MDL_context_owner *owner, 821 struct timespec *abs_timeout, 822 bool signal_timeout, 823 const PSI_stage_info *wait_state_name); 824 private: 825 826 /** 827 Condvar which is used for waiting until this context's pending 828 request can be satisfied or this thread has to perform actions 829 to resolve a potential deadlock (we subscribe to such 830 notification by adding a ticket corresponding to the request 831 to an appropriate queue of waiters). 832 */ 833 mysql_mutex_t m_LOCK_wait_status; 834 mysql_cond_t m_COND_wait_status; 835 enum_wait_status m_wait_status; 836 }; 837 838 839 /** 840 Base class to find out if the lock represented by a given ticket 841 should be released. Users of release_locks() need to subclass 842 this and specify an implementation of release(). Only for locks 843 with explicit duration. 844 */ 845 846 class MDL_release_locks_visitor 847 { 848 public: ~MDL_release_locks_visitor()849 virtual ~MDL_release_locks_visitor() {} 850 /** 851 Check if the given ticket represents a lock that should be released. 852 853 @retval true if the lock should be released, false otherwise. 854 */ 855 virtual bool release(MDL_ticket *ticket) = 0; 856 }; 857 858 859 /** 860 Abstract visitor class for inspecting MDL_context. 861 */ 862 863 class MDL_context_visitor 864 { 865 public: ~MDL_context_visitor()866 virtual ~MDL_context_visitor() {} 867 virtual void visit_context(const MDL_context *ctx) = 0; 868 }; 869 870 871 typedef I_P_List<MDL_request, I_P_List_adapter<MDL_request, 872 &MDL_request::next_in_list, 873 &MDL_request::prev_in_list>, 874 I_P_List_counter> 875 MDL_request_list; 876 877 /** 878 Context of the owner of metadata locks. I.e. each server 879 connection has such a context. 880 */ 881 882 class MDL_context 883 { 884 public: 885 typedef I_P_List<MDL_ticket, 886 I_P_List_adapter<MDL_ticket, 887 &MDL_ticket::next_in_context, 888 &MDL_ticket::prev_in_context> > 889 Ticket_list; 890 891 typedef Ticket_list::Iterator Ticket_iterator; 892 893 MDL_context(); 894 void destroy(); 895 896 bool try_acquire_lock(MDL_request *mdl_request); 897 bool acquire_lock(MDL_request *mdl_request, ulong lock_wait_timeout); 898 bool acquire_locks(MDL_request_list *requests, ulong lock_wait_timeout); 899 bool upgrade_shared_lock(MDL_ticket *mdl_ticket, 900 enum_mdl_type new_type, 901 ulong lock_wait_timeout); 902 903 bool clone_ticket(MDL_request *mdl_request); 904 905 void release_all_locks_for_name(MDL_ticket *ticket); 906 void release_locks(MDL_release_locks_visitor *visitor); 907 void release_lock(MDL_ticket *ticket); 908 909 bool owns_equal_or_stronger_lock(MDL_key::enum_mdl_namespace mdl_namespace, 910 const char *db, const char *name, 911 enum_mdl_type mdl_type); 912 913 bool find_lock_owner(const MDL_key *mdl_key, MDL_context_visitor *visitor); 914 915 bool has_lock(const MDL_savepoint &mdl_savepoint, MDL_ticket *mdl_ticket); 916 has_locks()917 inline bool has_locks() const 918 { 919 return !(m_tickets[MDL_STATEMENT].is_empty() && 920 m_tickets[MDL_TRANSACTION].is_empty() && 921 m_tickets[MDL_EXPLICIT].is_empty()); 922 } 923 924 bool has_locks(MDL_key::enum_mdl_namespace mdl_namespace) const; 925 926 bool has_locks_waited_for() const; 927 mdl_savepoint()928 MDL_savepoint mdl_savepoint() 929 { 930 return MDL_savepoint(m_tickets[MDL_STATEMENT].front(), 931 m_tickets[MDL_TRANSACTION].front()); 932 } 933 934 void set_explicit_duration_for_all_locks(); 935 void set_transaction_duration_for_all_locks(); 936 void set_lock_duration(MDL_ticket *mdl_ticket, enum_mdl_duration duration); 937 938 void release_statement_locks(); 939 void release_transactional_locks(); 940 void rollback_to_savepoint(const MDL_savepoint &mdl_savepoint); 941 get_owner()942 MDL_context_owner *get_owner() const { return m_owner; } 943 944 /** @pre Only valid if we started waiting for lock. */ get_deadlock_weight()945 inline uint get_deadlock_weight() const 946 { 947 return m_force_dml_deadlock_weight ? 948 MDL_wait_for_subgraph::DEADLOCK_WEIGHT_DML : 949 m_waiting_for->get_deadlock_weight(); 950 } 951 init(MDL_context_owner * arg)952 void init(MDL_context_owner *arg) { m_owner= arg; } 953 set_needs_thr_lock_abort(bool needs_thr_lock_abort)954 void set_needs_thr_lock_abort(bool needs_thr_lock_abort) 955 { 956 /* 957 @note In theory, this member should be modified under protection 958 of some lock since it can be accessed from different threads. 959 In practice, this is not necessary as code which reads this 960 value and so might miss the fact that value was changed will 961 always re-try reading it after small timeout and therefore 962 will see the new value eventually. 963 */ 964 m_needs_thr_lock_abort= needs_thr_lock_abort; 965 966 if (m_needs_thr_lock_abort) 967 { 968 /* 969 For MDL_object_lock::notify_conflicting_locks() to work properly 970 all context requiring thr_lock aborts should not have any "fast 971 path" locks. 972 */ 973 materialize_fast_path_locks(); 974 } 975 } get_needs_thr_lock_abort()976 bool get_needs_thr_lock_abort() const 977 { 978 return m_needs_thr_lock_abort; 979 } 980 set_force_dml_deadlock_weight(bool force_dml_deadlock_weight)981 void set_force_dml_deadlock_weight(bool force_dml_deadlock_weight) 982 { 983 m_force_dml_deadlock_weight= force_dml_deadlock_weight; 984 } 985 986 /** 987 Get pseudo random value in [0 .. 2^31-1] range. 988 989 @note We use Linear Congruential Generator with venerable constant 990 parameters for this. 991 It is known to have problems with its lower bits are not being 992 very random so probably is not good enough for generic use. 993 However, we only use it to do random dives into MDL_lock objects 994 hash when searching for unused objects to be freed, and for this 995 purposes it is sufficient. 996 We rely on values of "get_random() % 2^k" expression having "2^k" 997 as a period to ensure that random dives eventually cover all hash 998 (the former can be proven to be true). This also means that there 999 is no bias towards any specific objects to be expelled (as hash 1000 values don't repeat), which is nice for performance. 1001 */ get_random()1002 uint get_random() 1003 { 1004 if (m_rand_state > INT_MAX32) 1005 { 1006 /* 1007 Perform lazy initialization of LCG. We can't initialize it at the 1008 point when MDL_context is created since THD represented through 1009 MDL_context_owner interface is not fully initialized at this point 1010 itself. 1011 */ 1012 m_rand_state= m_owner->get_rand_seed() & INT_MAX32; 1013 } 1014 m_rand_state= (m_rand_state * 1103515245 + 12345) & INT_MAX32; 1015 return m_rand_state; 1016 } 1017 1018 /** 1019 Within MDL subsystem this one is only used for DEBUG_SYNC. 1020 Do not use it to peek/poke into other parts of THD from MDL. 1021 @sa MDL_context_owner::get_thd(). 1022 */ get_thd()1023 THD *get_thd() const { return m_owner->get_thd(); } 1024 1025 public: 1026 /** 1027 If our request for a lock is scheduled, or aborted by the deadlock 1028 detector, the result is recorded in this class. 1029 */ 1030 MDL_wait m_wait; 1031 private: 1032 /** 1033 Lists of all MDL tickets acquired by this connection. 1034 1035 Lists of MDL tickets: 1036 --------------------- 1037 The entire set of locks acquired by a connection can be separated 1038 in three subsets according to their duration: locks released at 1039 the end of statement, at the end of transaction and locks are 1040 released explicitly. 1041 1042 Statement and transactional locks are locks with automatic scope. 1043 They are accumulated in the course of a transaction, and released 1044 either at the end of uppermost statement (for statement locks) or 1045 on COMMIT, ROLLBACK or ROLLBACK TO SAVEPOINT (for transactional 1046 locks). They must not be (and never are) released manually, 1047 i.e. with release_lock() call. 1048 1049 Tickets with explicit duration are taken for locks that span 1050 multiple transactions or savepoints. 1051 These are: HANDLER SQL locks (HANDLER SQL is 1052 transaction-agnostic), LOCK TABLES locks (you can COMMIT/etc 1053 under LOCK TABLES, and the locked tables stay locked), user level 1054 locks (GET_LOCK()/RELEASE_LOCK() functions) and 1055 locks implementing "global read lock". 1056 1057 Statement/transactional locks are always prepended to the 1058 beginning of the appropriate list. In other words, they are 1059 stored in reverse temporal order. Thus, when we rollback to 1060 a savepoint, we start popping and releasing tickets from the 1061 front until we reach the last ticket acquired after the savepoint. 1062 1063 Locks with explicit duration are not stored in any 1064 particular order, and among each other can be split into 1065 four sets: 1066 - LOCK TABLES locks 1067 - User-level locks 1068 - HANDLER locks 1069 - GLOBAL READ LOCK locks 1070 */ 1071 Ticket_list m_tickets[MDL_DURATION_END]; 1072 MDL_context_owner *m_owner; 1073 /** 1074 TRUE - if for this context we will break protocol and try to 1075 acquire table-level locks while having only S lock on 1076 some table. 1077 To avoid deadlocks which might occur during concurrent 1078 upgrade of SNRW lock on such object to X lock we have to 1079 abort waits for table-level locks for such connections. 1080 FALSE - Otherwise. 1081 */ 1082 bool m_needs_thr_lock_abort; 1083 1084 /** 1085 Indicates that we need to use DEADLOCK_WEIGHT_DML deadlock 1086 weight for this context and ignore the deadlock weight provided 1087 by the MDL_wait_for_subgraph object which we are waiting for. 1088 1089 @note Can be changed only when there is a guarantee that this 1090 MDL_context is not waiting for a metadata lock or table 1091 definition entry. 1092 */ 1093 bool m_force_dml_deadlock_weight; 1094 1095 /** 1096 Read-write lock protecting m_waiting_for member. 1097 1098 @note The fact that this read-write lock prefers readers is 1099 important as deadlock detector won't work correctly 1100 otherwise. @sa Comment for MDL_lock::m_rwlock. 1101 */ 1102 mysql_prlock_t m_LOCK_waiting_for; 1103 /** 1104 Tell the deadlock detector what metadata lock or table 1105 definition cache entry this session is waiting for. 1106 In principle, this is redundant, as information can be found 1107 by inspecting waiting queues, but we'd very much like it to be 1108 readily available to the wait-for graph iterator. 1109 */ 1110 MDL_wait_for_subgraph *m_waiting_for; 1111 /** 1112 Thread's pins (a.k.a. hazard pointers) to be used by lock-free 1113 implementation of MDL_map::m_locks container. NULL if pins are 1114 not yet allocated from container's pinbox. 1115 */ 1116 LF_PINS *m_pins; 1117 /** 1118 State for pseudo random numbers generator (PRNG) which output 1119 is used to perform random dives into MDL_lock objects hash 1120 when searching for unused objects to free. 1121 */ 1122 uint m_rand_state; 1123 1124 private: 1125 MDL_ticket *find_ticket(MDL_request *mdl_req, 1126 enum_mdl_duration *duration); 1127 void release_locks_stored_before(enum_mdl_duration duration, MDL_ticket *sentinel); 1128 void release_lock(enum_mdl_duration duration, MDL_ticket *ticket); 1129 bool try_acquire_lock_impl(MDL_request *mdl_request, 1130 MDL_ticket **out_ticket); 1131 void materialize_fast_path_locks(); 1132 inline bool fix_pins(); 1133 1134 public: 1135 void find_deadlock(); 1136 1137 bool visit_subgraph(MDL_wait_for_graph_visitor *dvisitor); 1138 1139 /** Inform the deadlock detector there is an edge in the wait-for graph. */ will_wait_for(MDL_wait_for_subgraph * waiting_for_arg)1140 void will_wait_for(MDL_wait_for_subgraph *waiting_for_arg) 1141 { 1142 /* 1143 Before starting wait for any resource we need to materialize 1144 all "fast path" tickets belonging to this thread. Otherwise 1145 locks acquired which are represented by these tickets won't 1146 be present in wait-for graph and could cause missed deadlocks. 1147 1148 It is OK for context which doesn't wait for any resource to 1149 have "fast path" tickets, as such context can't participate 1150 in any deadlock. 1151 */ 1152 materialize_fast_path_locks(); 1153 1154 mysql_prlock_wrlock(&m_LOCK_waiting_for); 1155 m_waiting_for= waiting_for_arg; 1156 mysql_prlock_unlock(&m_LOCK_waiting_for); 1157 } 1158 1159 /** Remove the wait-for edge from the graph after we're done waiting. */ done_waiting_for()1160 void done_waiting_for() 1161 { 1162 mysql_prlock_wrlock(&m_LOCK_waiting_for); 1163 m_waiting_for= NULL; 1164 mysql_prlock_unlock(&m_LOCK_waiting_for); 1165 } lock_deadlock_victim()1166 void lock_deadlock_victim() 1167 { 1168 mysql_prlock_rdlock(&m_LOCK_waiting_for); 1169 } unlock_deadlock_victim()1170 void unlock_deadlock_victim() 1171 { 1172 mysql_prlock_unlock(&m_LOCK_waiting_for); 1173 } 1174 private: 1175 MDL_context(const MDL_context &rhs); /* not implemented */ 1176 MDL_context &operator=(MDL_context &rhs); /* not implemented */ 1177 }; 1178 1179 1180 void mdl_init(); 1181 void mdl_destroy(); 1182 1183 1184 #ifndef DBUG_OFF 1185 extern mysql_mutex_t LOCK_open; 1186 #endif 1187 1188 1189 /* 1190 Metadata locking subsystem tries not to grant more than 1191 max_write_lock_count high priority, strong locks successively, 1192 to avoid starving out weak, lower priority locks. 1193 */ 1194 extern "C" ulong max_write_lock_count; 1195 1196 extern int32 mdl_locks_unused_locks_low_water; 1197 1198 /** 1199 Default value for threshold for number of unused MDL_lock objects after 1200 exceeding which we start considering freeing them. Only unit tests use 1201 different threshold value. 1202 */ 1203 const int32 MDL_LOCKS_UNUSED_LOCKS_LOW_WATER_DEFAULT= 1000; 1204 1205 /** 1206 Ratio of unused/total MDL_lock objects after exceeding which we 1207 start trying to free unused MDL_lock objects (assuming that 1208 mdl_locks_unused_locks_low_water threshold is passed as well). 1209 Note that this value should be high enough for our algorithm 1210 using random dives into hash to work well. 1211 */ 1212 const double MDL_LOCKS_UNUSED_LOCKS_MIN_RATIO= 0.25; 1213 1214 int32 mdl_get_unused_locks_count(); 1215 1216 #endif 1217