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