1 #ifndef MDL_H 2 #define MDL_H 3 /* Copyright (c) 2009, 2020, 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 23 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ 24 25 #include <string.h> 26 #include <sys/types.h> 27 #include <algorithm> 28 #include <new> 29 #include <unordered_map> 30 31 #include "m_string.h" 32 #include "my_alloc.h" 33 #include "my_compiler.h" 34 #include "my_dbug.h" 35 #include "my_inttypes.h" 36 #include "my_psi_config.h" 37 #include "my_sys.h" 38 #include "my_systime.h" // Timout_type 39 #include "mysql/components/services/mysql_cond_bits.h" 40 #include "mysql/components/services/mysql_mutex_bits.h" 41 #include "mysql/components/services/mysql_rwlock_bits.h" 42 #include "mysql/components/services/psi_mdl_bits.h" 43 #include "mysql/components/services/psi_stage_bits.h" 44 #include "mysql/psi/mysql_rwlock.h" 45 #include "mysql_com.h" 46 #include "sql/sql_plist.h" 47 #include "template_utils.h" 48 49 class MDL_context; 50 class MDL_lock; 51 class MDL_ticket; 52 class THD; 53 struct LF_PINS; 54 struct MDL_key; 55 struct MEM_ROOT; 56 namespace mdl_unittest { 57 bool test_drive_fix_pins(MDL_context *); 58 } 59 /** 60 @def ENTER_COND(C, M, S, O) 61 Start a wait on a condition. 62 @param C the condition to wait on 63 @param M the associated mutex 64 @param S the new stage to enter 65 @param O the previous stage 66 @sa EXIT_COND(). 67 */ 68 #define ENTER_COND(C, M, S, O) \ 69 enter_cond(C, M, S, O, __func__, __FILE__, __LINE__) 70 71 /** 72 @def EXIT_COND(S) 73 End a wait on a condition 74 @param S the new stage to enter 75 */ 76 #define EXIT_COND(S) exit_cond(S, __func__, __FILE__, __LINE__) 77 78 /** 79 An interface to separate the MDL module from the THD, and the rest of the 80 server code. 81 */ 82 83 class MDL_context_owner { 84 public: ~MDL_context_owner()85 virtual ~MDL_context_owner() {} 86 87 /** 88 Enter a condition wait. 89 For @c enter_cond() / @c exit_cond() to work the mutex must be held before 90 @c enter_cond(); this mutex must then be released before @c exit_cond(). 91 Usage must be: lock mutex; enter_cond(); your code; unlock mutex; 92 exit_cond(). 93 @param cond the condition to wait on 94 @param mutex the associated mutex 95 @param [in] stage the stage to enter, or NULL 96 @param [out] old_stage the previous stage, or NULL 97 @param src_function function name of the caller 98 @param src_file file name of the caller 99 @param src_line line number of the caller 100 @sa ENTER_COND(), THD::enter_cond() 101 @sa EXIT_COND(), THD::exit_cond() 102 */ 103 virtual void enter_cond(mysql_cond_t *cond, mysql_mutex_t *mutex, 104 const PSI_stage_info *stage, 105 PSI_stage_info *old_stage, const char *src_function, 106 const char *src_file, int src_line) = 0; 107 108 /** 109 End a wait on a condition 110 @param [in] stage the new stage to enter 111 @param src_function function name of the caller 112 @param src_file file name of the caller 113 @param src_line line number of the caller 114 @sa ENTER_COND(), THD::enter_cond() 115 @sa EXIT_COND(), THD::exit_cond() 116 */ 117 virtual void exit_cond(const PSI_stage_info *stage, const char *src_function, 118 const char *src_file, int src_line) = 0; 119 /** 120 Has the owner thread been killed? 121 */ 122 virtual int is_killed() const = 0; 123 124 /** 125 Does the owner still have connection to the client? 126 */ 127 virtual bool is_connected() = 0; 128 129 /** 130 Within MDL subsystem this one is only used for DEBUG_SYNC. 131 Do not use it to peek/poke into other parts of THD from MDL. 132 However it is OK to use this method in callbacks provided 133 by SQL-layer to MDL subsystem (since SQL-layer has full 134 access to THD anyway). 135 136 @warning For some derived classes implementation of this method 137 can return nullptr. Calling side must be ready to handle 138 this case. 139 */ 140 virtual THD *get_thd() = 0; 141 142 /** 143 @see THD::notify_shared_lock() 144 */ 145 virtual void notify_shared_lock(MDL_context_owner *in_use, 146 bool needs_thr_lock_abort) = 0; 147 148 /** 149 Notify/get permission from interested storage engines before acquiring 150 exclusive lock for the key. 151 152 The returned argument 'victimized' specify reason for lock 153 not granted. If 'true', lock was refused in an attempt to 154 resolve a possible MDL->GSL deadlock. Locking may then be retried. 155 156 @return False if notification was successful and it is OK to acquire lock, 157 True if one of SEs asks to abort lock acquisition. 158 */ 159 virtual bool notify_hton_pre_acquire_exclusive(const MDL_key *mdl_key, 160 bool *victimized) = 0; 161 /** 162 Notify interested storage engines that we have just released exclusive 163 lock for the key. 164 */ 165 virtual void notify_hton_post_release_exclusive(const MDL_key *mdl_key) = 0; 166 167 /** 168 Get random seed specific to this THD to be used for initialization 169 of PRNG for the MDL_context. 170 */ 171 virtual uint get_rand_seed() const = 0; 172 }; 173 174 /** 175 Type of metadata lock request. 176 177 @sa Comments for MDL_object_lock::can_grant_lock() and 178 MDL_scoped_lock::can_grant_lock() for details. 179 */ 180 181 enum enum_mdl_type { 182 /* 183 An intention exclusive metadata lock. Used only for scoped locks. 184 Owner of this type of lock can acquire upgradable exclusive locks on 185 individual objects. 186 This lock type is also used when doing lookups in the dictionary 187 cache. When acquiring objects in a schema, we lock the schema with IX 188 to prevent the schema from being deleted. This should conceptually 189 be an IS lock, but it would have the same behavior as the current IX. 190 Compatible with other IX locks, but is incompatible with scoped S and 191 X locks. 192 */ 193 MDL_INTENTION_EXCLUSIVE = 0, 194 /* 195 A shared metadata lock. 196 To be used in cases when we are interested in object metadata only 197 and there is no intention to access object data (e.g. for stored 198 routines or during preparing prepared statements). 199 We also mis-use this type of lock for open HANDLERs, since lock 200 acquired by this statement has to be compatible with lock acquired 201 by LOCK TABLES ... WRITE statement, i.e. SNRW (We can't get by by 202 acquiring S lock at HANDLER ... OPEN time and upgrading it to SR 203 lock for HANDLER ... READ as it doesn't solve problem with need 204 to abort DML statements which wait on table level lock while having 205 open HANDLER in the same connection). 206 To avoid deadlock which may occur when SNRW lock is being upgraded to 207 X lock for table on which there is an active S lock which is owned by 208 thread which waits in its turn for table-level lock owned by thread 209 performing upgrade we have to use thr_abort_locks_for_thread() 210 facility in such situation. 211 This problem does not arise for locks on stored routines as we don't 212 use SNRW locks for them. It also does not arise when S locks are used 213 during PREPARE calls as table-level locks are not acquired in this 214 case. 215 */ 216 MDL_SHARED, 217 /* 218 A high priority shared metadata lock. 219 Used for cases when there is no intention to access object data (i.e. 220 data in the table). 221 "High priority" means that, unlike other shared locks, it is granted 222 ignoring pending requests for exclusive locks. Intended for use in 223 cases when we only need to access metadata and not data, e.g. when 224 filling an INFORMATION_SCHEMA table. 225 Since SH lock is compatible with SNRW lock, the connection that 226 holds SH lock lock should not try to acquire any kind of table-level 227 or row-level lock, as this can lead to a deadlock. Moreover, after 228 acquiring SH lock, the connection should not wait for any other 229 resource, as it might cause starvation for X locks and a potential 230 deadlock during upgrade of SNW or SNRW to X lock (e.g. if the 231 upgrading connection holds the resource that is being waited for). 232 */ 233 MDL_SHARED_HIGH_PRIO, 234 /* 235 A shared metadata lock for cases when there is an intention to read data 236 from table. 237 A connection holding this kind of lock can read table metadata and read 238 table data (after acquiring appropriate table and row-level locks). 239 This means that one can only acquire TL_READ, TL_READ_NO_INSERT, and 240 similar table-level locks on table if one holds SR MDL lock on it. 241 To be used for tables in SELECTs, subqueries, and LOCK TABLE ... READ 242 statements. 243 */ 244 MDL_SHARED_READ, 245 /* 246 A shared metadata lock for cases when there is an intention to modify 247 (and not just read) data in the table. 248 A connection holding SW lock can read table metadata and modify or read 249 table data (after acquiring appropriate table and row-level locks). 250 To be used for tables to be modified by INSERT, UPDATE, DELETE 251 statements, but not LOCK TABLE ... WRITE or DDL). Also taken by 252 SELECT ... FOR UPDATE. 253 */ 254 MDL_SHARED_WRITE, 255 /* 256 A version of MDL_SHARED_WRITE lock which has lower priority than 257 MDL_SHARED_READ_ONLY locks. Used by DML statements modifying 258 tables and using the LOW_PRIORITY clause. 259 */ 260 MDL_SHARED_WRITE_LOW_PRIO, 261 /* 262 An upgradable shared metadata lock which allows concurrent updates and 263 reads of table data. 264 A connection holding this kind of lock can read table metadata and read 265 table data. It should not modify data as this lock is compatible with 266 SRO locks. 267 Can be upgraded to SNW, SNRW and X locks. Once SU lock is upgraded to X 268 or SNRW lock data modification can happen freely. 269 To be used for the first phase of ALTER TABLE. 270 */ 271 MDL_SHARED_UPGRADABLE, 272 /* 273 A shared metadata lock for cases when we need to read data from table 274 and block all concurrent modifications to it (for both data and metadata). 275 Used by LOCK TABLES READ statement. 276 */ 277 MDL_SHARED_READ_ONLY, 278 /* 279 An upgradable shared metadata lock which blocks all attempts to update 280 table data, allowing reads. 281 A connection holding this kind of lock can read table metadata and read 282 table data. 283 Can be upgraded to X metadata lock. 284 Note, that since this type of lock is not compatible with SNRW or SW 285 lock types, acquiring appropriate engine-level locks for reading 286 (TL_READ* for MyISAM, shared row locks in InnoDB) should be 287 contention-free. 288 To be used for the first phase of ALTER TABLE, when copying data between 289 tables, to allow concurrent SELECTs from the table, but not UPDATEs. 290 */ 291 MDL_SHARED_NO_WRITE, 292 /* 293 An upgradable shared metadata lock which allows other connections 294 to access table metadata, but not data. 295 It blocks all attempts to read or update table data, while allowing 296 INFORMATION_SCHEMA and SHOW queries. 297 A connection holding this kind of lock can read table metadata modify and 298 read table data. 299 Can be upgraded to X metadata lock. 300 To be used for LOCK TABLES WRITE statement. 301 Not compatible with any other lock type except S and SH. 302 */ 303 MDL_SHARED_NO_READ_WRITE, 304 /* 305 An exclusive metadata lock. 306 A connection holding this lock can modify both table's metadata and data. 307 No other type of metadata lock can be granted while this lock is held. 308 To be used for CREATE/DROP/RENAME TABLE statements and for execution of 309 certain phases of other DDL statements. 310 */ 311 MDL_EXCLUSIVE, 312 /* This should be the last !!! */ 313 MDL_TYPE_END 314 }; 315 316 /** Duration of metadata lock. */ 317 318 enum enum_mdl_duration { 319 /** 320 Locks with statement duration are automatically released at the end 321 of statement or transaction. 322 */ 323 MDL_STATEMENT = 0, 324 /** 325 Locks with transaction duration are automatically released at the end 326 of transaction. 327 */ 328 MDL_TRANSACTION, 329 /** 330 Locks with explicit duration survive the end of statement and transaction. 331 They have to be released explicitly by calling MDL_context::release_lock(). 332 */ 333 MDL_EXPLICIT, 334 /* This should be the last ! */ 335 MDL_DURATION_END 336 }; 337 338 /** Maximal length of key for metadata locking subsystem. */ 339 #define MAX_MDLKEY_LENGTH (1 + NAME_LEN + 1 + NAME_LEN + 1) 340 341 /** 342 Metadata lock object key. 343 344 A lock is requested or granted based on a fully qualified name and type. 345 E.g. They key for a table consists of @<0 (=table)@>+@<database@>+@<table 346 name@>. Elsewhere in the comments this triple will be referred to simply as 347 "key" or "name". 348 */ 349 350 struct MDL_key { 351 public: 352 #ifdef HAVE_PSI_INTERFACE 353 static void init_psi_keys(); 354 #endif 355 356 /** 357 Object namespaces. 358 Sic: when adding a new member to this enum make sure to 359 update m_namespace_to_wait_state_name array in mdl.cc! 360 361 Different types of objects exist in different namespaces 362 - GLOBAL is used for the global read lock. 363 - BACKUP_LOCK is to block any operations that could cause 364 inconsistent backup. Such operations are most DDL statements, 365 and some administrative statements. 366 - TABLESPACE is for tablespaces. 367 - SCHEMA is for schemas (aka databases). 368 - TABLE is for tables and views. 369 - FUNCTION is for stored functions. 370 - PROCEDURE is for stored procedures. 371 - TRIGGER is for triggers. 372 - EVENT is for event scheduler events. 373 - COMMIT is for enabling the global read lock to block commits. 374 - USER_LEVEL_LOCK is for user-level locks. 375 - LOCKING_SERVICE is for the name plugin RW-lock service 376 - SRID is for spatial reference systems 377 - ACL_CACHE is for ACL caches 378 - COLUMN_STATISTICS is for column statistics, such as histograms 379 - RESOURCE_GROUPS is for resource groups. 380 - FOREIGN_KEY is for foreign key names. 381 - CHECK_CONSTRAINT is for check constraint names. 382 Note that requests waiting for user-level locks get special 383 treatment - waiting is aborted if connection to client is lost. 384 */ 385 enum enum_mdl_namespace { 386 GLOBAL = 0, 387 BACKUP_LOCK, 388 TABLESPACE, 389 SCHEMA, 390 TABLE, 391 FUNCTION, 392 PROCEDURE, 393 TRIGGER, 394 EVENT, 395 COMMIT, 396 USER_LEVEL_LOCK, 397 LOCKING_SERVICE, 398 SRID, 399 ACL_CACHE, 400 COLUMN_STATISTICS, 401 RESOURCE_GROUPS, 402 FOREIGN_KEY, 403 CHECK_CONSTRAINT, 404 /* This should be the last ! */ 405 NAMESPACE_END 406 }; 407 ptrMDL_key408 const uchar *ptr() const { return pointer_cast<const uchar *>(m_ptr); } lengthMDL_key409 uint length() const { return m_length; } 410 db_nameMDL_key411 const char *db_name() const { return m_ptr + 1; } db_name_lengthMDL_key412 uint db_name_length() const { return m_db_name_length; } 413 nameMDL_key414 const char *name() const { 415 return (use_normalized_object_name() ? m_ptr + m_length 416 : m_ptr + m_db_name_length + 2); 417 } name_lengthMDL_key418 uint name_length() const { return m_object_name_length; } 419 col_nameMDL_key420 const char *col_name() const { 421 DBUG_ASSERT(!use_normalized_object_name()); 422 423 if (m_db_name_length + m_object_name_length + 3 < m_length) { 424 /* A column name was stored in the key buffer. */ 425 return m_ptr + m_db_name_length + m_object_name_length + 3; 426 } 427 428 /* No column name stored. */ 429 return nullptr; 430 } 431 col_name_lengthMDL_key432 uint col_name_length() const { 433 DBUG_ASSERT(!use_normalized_object_name()); 434 435 if (m_db_name_length + m_object_name_length + 3 < m_length) { 436 /* A column name was stored in the key buffer. */ 437 return m_length - m_db_name_length - m_object_name_length - 4; 438 } 439 440 /* No column name stored. */ 441 return 0; 442 } 443 mdl_namespaceMDL_key444 enum_mdl_namespace mdl_namespace() const { 445 return (enum_mdl_namespace)(m_ptr[0]); 446 } 447 448 /** 449 Construct a metadata lock key from a triplet (mdl_namespace, 450 database and name). 451 452 @remark The key for a table is @<mdl_namespace@>+@<database name@>+@<table 453 name@> 454 455 @param mdl_namespace Id of namespace of object to be locked 456 @param db Name of database to which the object belongs 457 @param name Name of of the object 458 */ mdl_key_initMDL_key459 void mdl_key_init(enum_mdl_namespace mdl_namespace, const char *db, 460 const char *name) { 461 m_ptr[0] = (char)mdl_namespace; 462 463 DBUG_ASSERT(!use_normalized_object_name()); 464 465 /* 466 It is responsibility of caller to ensure that db and object names 467 are not longer than NAME_LEN. Still we play safe and try to avoid 468 buffer overruns. 469 470 Implicit tablespace names in InnoDB may be longer than NAME_LEN. 471 We will lock based on the first NAME_LEN characters. 472 473 TODO: The patch acquires metadata locks on the NAME_LEN 474 first bytest of the tablespace names. For long names, 475 the consequence of locking on this prefix is 476 that locking a single implicit tablespace might end up 477 effectively lock all implicit tablespaces in the same 478 schema. A possible fix is to lock on a prefix of length 479 NAME_LEN * 2, since this is the real buffer size of 480 the metadata lock key. Dependencies from the PFS 481 implementation, possibly relying on the key format, 482 must be investigated first, though. 483 */ 484 DBUG_ASSERT(strlen(db) <= NAME_LEN); 485 DBUG_ASSERT((mdl_namespace == TABLESPACE) || (strlen(name) <= NAME_LEN)); 486 m_db_name_length = 487 static_cast<uint16>(strmake(m_ptr + 1, db, NAME_LEN) - m_ptr - 1); 488 m_object_name_length = static_cast<uint16>( 489 strmake(m_ptr + m_db_name_length + 2, name, NAME_LEN) - m_ptr - 490 m_db_name_length - 2); 491 m_length = m_db_name_length + m_object_name_length + 3; 492 } 493 494 /** 495 Construct a metadata lock key from a quadruplet (mdl_namespace, 496 database, table and column name). 497 498 @remark The key for a column is 499 @<mdl_namespace@>+@<database name@>+@<table name@>+@<column name@> 500 501 @param mdl_namespace Id of namespace of object to be locked 502 @param db Name of database to which the object belongs 503 @param name Name of of the object 504 @param column_name Name of of the column 505 */ mdl_key_initMDL_key506 void mdl_key_init(enum_mdl_namespace mdl_namespace, const char *db, 507 const char *name, const char *column_name) { 508 m_ptr[0] = (char)mdl_namespace; 509 char *start; 510 char *end; 511 512 DBUG_ASSERT(!use_normalized_object_name()); 513 514 DBUG_ASSERT(strlen(db) <= NAME_LEN); 515 start = m_ptr + 1; 516 end = strmake(start, db, NAME_LEN); 517 m_db_name_length = static_cast<uint16>(end - start); 518 519 DBUG_ASSERT(strlen(name) <= NAME_LEN); 520 start = end + 1; 521 end = strmake(start, name, NAME_LEN); 522 m_object_name_length = static_cast<uint16>(end - start); 523 524 size_t col_len = strlen(column_name); 525 DBUG_ASSERT(col_len <= NAME_LEN); 526 start = end + 1; 527 size_t remaining = 528 MAX_MDLKEY_LENGTH - m_db_name_length - m_object_name_length - 3; 529 uint16 extra_length = 0; 530 531 /* 532 In theory: 533 - schema name is up to NAME_LEN characters 534 - object name is up to NAME_LEN characters 535 - column name is up to NAME_LEN characters 536 - NAME_LEN is 64 characters 537 - 1 character is up to 3 bytes (UTF8MB3), 538 and when moving to UTF8MB4, up to 4 bytes. 539 - Storing a SCHEMA + OBJECT MDL key 540 can take up to 387 bytes 541 - Storing a SCHEMA + OBJECT + COLUMN MDL key 542 can take up to 580 bytes. 543 544 In practice: 545 - full storage is allocated for SCHEMA + OBJECT only, 546 storage for COLUMN is **NOT** reserved. 547 - SCHEMA and OBJECT names are typically shorter, 548 and are not using systematically multi-bytes characters 549 for each character, so that less space is required. 550 - MDL keys that are not COLUMN_STATISTICS 551 are stored in full, without truncation. 552 553 For the COLUMN_STATISTICS name space: 554 - either the full SCHEMA + OBJECT + COLUMN key fits 555 within 387 bytes, in which case the fully qualified 556 column name is stored, 557 leading to MDL locks per column (as intended) 558 - or the SCHEMA and OBJECT names are very long, 559 so that not enough room is left to store a column name, 560 in which case the MDL key is truncated to be 561 COLUMN_STATISTICS + SCHEMA + NAME. 562 In this case, MDL locks for columns col_X and col_Y 563 in table LONG_FOO.LONG_BAR will both share the same 564 key LONG_FOO.LONG_BAR, in effect providing a lock 565 granularity not per column but per table. 566 This is a degraded mode of operation, 567 which serializes MDL access to columns 568 (for tables with a very long fully qualified name), 569 to reduce the memory footprint for all MDL access. 570 571 To be revised if the MDL key buffer is allocated dynamically 572 instead. 573 */ 574 575 static_assert(MAX_MDLKEY_LENGTH == 387, "UTF8MB3"); 576 577 /* 578 Check if there is room to store the whole column name. 579 This code is not trying to store truncated column names, 580 to avoid cutting column_name in the middle of a 581 multi-byte character. 582 */ 583 if (remaining >= col_len + 1) { 584 end = strmake(start, column_name, remaining); 585 extra_length = static_cast<uint16>(end - start) + 1; // With \0 586 } 587 m_length = m_db_name_length + m_object_name_length + 3 + extra_length; 588 DBUG_ASSERT(m_length <= MAX_MDLKEY_LENGTH); 589 } 590 591 /** 592 Construct a metadata lock key from a quadruplet (mdl_namespace, database, 593 normalized object name buffer and the object name). 594 595 @remark The key for a routine/event/resource group/trigger is 596 @<mdl_namespace@>+@<database name@>+@<normalized object name@> 597 additionaly @<object name@> is stored in the same buffer for information 598 purpose if buffer has sufficent space. 599 600 Routine, Event and Resource group names are case sensitive and accent 601 sensitive. So normalized object name is used to form a MDL_key. 602 603 With the UTF8MB3 charset space reserved for the db name/object name is 604 64 * 3 bytes. utf8_general_ci collation is used for the Routine, Event and 605 Resource group names. With this collation, the normalized object name uses 606 just 2 bytes for each character (max length = 64 * 2 bytes). MDL_key has 607 still some space to store the object names. If there is a sufficient space 608 for the object name in the MDL_key then it is stored in the MDL_key (similar 609 to the column names in the MDL_key). Actual object name is used by the PFS. 610 Not listing actual object name from the PFS should be OK when there is no 611 space to store it (instead of increasing the MDL_key size). Object name is 612 not used in the key comparisons. So only (mdl_namespace + strlen(db) + 1 + 613 normalized_name_len + 1) value is stored in the m_length member. 614 615 @param mdl_namespace Id of namespace of object to be locked. 616 @param db Name of database to which the object belongs. 617 @param normalized_name Normalized name of the object. 618 @param normalized_name_len Length of the normalized object name. 619 @param name Name of the object. 620 */ mdl_key_initMDL_key621 void mdl_key_init(enum_mdl_namespace mdl_namespace, const char *db, 622 const char *normalized_name, size_t normalized_name_len, 623 const char *name) { 624 m_ptr[0] = (char)mdl_namespace; 625 626 /* 627 FUNCTION, PROCEDURE, EVENT and RESOURCE_GROUPS names are case and accent 628 insensitive. For other objects key should not be formed from this method. 629 */ 630 DBUG_ASSERT(use_normalized_object_name()); 631 632 DBUG_ASSERT(strlen(db) <= NAME_LEN && strlen(name) <= NAME_LEN && 633 normalized_name_len <= NAME_CHAR_LEN * 2); 634 635 // Database name. 636 m_db_name_length = 637 static_cast<uint16>(strmake(m_ptr + 1, db, NAME_LEN) - m_ptr - 1); 638 639 // Normalized object name. 640 m_length = static_cast<uint16>(m_db_name_length + normalized_name_len + 3); 641 memcpy(m_ptr + m_db_name_length + 2, normalized_name, normalized_name_len); 642 *(m_ptr + m_length - 1) = 0; 643 644 /* 645 Copy name of the object if there is a sufficient space to store the name 646 in the MDL key. This code is not trying to store truncated object names, 647 to avoid cutting object_name in the middle of a multi-byte character. 648 */ 649 if (strlen(name) < static_cast<size_t>(MAX_MDLKEY_LENGTH - m_length)) { 650 m_object_name_length = static_cast<uint16>( 651 (strmake(m_ptr + m_length, name, MAX_MDLKEY_LENGTH - m_length - 1) - 652 m_ptr - m_length)); 653 } else { 654 m_object_name_length = 0; 655 *(m_ptr + m_length) = 0; 656 } 657 658 DBUG_ASSERT(m_length + m_object_name_length < MAX_MDLKEY_LENGTH); 659 } 660 661 /** 662 Construct a metadata lock key from namespace and partial key, which 663 contains info about object database and name. 664 665 @remark The partial key must be "<database>\0<name>\0". 666 667 @param mdl_namespace Id of namespace of object to be locked 668 @param part_key Partial key. 669 @param part_key_length Partial key length 670 @param db_length Database name length. 671 */ mdl_key_initMDL_key672 void mdl_key_init(enum_mdl_namespace mdl_namespace, const char *part_key, 673 size_t part_key_length, size_t db_length) { 674 /* 675 Key suffix provided should be in compatible format and 676 its components should adhere to length restrictions. 677 */ 678 DBUG_ASSERT(strlen(part_key) == db_length); 679 DBUG_ASSERT(db_length + 1 + strlen(part_key + db_length + 1) + 1 == 680 part_key_length); 681 DBUG_ASSERT(db_length <= NAME_LEN); 682 DBUG_ASSERT(part_key_length <= NAME_LEN + 1 + NAME_LEN + 1); 683 684 m_ptr[0] = (char)mdl_namespace; 685 /* 686 Partial key of objects with normalized object name can not be used to 687 initialize MDL key. 688 */ 689 DBUG_ASSERT(!use_normalized_object_name()); 690 691 memcpy(m_ptr + 1, part_key, part_key_length); 692 m_length = static_cast<uint16>(part_key_length + 1); 693 m_db_name_length = static_cast<uint16>(db_length); 694 m_object_name_length = m_length - m_db_name_length - 3; 695 } mdl_key_initMDL_key696 void mdl_key_init(const MDL_key *rhs) { 697 uint16 copy_length = rhs->use_normalized_object_name() 698 ? rhs->m_length + rhs->m_object_name_length + 1 699 : rhs->m_length; 700 memcpy(m_ptr, rhs->m_ptr, copy_length); 701 m_length = rhs->m_length; 702 m_db_name_length = rhs->m_db_name_length; 703 m_object_name_length = rhs->m_object_name_length; 704 } resetMDL_key705 void reset() { 706 m_ptr[0] = NAMESPACE_END; 707 m_db_name_length = 0; 708 m_object_name_length = 0; 709 m_length = 0; 710 } is_equalMDL_key711 bool is_equal(const MDL_key *rhs) const { 712 return (m_length == rhs->m_length && 713 memcmp(m_ptr, rhs->m_ptr, m_length) == 0); 714 } 715 /** 716 Compare two MDL keys lexicographically. 717 */ cmpMDL_key718 int cmp(const MDL_key *rhs) const { 719 /* 720 For the keys with the normalized names, there is a possibility of getting 721 '\0' in its middle. So only key content comparison would yield incorrect 722 result. Hence comparing key length too when keys are equal. 723 For other keys, key buffer is always '\0'-terminated. Since key character 724 set is utf-8, we can safely assume that no character starts with a zero 725 byte. 726 */ 727 int res = memcmp(m_ptr, rhs->m_ptr, std::min(m_length, rhs->m_length)); 728 if (res == 0) res = m_length - rhs->m_length; 729 return res; 730 } 731 MDL_keyMDL_key732 MDL_key(const MDL_key &rhs) { mdl_key_init(&rhs); } 733 734 MDL_key &operator=(const MDL_key &rhs) { 735 mdl_key_init(&rhs); 736 return *this; 737 } 738 MDL_keyMDL_key739 MDL_key(enum_mdl_namespace namespace_arg, const char *db_arg, 740 const char *name_arg) { 741 mdl_key_init(namespace_arg, db_arg, name_arg); 742 } MDL_keyMDL_key743 MDL_key() {} /* To use when part of MDL_request. */ 744 745 /** 746 Get thread state name to be used in case when we have to 747 wait on resource identified by key. 748 */ get_wait_state_nameMDL_key749 const PSI_stage_info *get_wait_state_name() const { 750 return &m_namespace_to_wait_state_name[(int)mdl_namespace()]; 751 } 752 753 private: 754 /** 755 Check if normalized object name should be used. 756 757 @return true if normlized object name should be used, false 758 otherwise. 759 */ use_normalized_object_nameMDL_key760 bool use_normalized_object_name() const { 761 return (mdl_namespace() == FUNCTION || mdl_namespace() == PROCEDURE || 762 mdl_namespace() == EVENT || mdl_namespace() == RESOURCE_GROUPS || 763 mdl_namespace() == TRIGGER); 764 } 765 766 private: 767 uint16 m_length{0}; 768 uint16 m_db_name_length{0}; 769 uint16 m_object_name_length{0}; 770 char m_ptr[MAX_MDLKEY_LENGTH]{0}; 771 static PSI_stage_info m_namespace_to_wait_state_name[NAMESPACE_END]; 772 }; 773 774 /** 775 A pending metadata lock request. 776 777 A lock request and a granted metadata lock are represented by 778 different classes because they have different allocation 779 sites and hence different lifetimes. The allocation of lock requests is 780 controlled from outside of the MDL subsystem, while allocation of granted 781 locks (tickets) is controlled within the MDL subsystem. 782 */ 783 784 class MDL_request { 785 public: 786 /** Type of metadata lock. */ 787 enum_mdl_type type{MDL_INTENTION_EXCLUSIVE}; 788 /** Duration for requested lock. */ 789 enum_mdl_duration duration{MDL_STATEMENT}; 790 791 /** 792 Pointers for participating in the list of lock requests for this context. 793 */ 794 MDL_request *next_in_list{nullptr}; 795 MDL_request **prev_in_list{nullptr}; 796 /** 797 Pointer to the lock ticket object for this lock request. 798 Valid only if this lock request is satisfied. 799 */ 800 MDL_ticket *ticket{nullptr}; 801 802 /** A lock is requested based on a fully qualified name and type. */ 803 MDL_key key; 804 805 const char *m_src_file{nullptr}; 806 uint m_src_line{0}; 807 808 public: 809 static void *operator new(size_t size, MEM_ROOT *mem_root, 810 const std::nothrow_t &arg MY_ATTRIBUTE((unused)) = 811 std::nothrow) noexcept { 812 return mem_root->Alloc(size); 813 } 814 delete(void *,MEM_ROOT *,const std::nothrow_t &)815 static void operator delete(void *, MEM_ROOT *, 816 const std::nothrow_t &) noexcept {} 817 818 void init_with_source(MDL_key::enum_mdl_namespace namespace_arg, 819 const char *db_arg, const char *name_arg, 820 enum_mdl_type mdl_type_arg, 821 enum_mdl_duration mdl_duration_arg, 822 const char *src_file, uint src_line); 823 void init_by_key_with_source(const MDL_key *key_arg, 824 enum_mdl_type mdl_type_arg, 825 enum_mdl_duration mdl_duration_arg, 826 const char *src_file, uint src_line); 827 void init_by_part_key_with_source(MDL_key::enum_mdl_namespace namespace_arg, 828 const char *part_key_arg, 829 size_t part_key_length_arg, 830 size_t db_length_arg, 831 enum_mdl_type mdl_type_arg, 832 enum_mdl_duration mdl_duration_arg, 833 const char *src_file, uint src_line); 834 /** Set type of lock request. Can be only applied to pending locks. */ set_type(enum_mdl_type type_arg)835 inline void set_type(enum_mdl_type type_arg) { 836 DBUG_ASSERT(ticket == nullptr); 837 type = type_arg; 838 } 839 840 /** 841 Is this a request for a lock which allow data to be updated? 842 843 @note This method returns true for MDL_SHARED_UPGRADABLE type of 844 lock. Even though this type of lock doesn't allow updates 845 it will always be upgraded to one that does. 846 */ is_write_lock_request()847 bool is_write_lock_request() const { 848 return (type >= MDL_SHARED_WRITE && type != MDL_SHARED_READ_ONLY); 849 } 850 851 /** Is this a request for a strong, DDL/LOCK TABLES-type, of lock? */ is_ddl_or_lock_tables_lock_request()852 bool is_ddl_or_lock_tables_lock_request() const { 853 return type >= MDL_SHARED_UPGRADABLE; 854 } 855 856 /** 857 This constructor exists for two reasons: 858 859 - TABLE_LIST objects are sometimes default-constructed. We plan to remove 860 this as there is no practical reason, the call to the default 861 constructor is always followed by either a call to TABLE_LIST::operator= 862 or memberwise assignments. 863 864 - In some legacy cases TABLE_LIST objects are copy-assigned without 865 intention to copy the TABLE_LIST::mdl_request member. In this cases they 866 are overwritten with an uninitialized MDL_request object. The cases are: 867 868 - Sql_cmd_handler_open::execute() 869 - mysql_execute_command() 870 - SELECT_LEX_UNIT::prepare() 871 - fill_defined_view_parts() 872 873 No new cases are expected. In all other cases, so far only 874 Locked_tables_list::rename_locked_table(), a move assignment is actually 875 what is intended. 876 */ MDL_request()877 MDL_request() {} 878 MDL_request(const MDL_request & rhs)879 MDL_request(const MDL_request &rhs) 880 : type(rhs.type), duration(rhs.duration), ticket(nullptr), key(rhs.key) {} 881 882 MDL_request(MDL_request &&) = default; 883 884 MDL_request &operator=(MDL_request &&) = default; 885 }; 886 887 #define MDL_REQUEST_INIT(R, P1, P2, P3, P4, P5) \ 888 (*R).init_with_source(P1, P2, P3, P4, P5, __FILE__, __LINE__) 889 890 #define MDL_REQUEST_INIT_BY_KEY(R, P1, P2, P3) \ 891 (*R).init_by_key_with_source(P1, P2, P3, __FILE__, __LINE__) 892 893 #define MDL_REQUEST_INIT_BY_PART_KEY(R, P1, P2, P3, P4, P5, P6) \ 894 (*R).init_by_part_key_with_source(P1, P2, P3, P4, P5, P6, __FILE__, __LINE__) 895 896 /** 897 An abstract class for inspection of a connected 898 subgraph of the wait-for graph. 899 */ 900 901 class MDL_wait_for_graph_visitor { 902 public: 903 virtual bool enter_node(MDL_context *node) = 0; 904 virtual void leave_node(MDL_context *node) = 0; 905 906 virtual bool inspect_edge(MDL_context *dest) = 0; 907 virtual ~MDL_wait_for_graph_visitor(); MDL_wait_for_graph_visitor()908 MDL_wait_for_graph_visitor() : m_lock_open_count(0) {} 909 910 public: 911 /** 912 XXX, hack: During deadlock search, we may need to 913 inspect TABLE_SHAREs and acquire LOCK_open. Since 914 LOCK_open is not a recursive mutex, count here how many 915 times we "took" it (but only take and release once). 916 Not using a native recursive mutex or rwlock in 5.5 for 917 LOCK_open since it has significant performance impacts. 918 */ 919 uint m_lock_open_count; 920 }; 921 922 /** 923 Abstract class representing an edge in the waiters graph 924 to be traversed by deadlock detection algorithm. 925 */ 926 927 class MDL_wait_for_subgraph { 928 public: 929 virtual ~MDL_wait_for_subgraph(); 930 931 /** 932 Accept a wait-for graph visitor to inspect the node 933 this edge is leading to. 934 */ 935 virtual bool accept_visitor(MDL_wait_for_graph_visitor *gvisitor) = 0; 936 937 static const uint DEADLOCK_WEIGHT_DML = 0; 938 static const uint DEADLOCK_WEIGHT_ULL = 50; 939 static const uint DEADLOCK_WEIGHT_DDL = 100; 940 941 /* A helper used to determine which lock request should be aborted. */ 942 virtual uint get_deadlock_weight() const = 0; 943 }; 944 945 /** 946 A granted metadata lock. 947 948 @warning MDL_ticket members are private to the MDL subsystem. 949 950 @note Multiple shared locks on a same object are represented by a 951 single ticket. The same does not apply for other lock types. 952 953 @note There are two groups of MDL_ticket members: 954 - "Externally accessible". These members can be accessed from 955 threads/contexts different than ticket owner in cases when 956 ticket participates in some list of granted or waiting tickets 957 for a lock. Therefore one should change these members before 958 including then to waiting/granted lists or while holding lock 959 protecting those lists. 960 - "Context private". Such members are private to thread/context 961 owning this ticket. I.e. they should not be accessed from other 962 threads/contexts. 963 */ 964 965 class MDL_ticket : public MDL_wait_for_subgraph { 966 public: 967 /** 968 Pointers for participating in the list of lock requests for this context. 969 Context private. 970 */ 971 MDL_ticket *next_in_context; 972 MDL_ticket **prev_in_context; 973 974 /** 975 Pointers for participating in the list of satisfied/pending requests 976 for the lock. Externally accessible. 977 */ 978 MDL_ticket *next_in_lock; 979 MDL_ticket **prev_in_lock; 980 981 public: 982 bool has_pending_conflicting_lock() const; 983 get_ctx()984 MDL_context *get_ctx() const { return m_ctx; } is_upgradable_or_exclusive()985 bool is_upgradable_or_exclusive() const { 986 return m_type == MDL_SHARED_UPGRADABLE || m_type == MDL_SHARED_NO_WRITE || 987 m_type == MDL_SHARED_NO_READ_WRITE || m_type == MDL_EXCLUSIVE; 988 } get_type()989 enum_mdl_type get_type() const { return m_type; } get_lock()990 MDL_lock *get_lock() const { return m_lock; } 991 const MDL_key *get_key() const; 992 void downgrade_lock(enum_mdl_type type); 993 994 bool has_stronger_or_equal_type(enum_mdl_type type) const; 995 996 bool is_incompatible_when_granted(enum_mdl_type type) const; 997 bool is_incompatible_when_waiting(enum_mdl_type type) const; 998 999 /** Implement MDL_wait_for_subgraph interface. */ 1000 virtual bool accept_visitor(MDL_wait_for_graph_visitor *dvisitor); 1001 virtual uint get_deadlock_weight() const; 1002 1003 #ifndef DBUG_OFF get_duration()1004 enum_mdl_duration get_duration() const { return m_duration; } set_duration(enum_mdl_duration dur)1005 void set_duration(enum_mdl_duration dur) { m_duration = dur; } 1006 #endif 1007 1008 public: 1009 /** 1010 Status of lock request represented by the ticket as reflected in P_S. 1011 */ 1012 enum enum_psi_status { 1013 PENDING = 0, 1014 GRANTED, 1015 PRE_ACQUIRE_NOTIFY, 1016 POST_RELEASE_NOTIFY 1017 }; 1018 1019 private: 1020 friend class MDL_context; 1021 MDL_ticket(MDL_context * ctx_arg,enum_mdl_type type_arg,enum_mdl_duration duration_arg)1022 MDL_ticket(MDL_context *ctx_arg, enum_mdl_type type_arg 1023 #ifndef DBUG_OFF 1024 , 1025 enum_mdl_duration duration_arg 1026 #endif 1027 ) 1028 : m_type(type_arg), 1029 #ifndef DBUG_OFF 1030 m_duration(duration_arg), 1031 #endif 1032 m_ctx(ctx_arg), 1033 m_lock(nullptr), 1034 m_is_fast_path(false), 1035 m_hton_notified(false), 1036 m_psi(nullptr) { 1037 } 1038 ~MDL_ticket()1039 virtual ~MDL_ticket() { DBUG_ASSERT(m_psi == nullptr); } 1040 1041 static MDL_ticket *create(MDL_context *ctx_arg, enum_mdl_type type_arg 1042 #ifndef DBUG_OFF 1043 , 1044 enum_mdl_duration duration_arg 1045 #endif 1046 ); 1047 static void destroy(MDL_ticket *ticket); 1048 1049 private: 1050 /** Type of metadata lock. Externally accessible. */ 1051 enum enum_mdl_type m_type; 1052 #ifndef DBUG_OFF 1053 /** 1054 Duration of lock represented by this ticket. 1055 Context private. Debug-only. 1056 */ 1057 enum_mdl_duration m_duration; 1058 #endif 1059 /** 1060 Context of the owner of the metadata lock ticket. Externally accessible. 1061 */ 1062 MDL_context *m_ctx; 1063 1064 /** 1065 Pointer to the lock object for this lock ticket. Externally accessible. 1066 */ 1067 MDL_lock *m_lock; 1068 1069 /** 1070 Indicates that ticket corresponds to lock acquired using "fast path" 1071 algorithm. Particularly this means that it was not included into 1072 MDL_lock::m_granted bitmap/list and instead is accounted for by 1073 MDL_lock::m_fast_path_locks_granted_counter 1074 */ 1075 bool m_is_fast_path; 1076 1077 /** 1078 Indicates that ticket corresponds to lock request which required 1079 storage engine notification during its acquisition and requires 1080 storage engine notification after its release. 1081 */ 1082 bool m_hton_notified; 1083 1084 PSI_metadata_lock *m_psi; 1085 1086 private: 1087 MDL_ticket(const MDL_ticket &); /* not implemented */ 1088 MDL_ticket &operator=(const MDL_ticket &); /* not implemented */ 1089 }; 1090 1091 /** 1092 Keep track of MDL_ticket for different durations. Maintains a 1093 hash-based secondary index into the linked lists, to speed up access 1094 by MDL_key. 1095 */ 1096 class MDL_ticket_store { 1097 public: 1098 /** 1099 Utility struct for representing a ticket pointer and its duration. 1100 */ 1101 struct MDL_ticket_handle { 1102 enum_mdl_duration m_dur = MDL_DURATION_END; 1103 MDL_ticket *m_ticket = nullptr; 1104 1105 MDL_ticket_handle() = default; MDL_ticket_handleMDL_ticket_handle1106 MDL_ticket_handle(MDL_ticket *t, enum_mdl_duration d) 1107 : m_dur{d}, m_ticket{t} {} 1108 }; 1109 1110 private: 1111 using Ticket_p_list = 1112 I_P_List<MDL_ticket, 1113 I_P_List_adapter<MDL_ticket, &MDL_ticket::next_in_context, 1114 &MDL_ticket::prev_in_context>>; 1115 1116 struct Duration { 1117 Ticket_p_list m_ticket_list; 1118 /** 1119 m_mat_front tracks what was the front of m_ticket_list, the last 1120 time MDL_context::materialize_fast_path_locks() was called. This 1121 just an optimization which allows 1122 MDL_context::materialize_fast_path_locks() only to consider the 1123 locks added since the last time it ran. Consequently, it can be 1124 assumed that every ticket after m_mat_front is materialized, but 1125 the converse is not necessarily true as new, already 1126 materialized, locks may have been added since the last time 1127 materialize_fast_path_locks() ran. 1128 */ 1129 MDL_ticket *m_mat_front = nullptr; 1130 }; 1131 1132 Duration m_durations[MDL_DURATION_END]; 1133 1134 struct Hash { 1135 size_t operator()(const MDL_key *k) const; 1136 }; 1137 1138 struct Key_equal { operatorKey_equal1139 bool operator()(const MDL_key *a, const MDL_key *b) const { 1140 return a->is_equal(b); 1141 } 1142 }; 1143 1144 using Ticket_map = std::unordered_multimap<const MDL_key *, MDL_ticket_handle, 1145 Hash, Key_equal>; 1146 1147 /** 1148 If the number of tickets in the ticket store (in all durations) is equal 1149 to, or exceeds this constant the hash index (in the form of an 1150 unordered_multi_map) will be maintained and used for lookups. 1151 1152 The value 256 is chosen as it has worked well in benchmarks. 1153 */ 1154 const size_t THRESHOLD = 256; 1155 1156 /** 1157 Initial number of buckets in the hash index. THRESHOLD is chosen 1158 to get a fill-factor of 50% when reaching the threshold value. 1159 */ 1160 const size_t INITIAL_BUCKET_COUNT = THRESHOLD * 2; 1161 size_t m_count = 0; 1162 1163 std::unique_ptr<Ticket_map> m_map; 1164 1165 MDL_ticket_handle find_in_lists(const MDL_request &req) const; 1166 MDL_ticket_handle find_in_hash(const MDL_request &req) const; 1167 1168 public: 1169 /** 1170 Public alias. 1171 */ 1172 using List_iterator = Ticket_p_list::Iterator; 1173 1174 /** 1175 Constructs store. The hash index is initially empty. Filled on demand. 1176 */ MDL_ticket_store()1177 MDL_ticket_store() 1178 : // Comment in to test threshold values in unit test micro benchmark 1179 // THRESHOLD{read_from_env("TS_THRESHOLD", 500)}, 1180 m_map{nullptr} {} 1181 1182 /** 1183 Calls the closure provided as argument for each of the MDL_tickets 1184 in the given duration. 1185 @param dur duration list to iterate over 1186 @param clos closure to invoke for each ticket in the list 1187 */ 1188 template <typename CLOS> for_each_ticket_in_duration_list(enum_mdl_duration dur,CLOS && clos)1189 void for_each_ticket_in_duration_list(enum_mdl_duration dur, CLOS &&clos) { 1190 List_iterator it(m_durations[dur].m_ticket_list); 1191 for (MDL_ticket *t = it++; t != nullptr; t = it++) { 1192 clos(t, dur); 1193 } 1194 } 1195 1196 /** 1197 Calls the closure provided as argument for each of the MDL_tickets 1198 in the store. 1199 @param clos closure to invoke for each ticket in the store 1200 */ 1201 template <typename CLOS> for_each_ticket_in_ticket_lists(CLOS && clos)1202 void for_each_ticket_in_ticket_lists(CLOS &&clos) { 1203 for_each_ticket_in_duration_list(MDL_STATEMENT, std::forward<CLOS>(clos)); 1204 for_each_ticket_in_duration_list(MDL_TRANSACTION, std::forward<CLOS>(clos)); 1205 for_each_ticket_in_duration_list(MDL_EXPLICIT, std::forward<CLOS>(clos)); 1206 } 1207 1208 /** 1209 Predicate for the emptiness of the store. 1210 @return true if there are no tickets in the store 1211 */ 1212 bool is_empty() const; 1213 1214 /** 1215 Predicate for the emptiness of a given duration list. 1216 @param di the duration to check 1217 @return true if there are no tickets with the given duration 1218 */ 1219 bool is_empty(int di) const; 1220 1221 /** 1222 Return the first MDL_ticket for the given duration. 1223 1224 @param di duration to get first ticket for 1225 1226 @return first ticket in the given duration or nullptr if no such 1227 tickets exist 1228 */ 1229 MDL_ticket *front(int di); 1230 1231 /** 1232 Push a ticket onto the list for a given duration. 1233 @param dur duration list to push into 1234 @param ticket to push 1235 */ 1236 void push_front(enum_mdl_duration dur, MDL_ticket *ticket); 1237 1238 /** 1239 Remove a ticket from a duration list. Note that since the 1240 underlying list is an intrusive linked list there is no guarantee 1241 that the ticket is actually in the duration list. It will be 1242 removed from which ever list it is in. 1243 */ 1244 void remove(enum_mdl_duration dur, MDL_ticket *ticket); 1245 1246 /** 1247 Return a P-list iterator to the given duration. 1248 @param di duration list index 1249 @return P-list iterator to tickets with given duration 1250 */ list_iterator(int di)1251 List_iterator list_iterator(int di) const { 1252 return List_iterator{m_durations[di].m_ticket_list}; 1253 } 1254 1255 /** 1256 Move all tickets to the explicit duration list. 1257 */ 1258 void move_all_to_explicit_duration(); 1259 1260 /** 1261 Move all tickets to the transaction duration list. 1262 */ 1263 void move_explicit_to_transaction_duration(); 1264 1265 /** 1266 Look up a ticket based on its MDL_key. 1267 @param req request to locate ticket for 1268 @return MDL_ticket_handle with ticket pointer and found duration 1269 (or nullptr and MDL_DURATION_END if not found 1270 */ 1271 MDL_ticket_handle find(const MDL_request &req) const; 1272 1273 /** 1274 Mark boundary for tickets with fast_path=false, so that later 1275 calls to materialize_fast_path_locks() do not have to traverse the 1276 whole set of tickets. 1277 */ 1278 void set_materialized(); 1279 1280 /** 1281 Return the first ticket for which materialize_fast_path_locks 1282 already has been called for the given duration. 1283 1284 @param di duration list index 1285 @return first materialized ticket for the given duration 1286 */ 1287 MDL_ticket *materialized_front(int di); 1288 }; 1289 1290 /** 1291 Savepoint for MDL context. 1292 1293 Doesn't include metadata locks with explicit duration as 1294 they are not released during rollback to savepoint. 1295 */ 1296 1297 class MDL_savepoint { 1298 public: MDL_savepoint()1299 MDL_savepoint() {} 1300 1301 private: MDL_savepoint(MDL_ticket * stmt_ticket,MDL_ticket * trans_ticket)1302 MDL_savepoint(MDL_ticket *stmt_ticket, MDL_ticket *trans_ticket) 1303 : m_stmt_ticket(stmt_ticket), m_trans_ticket(trans_ticket) {} 1304 1305 friend class MDL_context; 1306 1307 private: 1308 /** 1309 Pointer to last lock with statement duration which was taken 1310 before creation of savepoint. 1311 */ 1312 MDL_ticket *m_stmt_ticket; 1313 /** 1314 Pointer to last lock with transaction duration which was taken 1315 before creation of savepoint. 1316 */ 1317 MDL_ticket *m_trans_ticket; 1318 }; 1319 1320 /** 1321 A reliable way to wait on an MDL lock. 1322 */ 1323 1324 class MDL_wait { 1325 public: 1326 MDL_wait(); 1327 ~MDL_wait(); 1328 1329 // WS_EMPTY since EMPTY conflicts with #define in system headers on some 1330 // platforms. 1331 enum enum_wait_status { WS_EMPTY = 0, GRANTED, VICTIM, TIMEOUT, KILLED }; 1332 1333 bool set_status(enum_wait_status result_arg); 1334 enum_wait_status get_status(); 1335 void reset_status(); 1336 enum_wait_status timed_wait(MDL_context_owner *owner, 1337 struct timespec *abs_timeout, bool signal_timeout, 1338 const PSI_stage_info *wait_state_name); 1339 1340 private: 1341 /** 1342 Condvar which is used for waiting until this context's pending 1343 request can be satisfied or this thread has to perform actions 1344 to resolve a potential deadlock (we subscribe to such 1345 notification by adding a ticket corresponding to the request 1346 to an appropriate queue of waiters). 1347 */ 1348 mysql_mutex_t m_LOCK_wait_status; 1349 mysql_cond_t m_COND_wait_status; 1350 enum_wait_status m_wait_status; 1351 }; 1352 1353 /** 1354 Base class to find out if the lock represented by a given ticket 1355 should be released. Users of release_locks() need to subclass 1356 this and specify an implementation of release(). Only for locks 1357 with explicit duration. 1358 */ 1359 1360 class MDL_release_locks_visitor { 1361 public: ~MDL_release_locks_visitor()1362 virtual ~MDL_release_locks_visitor() {} 1363 /** 1364 Check if the given ticket represents a lock that should be released. 1365 1366 @retval true if the lock should be released, false otherwise. 1367 */ 1368 virtual bool release(MDL_ticket *ticket) = 0; 1369 }; 1370 1371 /** 1372 Abstract visitor class for inspecting MDL_context. 1373 */ 1374 1375 class MDL_context_visitor { 1376 public: ~MDL_context_visitor()1377 virtual ~MDL_context_visitor() {} 1378 virtual void visit_context(const MDL_context *ctx) = 0; 1379 }; 1380 1381 typedef I_P_List<MDL_request, 1382 I_P_List_adapter<MDL_request, &MDL_request::next_in_list, 1383 &MDL_request::prev_in_list>, 1384 I_P_List_counter> 1385 MDL_request_list; 1386 1387 /** 1388 Context of the owner of metadata locks. I.e. each server 1389 connection has such a context. 1390 */ 1391 1392 class MDL_context { 1393 public: 1394 typedef I_P_List<MDL_ticket, 1395 I_P_List_adapter<MDL_ticket, &MDL_ticket::next_in_context, 1396 &MDL_ticket::prev_in_context>> 1397 Ticket_list; 1398 1399 typedef Ticket_list::Iterator Ticket_iterator; 1400 1401 MDL_context(); 1402 void destroy(); 1403 1404 bool try_acquire_lock(MDL_request *mdl_request); 1405 bool acquire_lock(MDL_request *mdl_request, Timeout_type lock_wait_timeout); 1406 bool acquire_locks(MDL_request_list *requests, 1407 Timeout_type lock_wait_timeout); 1408 bool upgrade_shared_lock(MDL_ticket *mdl_ticket, enum_mdl_type new_type, 1409 Timeout_type lock_wait_timeout); 1410 1411 bool clone_ticket(MDL_request *mdl_request); 1412 1413 /** 1414 Create copy of all granted tickets of particular duration from given 1415 context to current context. 1416 Used by XA for preserving locks during client disconnect. 1417 1418 @param ticket_owner Owner of tickets to be cloned 1419 @param duration MDL lock duration for that tickets are to be cloned 1420 1421 @retval true Out of memory or deadlock happened or 1422 lock request was refused by storage engine. 1423 @retval false Success. 1424 */ 1425 1426 bool clone_tickets(const MDL_context *ticket_owner, 1427 enum_mdl_duration duration); 1428 1429 void release_all_locks_for_name(MDL_ticket *ticket); 1430 void release_locks(MDL_release_locks_visitor *visitor); 1431 void release_lock(MDL_ticket *ticket); 1432 1433 bool owns_equal_or_stronger_lock(const MDL_key *mdl_key, 1434 enum_mdl_type mdl_type); 1435 1436 bool owns_equal_or_stronger_lock(MDL_key::enum_mdl_namespace mdl_namespace, 1437 const char *db, const char *name, 1438 enum_mdl_type mdl_type); 1439 1440 bool find_lock_owner(const MDL_key *mdl_key, MDL_context_visitor *visitor); 1441 1442 bool has_lock(const MDL_savepoint &mdl_savepoint, MDL_ticket *mdl_ticket); 1443 has_locks()1444 inline bool has_locks() const { return !m_ticket_store.is_empty(); } 1445 1446 bool has_locks(MDL_key::enum_mdl_namespace mdl_namespace) const; 1447 1448 bool has_locks_waited_for() const; 1449 1450 #ifndef DBUG_OFF has_locks(enum_mdl_duration duration)1451 bool has_locks(enum_mdl_duration duration) { 1452 return !m_ticket_store.is_empty(duration); 1453 } 1454 #endif 1455 mdl_savepoint()1456 MDL_savepoint mdl_savepoint() { 1457 return MDL_savepoint(m_ticket_store.front(MDL_STATEMENT), 1458 m_ticket_store.front(MDL_TRANSACTION)); 1459 } 1460 1461 void set_explicit_duration_for_all_locks(); 1462 void set_transaction_duration_for_all_locks(); 1463 void set_lock_duration(MDL_ticket *mdl_ticket, enum_mdl_duration duration); 1464 1465 void release_statement_locks(); 1466 void release_transactional_locks(); 1467 void rollback_to_savepoint(const MDL_savepoint &mdl_savepoint); 1468 get_owner()1469 MDL_context_owner *get_owner() const { return m_owner; } 1470 1471 /** @pre Only valid if we started waiting for lock. */ get_deadlock_weight()1472 inline uint get_deadlock_weight() const { 1473 return m_force_dml_deadlock_weight 1474 ? MDL_wait_for_subgraph::DEADLOCK_WEIGHT_DML 1475 : m_waiting_for->get_deadlock_weight(); 1476 } 1477 init(MDL_context_owner * arg)1478 void init(MDL_context_owner *arg) { m_owner = arg; } 1479 set_needs_thr_lock_abort(bool needs_thr_lock_abort)1480 void set_needs_thr_lock_abort(bool needs_thr_lock_abort) { 1481 /* 1482 @note In theory, this member should be modified under protection 1483 of some lock since it can be accessed from different threads. 1484 In practice, this is not necessary as code which reads this 1485 value and so might miss the fact that value was changed will 1486 always re-try reading it after small timeout and therefore 1487 will see the new value eventually. 1488 */ 1489 m_needs_thr_lock_abort = needs_thr_lock_abort; 1490 1491 if (m_needs_thr_lock_abort) { 1492 /* 1493 For MDL_object_lock::notify_conflicting_locks() to work properly 1494 all context requiring thr_lock aborts should not have any "fast 1495 path" locks. 1496 */ 1497 materialize_fast_path_locks(); 1498 } 1499 } get_needs_thr_lock_abort()1500 bool get_needs_thr_lock_abort() const { return m_needs_thr_lock_abort; } 1501 set_force_dml_deadlock_weight(bool force_dml_deadlock_weight)1502 void set_force_dml_deadlock_weight(bool force_dml_deadlock_weight) { 1503 m_force_dml_deadlock_weight = force_dml_deadlock_weight; 1504 } 1505 1506 /** 1507 Get pseudo random value in [0 .. 2^31-1] range. 1508 1509 @note We use Linear Congruential Generator with venerable constant 1510 parameters for this. 1511 It is known to have problems with its lower bits are not being 1512 very random so probably is not good enough for generic use. 1513 However, we only use it to do random dives into MDL_lock objects 1514 hash when searching for unused objects to be freed, and for this 1515 purposes it is sufficient. 1516 We rely on values of "get_random() % 2^k" expression having "2^k" 1517 as a period to ensure that random dives eventually cover all hash 1518 (the former can be proven to be true). This also means that there 1519 is no bias towards any specific objects to be expelled (as hash 1520 values don't repeat), which is nice for performance. 1521 */ get_random()1522 uint get_random() { 1523 if (m_rand_state > INT_MAX32) { 1524 /* 1525 Perform lazy initialization of LCG. We can't initialize it at the 1526 point when MDL_context is created since THD represented through 1527 MDL_context_owner interface is not fully initialized at this point 1528 itself. 1529 */ 1530 m_rand_state = m_owner->get_rand_seed() & INT_MAX32; 1531 } 1532 m_rand_state = (m_rand_state * 1103515245 + 12345) & INT_MAX32; 1533 return m_rand_state; 1534 } 1535 1536 /** 1537 Within MDL subsystem this one is only used for DEBUG_SYNC. 1538 Do not use it to peek/poke into other parts of THD from MDL. 1539 @sa MDL_context_owner::get_thd(). 1540 */ get_thd()1541 THD *get_thd() const { return m_owner->get_thd(); } 1542 1543 public: 1544 /** 1545 If our request for a lock is scheduled, or aborted by the deadlock 1546 detector, the result is recorded in this class. 1547 */ 1548 MDL_wait m_wait; 1549 1550 private: 1551 /** 1552 Lists of all MDL tickets acquired by this connection. 1553 1554 Lists of MDL tickets: 1555 --------------------- 1556 The entire set of locks acquired by a connection can be separated 1557 in three subsets according to their duration: locks released at 1558 the end of statement, at the end of transaction and locks are 1559 released explicitly. 1560 1561 Statement and transactional locks are locks with automatic scope. 1562 They are accumulated in the course of a transaction, and released 1563 either at the end of uppermost statement (for statement locks) or 1564 on COMMIT, ROLLBACK or ROLLBACK TO SAVEPOINT (for transactional 1565 locks). They must not be (and never are) released manually, 1566 i.e. with release_lock() call. 1567 1568 Tickets with explicit duration are taken for locks that span 1569 multiple transactions or savepoints. 1570 These are: HANDLER SQL locks (HANDLER SQL is 1571 transaction-agnostic), LOCK TABLES locks (you can COMMIT/etc 1572 under LOCK TABLES, and the locked tables stay locked), user level 1573 locks (GET_LOCK()/RELEASE_LOCK() functions) and 1574 locks implementing "global read lock". 1575 1576 Statement/transactional locks are always prepended to the 1577 beginning of the appropriate list. In other words, they are 1578 stored in reverse temporal order. Thus, when we rollback to 1579 a savepoint, we start popping and releasing tickets from the 1580 front until we reach the last ticket acquired after the savepoint. 1581 1582 Locks with explicit duration are not stored in any 1583 particular order, and among each other can be split into 1584 four sets: 1585 - LOCK TABLES locks 1586 - User-level locks 1587 - HANDLER locks 1588 - GLOBAL READ LOCK locks 1589 */ 1590 MDL_ticket_store m_ticket_store; 1591 1592 MDL_context_owner *m_owner; 1593 /** 1594 true - if for this context we will break protocol and try to 1595 acquire table-level locks while having only S lock on 1596 some table. 1597 To avoid deadlocks which might occur during concurrent 1598 upgrade of SNRW lock on such object to X lock we have to 1599 abort waits for table-level locks for such connections. 1600 false - Otherwise. 1601 */ 1602 bool m_needs_thr_lock_abort; 1603 1604 /** 1605 Indicates that we need to use DEADLOCK_WEIGHT_DML deadlock 1606 weight for this context and ignore the deadlock weight provided 1607 by the MDL_wait_for_subgraph object which we are waiting for. 1608 1609 @note Can be changed only when there is a guarantee that this 1610 MDL_context is not waiting for a metadata lock or table 1611 definition entry. 1612 */ 1613 bool m_force_dml_deadlock_weight; 1614 1615 /** 1616 Read-write lock protecting m_waiting_for member. 1617 1618 @note The fact that this read-write lock prefers readers is 1619 important as deadlock detector won't work correctly 1620 otherwise. @sa Comment for MDL_lock::m_rwlock. 1621 */ 1622 mysql_prlock_t m_LOCK_waiting_for; 1623 /** 1624 Tell the deadlock detector what metadata lock or table 1625 definition cache entry this session is waiting for. 1626 In principle, this is redundant, as information can be found 1627 by inspecting waiting queues, but we'd very much like it to be 1628 readily available to the wait-for graph iterator. 1629 */ 1630 MDL_wait_for_subgraph *m_waiting_for; 1631 /** 1632 Thread's pins (a.k.a. hazard pointers) to be used by lock-free 1633 implementation of MDL_map::m_locks container. NULL if pins are 1634 not yet allocated from container's pinbox. 1635 */ 1636 LF_PINS *m_pins; 1637 /** 1638 State for pseudo random numbers generator (PRNG) which output 1639 is used to perform random dives into MDL_lock objects hash 1640 when searching for unused objects to free. 1641 */ 1642 uint m_rand_state; 1643 1644 private: 1645 MDL_ticket *find_ticket(MDL_request *mdl_req, enum_mdl_duration *duration); 1646 void release_locks_stored_before(enum_mdl_duration duration, 1647 MDL_ticket *sentinel); 1648 void release_lock(enum_mdl_duration duration, MDL_ticket *ticket); 1649 bool try_acquire_lock_impl(MDL_request *mdl_request, MDL_ticket **out_ticket); 1650 void materialize_fast_path_locks(); 1651 1652 friend bool mdl_unittest::test_drive_fix_pins(MDL_context *); 1653 bool fix_pins(); 1654 1655 public: 1656 void find_deadlock(); 1657 1658 bool visit_subgraph(MDL_wait_for_graph_visitor *dvisitor); 1659 1660 /** Inform the deadlock detector there is an edge in the wait-for graph. */ will_wait_for(MDL_wait_for_subgraph * waiting_for_arg)1661 void will_wait_for(MDL_wait_for_subgraph *waiting_for_arg) { 1662 /* 1663 Before starting wait for any resource we need to materialize 1664 all "fast path" tickets belonging to this thread. Otherwise 1665 locks acquired which are represented by these tickets won't 1666 be present in wait-for graph and could cause missed deadlocks. 1667 1668 It is OK for context which doesn't wait for any resource to 1669 have "fast path" tickets, as such context can't participate 1670 in any deadlock. 1671 */ 1672 materialize_fast_path_locks(); 1673 1674 mysql_prlock_wrlock(&m_LOCK_waiting_for); 1675 m_waiting_for = waiting_for_arg; 1676 mysql_prlock_unlock(&m_LOCK_waiting_for); 1677 } 1678 1679 /** Remove the wait-for edge from the graph after we're done waiting. */ done_waiting_for()1680 void done_waiting_for() { 1681 mysql_prlock_wrlock(&m_LOCK_waiting_for); 1682 m_waiting_for = nullptr; 1683 mysql_prlock_unlock(&m_LOCK_waiting_for); 1684 } lock_deadlock_victim()1685 void lock_deadlock_victim() { mysql_prlock_rdlock(&m_LOCK_waiting_for); } unlock_deadlock_victim()1686 void unlock_deadlock_victim() { mysql_prlock_unlock(&m_LOCK_waiting_for); } 1687 1688 private: 1689 MDL_context(const MDL_context &rhs); /* not implemented */ 1690 MDL_context &operator=(MDL_context &rhs); /* not implemented */ 1691 }; 1692 1693 void mdl_init(); 1694 void mdl_destroy(); 1695 1696 #ifndef DBUG_OFF 1697 extern mysql_mutex_t LOCK_open; 1698 #endif 1699 1700 /* 1701 Metadata locking subsystem tries not to grant more than 1702 max_write_lock_count high priority, strong locks successively, 1703 to avoid starving out weak, lower priority locks. 1704 */ 1705 extern ulong max_write_lock_count; 1706 1707 extern int32 mdl_locks_unused_locks_low_water; 1708 1709 /** 1710 Default value for threshold for number of unused MDL_lock objects after 1711 exceeding which we start considering freeing them. Only unit tests use 1712 different threshold value. 1713 */ 1714 const int32 MDL_LOCKS_UNUSED_LOCKS_LOW_WATER_DEFAULT = 1000; 1715 1716 /** 1717 Ratio of unused/total MDL_lock objects after exceeding which we 1718 start trying to free unused MDL_lock objects (assuming that 1719 mdl_locks_unused_locks_low_water threshold is passed as well). 1720 Note that this value should be high enough for our algorithm 1721 using random dives into hash to work well. 1722 */ 1723 const double MDL_LOCKS_UNUSED_LOCKS_MIN_RATIO = 0.25; 1724 1725 int32 mdl_get_unused_locks_count(); 1726 1727 /** 1728 Inspect if MDL_context is owned by any thread. 1729 */ 1730 class MDL_lock_is_owned_visitor : public MDL_context_visitor { 1731 public: MDL_lock_is_owned_visitor()1732 MDL_lock_is_owned_visitor() : m_exists(false) {} 1733 1734 /** 1735 Collects relevant information about the MDL lock owner. 1736 1737 This function is only called by MDL_context::find_lock_owner() when 1738 searching for MDL lock owners to collect extra information about the 1739 owner. As we only need to know that the MDL lock is owned, setting 1740 m_exists to true is enough. 1741 */ 1742 visit_context(const MDL_context * ctx MY_ATTRIBUTE ((unused)))1743 void visit_context(const MDL_context *ctx MY_ATTRIBUTE((unused))) override { 1744 m_exists = true; 1745 } 1746 1747 /** 1748 Returns if an owner for the MDL lock being inspected exists. 1749 1750 @return true when MDL lock is owned, false otherwise. 1751 */ 1752 exists()1753 bool exists() const { return m_exists; } 1754 1755 private: 1756 /* holds information about MDL being owned by any thread */ 1757 bool m_exists; 1758 }; 1759 1760 #endif 1761