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