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