1 #ifndef MDL_H
2 #define MDL_H
3 /* Copyright (c) 2009, 2021, Oracle and/or its affiliates.
4 
5    This program is free software; you can redistribute it and/or modify
6    it under the terms of the GNU General Public License, version 2.0,
7    as published by the Free Software Foundation.
8 
9    This program is also distributed with certain software (including
10    but not limited to OpenSSL) that is licensed under separate terms,
11    as designated in a particular file or component or in included license
12    documentation.  The authors of MySQL hereby grant you an additional
13    permission to link the program and your derivative works with the
14    separately licensed software that they have included with MySQL.
15 
16    This program is distributed in the hope that it will be useful,
17    but WITHOUT ANY WARRANTY; without even the implied warranty of
18    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19    GNU General Public License, version 2.0, for more details.
20 
21    You should have received a copy of the GNU General Public License
22    along with this program; if not, write to the Free Software Foundation,
23    51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */
24 
25 #include "sql_plist.h"
26 #include <my_sys.h>
27 #include <m_string.h>
28 #include <mysql_com.h>
29 
30 #include <algorithm>
31 
32 class THD;
33 
34 struct MDL_key;
35 class MDL_context;
36 class MDL_lock;
37 class MDL_ticket;
38 typedef struct st_lf_pins LF_PINS;
39 
40 /**
41   @def ENTER_COND(C, M, S, O)
42   Start a wait on a condition.
43   @param C the condition to wait on
44   @param M the associated mutex
45   @param S the new stage to enter
46   @param O the previous stage
47   @sa EXIT_COND().
48 */
49 #define ENTER_COND(C, M, S, O) enter_cond(C, M, S, O, __func__, __FILE__, __LINE__)
50 
51 /**
52   @def EXIT_COND(S)
53   End a wait on a condition
54   @param S the new stage to enter
55 */
56 #define EXIT_COND(S) exit_cond(S, __func__, __FILE__, __LINE__)
57 
58 /**
59    An interface to separate the MDL module from the THD, and the rest of the
60    server code.
61  */
62 
63 class MDL_context_owner
64 {
65 public:
~MDL_context_owner()66   virtual ~MDL_context_owner() {}
67 
68   /**
69     Enter a condition wait.
70     For @c enter_cond() / @c exit_cond() to work the mutex must be held before
71     @c enter_cond(); this mutex must then be released before @c exit_cond().
72     Usage must be: lock mutex; enter_cond(); your code; unlock mutex; exit_cond().
73     @param cond the condition to wait on
74     @param mutex the associated mutex
75     @param [in] stage the stage to enter, or NULL
76     @param [out] old_stage the previous stage, or NULL
77     @param src_function function name of the caller
78     @param src_file file name of the caller
79     @param src_line line number of the caller
80     @sa ENTER_COND(), THD::enter_cond()
81     @sa EXIT_COND(), THD::exit_cond()
82   */
83   virtual void enter_cond(mysql_cond_t *cond, mysql_mutex_t *mutex,
84                           const PSI_stage_info *stage, PSI_stage_info *old_stage,
85                           const char *src_function, const char *src_file,
86                           int src_line) = 0;
87 
88   /**
89     @def EXIT_COND(S)
90     End a wait on a condition
91     @param [in] stage the new stage to enter
92     @param src_function function name of the caller
93     @param src_file file name of the caller
94     @param src_line line number of the caller
95     @sa ENTER_COND(), THD::enter_cond()
96     @sa EXIT_COND(), THD::exit_cond()
97   */
98   virtual void exit_cond(const PSI_stage_info *stage,
99                          const char *src_function, const char *src_file,
100                          int src_line) = 0;
101   /**
102      Has the owner thread been killed?
103    */
104   virtual int  is_killed() = 0;
105 
106   /**
107     Does the owner still have connection to the client?
108   */
109   virtual bool is_connected() = 0;
110 
111   /**
112      Within MDL subsystem this one is only used for DEBUG_SYNC.
113      Do not use it to peek/poke into other parts of THD from MDL.
114      However it is OK to use this method in callbacks provided
115      by SQL-layer to MDL subsystem (since SQL-layer has full
116      access to THD anyway).
117    */
118   virtual THD* get_thd() = 0;
119 
120   /**
121      @see THD::notify_shared_lock()
122    */
123   virtual void notify_shared_lock(MDL_context_owner *in_use,
124                                   bool needs_thr_lock_abort) = 0;
125 
126   /**
127     Notify/get permission from interested storage engines before acquiring
128     exclusive lock for the key.
129 
130     The returned argument 'victimized' specify reason for lock
131     not granted. If 'true', lock was refused in an attempt to
132     resolve a possible MDL->GSL deadlock. Locking may then be retried.
133 
134     @return False if notification was successful and it is OK to acquire lock,
135             True if one of SEs asks to abort lock acquisition.
136   */
137   virtual bool notify_hton_pre_acquire_exclusive(const MDL_key *mdl_key,
138                                                  bool *victimized) = 0;
139   /**
140     Notify interested storage engines that we have just released exclusive
141     lock for the key.
142   */
143   virtual void notify_hton_post_release_exclusive(const MDL_key *mdl_key) = 0;
144 
145   /**
146     Get random seed specific to this THD to be used for initialization
147     of PRNG for the MDL_context.
148   */
149   virtual uint get_rand_seed() = 0;
150 };
151 
152 /**
153   Type of metadata lock request.
154 
155   @sa Comments for MDL_object_lock::can_grant_lock() and
156       MDL_scoped_lock::can_grant_lock() for details.
157 */
158 
159 enum enum_mdl_type {
160   /*
161     An intention exclusive metadata lock. Used only for scoped locks.
162     Owner of this type of lock can acquire upgradable exclusive locks on
163     individual objects.
164     Compatible with other IX locks, but is incompatible with scoped S and
165     X locks.
166   */
167   MDL_INTENTION_EXCLUSIVE= 0,
168   /*
169     A shared metadata lock.
170     To be used in cases when we are interested in object metadata only
171     and there is no intention to access object data (e.g. for stored
172     routines or during preparing prepared statements).
173     We also mis-use this type of lock for open HANDLERs, since lock
174     acquired by this statement has to be compatible with lock acquired
175     by LOCK TABLES ... WRITE statement, i.e. SNRW (We can't get by by
176     acquiring S lock at HANDLER ... OPEN time and upgrading it to SR
177     lock for HANDLER ... READ as it doesn't solve problem with need
178     to abort DML statements which wait on table level lock while having
179     open HANDLER in the same connection).
180     To avoid deadlock which may occur when SNRW lock is being upgraded to
181     X lock for table on which there is an active S lock which is owned by
182     thread which waits in its turn for table-level lock owned by thread
183     performing upgrade we have to use thr_abort_locks_for_thread()
184     facility in such situation.
185     This problem does not arise for locks on stored routines as we don't
186     use SNRW locks for them. It also does not arise when S locks are used
187     during PREPARE calls as table-level locks are not acquired in this
188     case.
189   */
190   MDL_SHARED,
191   /*
192     A high priority shared metadata lock.
193     Used for cases when there is no intention to access object data (i.e.
194     data in the table).
195     "High priority" means that, unlike other shared locks, it is granted
196     ignoring pending requests for exclusive locks. Intended for use in
197     cases when we only need to access metadata and not data, e.g. when
198     filling an INFORMATION_SCHEMA table.
199     Since SH lock is compatible with SNRW lock, the connection that
200     holds SH lock lock should not try to acquire any kind of table-level
201     or row-level lock, as this can lead to a deadlock. Moreover, after
202     acquiring SH lock, the connection should not wait for any other
203     resource, as it might cause starvation for X locks and a potential
204     deadlock during upgrade of SNW or SNRW to X lock (e.g. if the
205     upgrading connection holds the resource that is being waited for).
206   */
207   MDL_SHARED_HIGH_PRIO,
208   /*
209     A shared metadata lock for cases when there is an intention to read data
210     from table.
211     A connection holding this kind of lock can read table metadata and read
212     table data (after acquiring appropriate table and row-level locks).
213     This means that one can only acquire TL_READ, TL_READ_NO_INSERT, and
214     similar table-level locks on table if one holds SR MDL lock on it.
215     To be used for tables in SELECTs, subqueries, and LOCK TABLE ...  READ
216     statements.
217   */
218   MDL_SHARED_READ,
219   /*
220     A shared metadata lock for cases when there is an intention to modify
221     (and not just read) data in the table.
222     A connection holding SW lock can read table metadata and modify or read
223     table data (after acquiring appropriate table and row-level locks).
224     To be used for tables to be modified by INSERT, UPDATE, DELETE
225     statements, but not LOCK TABLE ... WRITE or DDL). Also taken by
226     SELECT ... FOR UPDATE.
227   */
228   MDL_SHARED_WRITE,
229   /*
230     A version of MDL_SHARED_WRITE lock which has lower priority than
231     MDL_SHARED_READ_ONLY locks. Used by DML statements modifying
232     tables and using the LOW_PRIORITY clause.
233   */
234   MDL_SHARED_WRITE_LOW_PRIO,
235   /*
236     An upgradable shared metadata lock which allows concurrent updates and
237     reads of table data.
238     A connection holding this kind of lock can read table metadata and read
239     table data. It should not modify data as this lock is compatible with
240     SRO locks.
241     Can be upgraded to SNW, SNRW and X locks. Once SU lock is upgraded to X
242     or SNRW lock data modification can happen freely.
243     To be used for the first phase of ALTER TABLE.
244   */
245   MDL_SHARED_UPGRADABLE,
246   /*
247     A shared metadata lock for cases when we need to read data from table
248     and block all concurrent modifications to it (for both data and metadata).
249     Used by LOCK TABLES READ statement.
250   */
251   MDL_SHARED_READ_ONLY,
252   /*
253     An upgradable shared metadata lock which blocks all attempts to update
254     table data, allowing reads.
255     A connection holding this kind of lock can read table metadata and read
256     table data.
257     Can be upgraded to X metadata lock.
258     Note, that since this type of lock is not compatible with SNRW or SW
259     lock types, acquiring appropriate engine-level locks for reading
260     (TL_READ* for MyISAM, shared row locks in InnoDB) should be
261     contention-free.
262     To be used for the first phase of ALTER TABLE, when copying data between
263     tables, to allow concurrent SELECTs from the table, but not UPDATEs.
264   */
265   MDL_SHARED_NO_WRITE,
266   /*
267     An upgradable shared metadata lock which allows other connections
268     to access table metadata, but not data.
269     It blocks all attempts to read or update table data, while allowing
270     INFORMATION_SCHEMA and SHOW queries.
271     A connection holding this kind of lock can read table metadata modify and
272     read table data.
273     Can be upgraded to X metadata lock.
274     To be used for LOCK TABLES WRITE statement.
275     Not compatible with any other lock type except S and SH.
276   */
277   MDL_SHARED_NO_READ_WRITE,
278   /*
279     An exclusive metadata lock.
280     A connection holding this lock can modify both table's metadata and data.
281     No other type of metadata lock can be granted while this lock is held.
282     To be used for CREATE/DROP/RENAME TABLE statements and for execution of
283     certain phases of other DDL statements.
284   */
285   MDL_EXCLUSIVE,
286   /* This should be the last !!! */
287   MDL_TYPE_END};
288 
289 
290 /** Duration of metadata lock. */
291 
292 enum enum_mdl_duration {
293   /**
294     Locks with statement duration are automatically released at the end
295     of statement or transaction.
296   */
297   MDL_STATEMENT= 0,
298   /**
299     Locks with transaction duration are automatically released at the end
300     of transaction.
301   */
302   MDL_TRANSACTION,
303   /**
304     Locks with explicit duration survive the end of statement and transaction.
305     They have to be released explicitly by calling MDL_context::release_lock().
306   */
307   MDL_EXPLICIT,
308   /* This should be the last ! */
309   MDL_DURATION_END };
310 
311 
312 /** Maximal length of key for metadata locking subsystem. */
313 #define MAX_MDLKEY_LENGTH (1 + NAME_LEN + 1 + NAME_LEN + 1)
314 
315 
316 /**
317   Metadata lock object key.
318 
319   A lock is requested or granted based on a fully qualified name and type.
320   E.g. They key for a table consists of <0 (=table)>+<database>+<table name>.
321   Elsewhere in the comments this triple will be referred to simply as "key"
322   or "name".
323 */
324 
325 struct MDL_key
326 {
327 public:
328 #ifdef HAVE_PSI_INTERFACE
329   static void init_psi_keys();
330 #endif
331 
332   /**
333     Object namespaces.
334     Sic: when adding a new member to this enum make sure to
335     update m_namespace_to_wait_state_name array in mdl.cc!
336 
337     Different types of objects exist in different namespaces
338      - GLOBAL is used for the global read lock.
339      - TABLESPACE is for tablespaces.
340      - SCHEMA is for schemas (aka databases).
341      - TABLE is for tables and views.
342      - FUNCTION is for stored functions.
343      - PROCEDURE is for stored procedures.
344      - TRIGGER is for triggers.
345      - EVENT is for event scheduler events.
346      - COMMIT is for enabling the global read lock to block commits.
347      - USER_LEVEL_LOCK is for user-level locks.
348      - LOCKING_SERVICE is for the name plugin RW-lock service
349     Note that although there isn't metadata locking on triggers,
350     it's necessary to have a separate namespace for them since
351     MDL_key is also used outside of the MDL subsystem.
352     Also note that requests waiting for user-level locks get special
353     treatment - waiting is aborted if connection to client is lost.
354   */
355   enum enum_mdl_namespace { GLOBAL=0,
356                             TABLESPACE,
357                             SCHEMA,
358                             TABLE,
359                             FUNCTION,
360                             PROCEDURE,
361                             TRIGGER,
362                             EVENT,
363                             COMMIT,
364                             USER_LEVEL_LOCK,
365                             LOCKING_SERVICE,
366                             BACKUP,
367                             BINLOG,
368                             /* This should be the last ! */
369                             NAMESPACE_END };
370 
ptrMDL_key371   const uchar *ptr() const { return (uchar*) m_ptr; }
lengthMDL_key372   uint length() const { return m_length; }
373 
db_nameMDL_key374   const char *db_name() const { return m_ptr + 1; }
db_name_lengthMDL_key375   uint db_name_length() const { return m_db_name_length; }
376 
nameMDL_key377   const char *name() const { return m_ptr + m_db_name_length + 2; }
name_lengthMDL_key378   uint name_length() const { return m_length - m_db_name_length - 3; }
379 
mdl_namespaceMDL_key380   enum_mdl_namespace mdl_namespace() const
381   { return (enum_mdl_namespace)(m_ptr[0]); }
382 
383   /**
384     Construct a metadata lock key from a triplet (mdl_namespace,
385     database and name).
386 
387     @remark The key for a table is <mdl_namespace>+<database name>+<table name>
388 
389     @param  mdl_namespace Id of namespace of object to be locked
390     @param  db            Name of database to which the object belongs
391     @param  name          Name of of the object
392   */
mdl_key_initMDL_key393   void mdl_key_init(enum_mdl_namespace mdl_namespace,
394                     const char *db, const char *name)
395   {
396     m_ptr[0]= (char) mdl_namespace;
397     /*
398       It is responsibility of caller to ensure that db and object names
399       are not longer than NAME_LEN. Still we play safe and try to avoid
400       buffer overruns.
401     */
402     assert(strlen(db) <= NAME_LEN && strlen(name) <= NAME_LEN);
403     m_db_name_length= static_cast<uint16>(strmake(m_ptr + 1, db, NAME_LEN) -
404                                           m_ptr - 1);
405     m_length= static_cast<uint16>(strmake(m_ptr + m_db_name_length + 2, name,
406                                           NAME_LEN) - m_ptr + 1);
407   }
mdl_key_initMDL_key408   void mdl_key_init(const MDL_key *rhs)
409   {
410     memcpy(m_ptr, rhs->m_ptr, rhs->m_length);
411     m_length= rhs->m_length;
412     m_db_name_length= rhs->m_db_name_length;
413   }
resetMDL_key414   void reset()
415   {
416     m_ptr[0]= NAMESPACE_END;
417     m_db_name_length= 0;
418     m_length= 0;
419   }
is_equalMDL_key420   bool is_equal(const MDL_key *rhs) const
421   {
422     return (m_length == rhs->m_length &&
423             memcmp(m_ptr, rhs->m_ptr, m_length) == 0);
424   }
425   /**
426     Compare two MDL keys lexicographically.
427   */
cmpMDL_key428   int cmp(const MDL_key *rhs) const
429   {
430     /*
431       The key buffer is always '\0'-terminated. Since key
432       character set is utf-8, we can safely assume that no
433       character starts with a zero byte.
434     */
435     return memcmp(m_ptr, rhs->m_ptr, std::min(m_length, rhs->m_length));
436   }
437 
MDL_keyMDL_key438   MDL_key(const MDL_key *rhs)
439   {
440     mdl_key_init(rhs);
441   }
MDL_keyMDL_key442   MDL_key(enum_mdl_namespace namespace_arg,
443           const char *db_arg, const char *name_arg)
444   {
445     mdl_key_init(namespace_arg, db_arg, name_arg);
446   }
MDL_keyMDL_key447   MDL_key() {} /* To use when part of MDL_request. */
448 
449   /**
450     Get thread state name to be used in case when we have to
451     wait on resource identified by key.
452   */
get_wait_state_nameMDL_key453   const PSI_stage_info * get_wait_state_name() const
454   {
455     return & m_namespace_to_wait_state_name[(int)mdl_namespace()];
456   }
457 
458 private:
459   uint16 m_length;
460   uint16 m_db_name_length;
461   char m_ptr[MAX_MDLKEY_LENGTH];
462   static PSI_stage_info m_namespace_to_wait_state_name[NAMESPACE_END];
463 private:
464   MDL_key(const MDL_key &);                     /* not implemented */
465   MDL_key &operator=(const MDL_key &);          /* not implemented */
466 };
467 
468 
469 /**
470   A pending metadata lock request.
471 
472   A lock request and a granted metadata lock are represented by
473   different classes because they have different allocation
474   sites and hence different lifetimes. The allocation of lock requests is
475   controlled from outside of the MDL subsystem, while allocation of granted
476   locks (tickets) is controlled within the MDL subsystem.
477 
478   MDL_request is a C structure, you don't need to call a constructor
479   or destructor for it.
480 */
481 
482 class MDL_request
483 {
484 public:
485   /** Type of metadata lock. */
486   enum          enum_mdl_type type;
487   /** Duration for requested lock. */
488   enum enum_mdl_duration duration;
489 
490   /**
491     Pointers for participating in the list of lock requests for this context.
492   */
493   MDL_request *next_in_list;
494   MDL_request **prev_in_list;
495   /**
496     Pointer to the lock ticket object for this lock request.
497     Valid only if this lock request is satisfied.
498   */
499   MDL_ticket *ticket;
500 
501   /** A lock is requested based on a fully qualified name and type. */
502   MDL_key key;
503 
504   const char *m_src_file;
505   uint m_src_line;
506 
507 public:
new(size_t size,MEM_ROOT * mem_root)508   static void *operator new(size_t size, MEM_ROOT *mem_root) throw ()
509   { return alloc_root(mem_root, size); }
delete(void * ptr,MEM_ROOT * mem_root)510   static void operator delete(void *ptr, MEM_ROOT *mem_root) {}
511 
512   void init_with_source(MDL_key::enum_mdl_namespace namespace_arg,
513             const char *db_arg, const char *name_arg,
514             enum_mdl_type mdl_type_arg,
515             enum_mdl_duration mdl_duration_arg,
516             const char *src_file, uint src_line);
517   void init_by_key_with_source(const MDL_key *key_arg, enum_mdl_type mdl_type_arg,
518             enum_mdl_duration mdl_duration_arg,
519             const char *src_file, uint src_line);
520   /** Set type of lock request. Can be only applied to pending locks. */
set_type(enum_mdl_type type_arg)521   inline void set_type(enum_mdl_type type_arg)
522   {
523     assert(ticket == NULL);
524     type= type_arg;
525   }
526 
527   /**
528     Is this a request for a lock which allow data to be updated?
529 
530     @note This method returns true for MDL_SHARED_UPGRADABLE type of
531           lock. Even though this type of lock doesn't allow updates
532           it will always be upgraded to one that does.
533   */
is_write_lock_request()534   bool is_write_lock_request() const
535   {
536     return (type >= MDL_SHARED_WRITE &&
537             type != MDL_SHARED_READ_ONLY);
538   }
539 
540   /** Is this a request for a strong, DDL/LOCK TABLES-type, of lock? */
is_ddl_or_lock_tables_lock_request()541   bool is_ddl_or_lock_tables_lock_request() const
542   {
543     return type >= MDL_SHARED_UPGRADABLE;
544   }
545 
546   /*
547     This is to work around the ugliness of TABLE_LIST
548     compiler-generated assignment operator. It is currently used
549     in several places to quickly copy "most" of the members of the
550     table list. These places currently never assume that the mdl
551     request is carried over to the new TABLE_LIST, or shared
552     between lists.
553 
554     This method does not initialize the instance being assigned!
555     Use of init() for initialization after this assignment operator
556     is mandatory. Can only be used before the request has been
557     granted.
558   */
559   MDL_request& operator=(const MDL_request &rhs)
560   {
561     ticket= NULL;
562     /* Do nothing, in particular, don't try to copy the key. */
563     return *this;
564   }
565   /* Another piece of ugliness for TABLE_LIST constructor */
MDL_request()566   MDL_request() {}
567 
MDL_request(const MDL_request * rhs)568   MDL_request(const MDL_request *rhs)
569     :type(rhs->type),
570     duration(rhs->duration),
571     ticket(NULL),
572     key(&rhs->key)
573   {}
574 };
575 
576 #define MDL_REQUEST_INIT(R, P1, P2, P3, P4, P5) \
577   (*R).init_with_source(P1, P2, P3, P4, P5, __FILE__, __LINE__)
578 
579 #define MDL_REQUEST_INIT_BY_KEY(R, P1, P2, P3) \
580   (*R).init_by_key_with_source(P1, P2, P3, __FILE__, __LINE__)
581 
582 
583 /**
584   An abstract class for inspection of a connected
585   subgraph of the wait-for graph.
586 */
587 
588 class MDL_wait_for_graph_visitor
589 {
590 public:
591   virtual bool enter_node(MDL_context *node) = 0;
592   virtual void leave_node(MDL_context *node) = 0;
593 
594   virtual bool inspect_edge(MDL_context *dest) = 0;
595   virtual ~MDL_wait_for_graph_visitor();
MDL_wait_for_graph_visitor()596   MDL_wait_for_graph_visitor() :m_lock_open_count(0) {}
597 public:
598   /**
599    XXX, hack: During deadlock search, we may need to
600    inspect TABLE_SHAREs and acquire LOCK_open. Since
601    LOCK_open is not a recursive mutex, count here how many
602    times we "took" it (but only take and release once).
603    Not using a native recursive mutex or rwlock in 5.5 for
604    LOCK_open since it has significant performance impacts.
605   */
606   uint m_lock_open_count;
607 };
608 
609 /**
610   Abstract class representing an edge in the waiters graph
611   to be traversed by deadlock detection algorithm.
612 */
613 
614 class MDL_wait_for_subgraph
615 {
616 public:
617   virtual ~MDL_wait_for_subgraph();
618 
619   /**
620     Accept a wait-for graph visitor to inspect the node
621     this edge is leading to.
622   */
623   virtual bool accept_visitor(MDL_wait_for_graph_visitor *gvisitor) = 0;
624 
625   static const uint DEADLOCK_WEIGHT_DML= 0;
626   static const uint DEADLOCK_WEIGHT_ULL= 50;
627   static const uint DEADLOCK_WEIGHT_DDL= 100;
628 
629   /* A helper used to determine which lock request should be aborted. */
630   virtual uint get_deadlock_weight() const = 0;
631 };
632 
633 
634 /**
635   A granted metadata lock.
636 
637   @warning MDL_ticket members are private to the MDL subsystem.
638 
639   @note Multiple shared locks on a same object are represented by a
640         single ticket. The same does not apply for other lock types.
641 
642   @note There are two groups of MDL_ticket members:
643         - "Externally accessible". These members can be accessed from
644           threads/contexts different than ticket owner in cases when
645           ticket participates in some list of granted or waiting tickets
646           for a lock. Therefore one should change these members before
647           including then to waiting/granted lists or while holding lock
648           protecting those lists.
649         - "Context private". Such members are private to thread/context
650           owning this ticket. I.e. they should not be accessed from other
651           threads/contexts.
652 */
653 
654 class MDL_ticket : public MDL_wait_for_subgraph
655 {
656 public:
657   /**
658     Pointers for participating in the list of lock requests for this context.
659     Context private.
660   */
661   MDL_ticket *next_in_context;
662   MDL_ticket **prev_in_context;
663   /**
664     Pointers for participating in the list of satisfied/pending requests
665     for the lock. Externally accessible.
666   */
667   MDL_ticket *next_in_lock;
668   MDL_ticket **prev_in_lock;
669 public:
670   bool has_pending_conflicting_lock() const;
671 
get_ctx()672   MDL_context *get_ctx() const { return m_ctx; }
is_upgradable_or_exclusive()673   bool is_upgradable_or_exclusive() const
674   {
675     return m_type == MDL_SHARED_UPGRADABLE ||
676            m_type == MDL_SHARED_NO_WRITE ||
677            m_type == MDL_SHARED_NO_READ_WRITE ||
678            m_type == MDL_EXCLUSIVE;
679   }
get_type()680   enum_mdl_type get_type() const { return m_type; }
get_lock()681   MDL_lock *get_lock() const { return m_lock; }
682   const MDL_key *get_key() const;
683   void downgrade_lock(enum_mdl_type type);
684 
685   bool has_stronger_or_equal_type(enum_mdl_type type) const;
686 
687   bool is_incompatible_when_granted(enum_mdl_type type) const;
688   bool is_incompatible_when_waiting(enum_mdl_type type) const;
689 
690   /** Implement MDL_wait_for_subgraph interface. */
691   virtual bool accept_visitor(MDL_wait_for_graph_visitor *dvisitor);
692   virtual uint get_deadlock_weight() const;
693 
694 public:
695   /**
696     Status of lock request represented by the ticket as reflected in P_S.
697   */
698   enum enum_psi_status { PENDING = 0, GRANTED,
699                          PRE_ACQUIRE_NOTIFY, POST_RELEASE_NOTIFY };
700 
701 private:
702   friend class MDL_context;
703 
MDL_ticket(MDL_context * ctx_arg,enum_mdl_type type_arg,enum_mdl_duration duration_arg)704   MDL_ticket(MDL_context *ctx_arg, enum_mdl_type type_arg
705 #ifndef NDEBUG
706              , enum_mdl_duration duration_arg
707 #endif
708             )
709    : m_type(type_arg),
710 #ifndef NDEBUG
711      m_duration(duration_arg),
712 #endif
713      m_ctx(ctx_arg),
714      m_lock(NULL),
715      m_is_fast_path(false),
716      m_hton_notified(false),
717      m_psi(NULL)
718   {}
719 
~MDL_ticket()720   virtual ~MDL_ticket()
721   {
722     assert(m_psi == NULL);
723   }
724 
725   static MDL_ticket *create(MDL_context *ctx_arg, enum_mdl_type type_arg
726 #ifndef NDEBUG
727                             , enum_mdl_duration duration_arg
728 #endif
729                             );
730   static void destroy(MDL_ticket *ticket);
731 private:
732   /** Type of metadata lock. Externally accessible. */
733   enum enum_mdl_type m_type;
734 #ifndef NDEBUG
735   /**
736     Duration of lock represented by this ticket.
737     Context private. Debug-only.
738   */
739   enum_mdl_duration m_duration;
740 #endif
741   /**
742     Context of the owner of the metadata lock ticket. Externally accessible.
743   */
744   MDL_context *m_ctx;
745 
746   /**
747     Pointer to the lock object for this lock ticket. Externally accessible.
748   */
749   MDL_lock *m_lock;
750 
751   /**
752     Indicates that ticket corresponds to lock acquired using "fast path"
753     algorithm. Particularly this means that it was not included into
754     MDL_lock::m_granted bitmap/list and instead is accounted for by
755     MDL_lock::m_fast_path_locks_granted_counter
756   */
757   bool m_is_fast_path;
758 
759   /**
760     Indicates that ticket corresponds to lock request which required
761     storage engine notification during its acquisition and requires
762     storage engine notification after its release.
763   */
764   bool m_hton_notified;
765 
766   PSI_metadata_lock *m_psi;
767 
768 private:
769   MDL_ticket(const MDL_ticket &);               /* not implemented */
770   MDL_ticket &operator=(const MDL_ticket &);    /* not implemented */
771 };
772 
773 
774 /**
775   Savepoint for MDL context.
776 
777   Doesn't include metadata locks with explicit duration as
778   they are not released during rollback to savepoint.
779 */
780 
781 class MDL_savepoint
782 {
783 public:
MDL_savepoint()784   MDL_savepoint() {};
785 
786 private:
MDL_savepoint(MDL_ticket * stmt_ticket,MDL_ticket * trans_ticket)787   MDL_savepoint(MDL_ticket *stmt_ticket, MDL_ticket *trans_ticket)
788     : m_stmt_ticket(stmt_ticket), m_trans_ticket(trans_ticket)
789   {}
790 
791   friend class MDL_context;
792 
793 private:
794   /**
795     Pointer to last lock with statement duration which was taken
796     before creation of savepoint.
797   */
798   MDL_ticket *m_stmt_ticket;
799   /**
800     Pointer to last lock with transaction duration which was taken
801     before creation of savepoint.
802   */
803   MDL_ticket *m_trans_ticket;
804 };
805 
806 
807 /**
808   A reliable way to wait on an MDL lock.
809 */
810 
811 class MDL_wait
812 {
813 public:
814   MDL_wait();
815   ~MDL_wait();
816 
817   enum enum_wait_status { EMPTY = 0, GRANTED, VICTIM, TIMEOUT, KILLED };
818 
819   bool set_status(enum_wait_status result_arg);
820   enum_wait_status get_status();
821   void reset_status();
822   enum_wait_status timed_wait(MDL_context_owner *owner,
823                               struct timespec *abs_timeout,
824                               bool signal_timeout,
825                               const PSI_stage_info *wait_state_name);
826 private:
827 
828   /**
829     Condvar which is used for waiting until this context's pending
830     request can be satisfied or this thread has to perform actions
831     to resolve a potential deadlock (we subscribe to such
832     notification by adding a ticket corresponding to the request
833     to an appropriate queue of waiters).
834   */
835   mysql_mutex_t m_LOCK_wait_status;
836   mysql_cond_t m_COND_wait_status;
837   enum_wait_status m_wait_status;
838 };
839 
840 
841 /**
842   Base class to find out if the lock represented by a given ticket
843   should be released. Users of release_locks() need to subclass
844   this and specify an implementation of release(). Only for locks
845   with explicit duration.
846 */
847 
848 class MDL_release_locks_visitor
849 {
850 public:
~MDL_release_locks_visitor()851   virtual ~MDL_release_locks_visitor() {}
852   /**
853     Check if the given ticket represents a lock that should be released.
854 
855     @retval true if the lock should be released, false otherwise.
856   */
857   virtual bool release(MDL_ticket *ticket) = 0;
858 };
859 
860 
861 /**
862   Abstract visitor class for inspecting MDL_context.
863 */
864 
865 class MDL_context_visitor
866 {
867 public:
~MDL_context_visitor()868   virtual ~MDL_context_visitor() {}
869   virtual void visit_context(const MDL_context *ctx) = 0;
870 };
871 
872 
873 typedef I_P_List<MDL_request, I_P_List_adapter<MDL_request,
874                  &MDL_request::next_in_list,
875                  &MDL_request::prev_in_list>,
876                  I_P_List_counter>
877         MDL_request_list;
878 
879 /**
880   Context of the owner of metadata locks. I.e. each server
881   connection has such a context.
882 */
883 
884 class MDL_context
885 {
886 public:
887   typedef I_P_List<MDL_ticket,
888                    I_P_List_adapter<MDL_ticket,
889                                     &MDL_ticket::next_in_context,
890                                     &MDL_ticket::prev_in_context> >
891           Ticket_list;
892 
893   typedef Ticket_list::Iterator Ticket_iterator;
894 
895   MDL_context();
896   void destroy();
897 
898   bool try_acquire_lock(MDL_request *mdl_request);
899   bool acquire_lock(MDL_request *mdl_request, ulong lock_wait_timeout);
900   bool acquire_locks(MDL_request_list *requests, ulong lock_wait_timeout);
901   bool upgrade_shared_lock(MDL_ticket *mdl_ticket,
902                            enum_mdl_type new_type,
903                            ulong lock_wait_timeout);
904 
905   bool clone_ticket(MDL_request *mdl_request);
906 
907   void release_all_locks_for_name(MDL_ticket *ticket);
908   void release_locks(MDL_release_locks_visitor *visitor);
909   void release_lock(MDL_ticket *ticket);
910 
911   bool owns_equal_or_stronger_lock(MDL_key::enum_mdl_namespace mdl_namespace,
912                                    const char *db, const char *name,
913                                    enum_mdl_type mdl_type);
914 
915   bool find_lock_owner(const MDL_key *mdl_key, MDL_context_visitor *visitor);
916 
917   bool has_lock(const MDL_savepoint &mdl_savepoint, MDL_ticket *mdl_ticket);
918 
has_locks()919   inline bool has_locks() const
920   {
921     return !(m_tickets[MDL_STATEMENT].is_empty() &&
922              m_tickets[MDL_TRANSACTION].is_empty() &&
923              m_tickets[MDL_EXPLICIT].is_empty());
924   }
925 
926   bool has_locks(MDL_key::enum_mdl_namespace mdl_namespace) const;
927 
928   bool has_locks_waited_for() const;
929 
mdl_savepoint()930   MDL_savepoint mdl_savepoint()
931   {
932     return MDL_savepoint(m_tickets[MDL_STATEMENT].front(),
933                          m_tickets[MDL_TRANSACTION].front());
934   }
935 
936   void set_explicit_duration_for_all_locks();
937   void set_transaction_duration_for_all_locks();
938   void set_lock_duration(MDL_ticket *mdl_ticket, enum_mdl_duration duration);
939 
940   void release_statement_locks();
941   void release_transactional_locks();
942   void rollback_to_savepoint(const MDL_savepoint &mdl_savepoint);
943 
get_owner()944   MDL_context_owner *get_owner() const { return m_owner; }
945 
946   /** @pre Only valid if we started waiting for lock. */
get_deadlock_weight()947   inline uint get_deadlock_weight() const
948   {
949     return m_force_dml_deadlock_weight ?
950            MDL_wait_for_subgraph::DEADLOCK_WEIGHT_DML :
951            m_waiting_for->get_deadlock_weight();
952   }
953 
init(MDL_context_owner * arg)954   void init(MDL_context_owner *arg) { m_owner= arg; }
955 
set_needs_thr_lock_abort(bool needs_thr_lock_abort)956   void set_needs_thr_lock_abort(bool needs_thr_lock_abort)
957   {
958     /*
959       @note In theory, this member should be modified under protection
960             of some lock since it can be accessed from different threads.
961             In practice, this is not necessary as code which reads this
962             value and so might miss the fact that value was changed will
963             always re-try reading it after small timeout and therefore
964             will see the new value eventually.
965     */
966     m_needs_thr_lock_abort= needs_thr_lock_abort;
967 
968     if (m_needs_thr_lock_abort)
969     {
970       /*
971         For MDL_object_lock::notify_conflicting_locks() to work properly
972         all context requiring thr_lock aborts should not have any "fast
973         path" locks.
974       */
975       materialize_fast_path_locks();
976     }
977   }
get_needs_thr_lock_abort()978   bool get_needs_thr_lock_abort() const
979   {
980     return m_needs_thr_lock_abort;
981   }
982 
set_force_dml_deadlock_weight(bool force_dml_deadlock_weight)983   void set_force_dml_deadlock_weight(bool force_dml_deadlock_weight)
984   {
985     m_force_dml_deadlock_weight= force_dml_deadlock_weight;
986   }
987 
988   /**
989     Get pseudo random value in [0 .. 2^31-1] range.
990 
991     @note We use Linear Congruential Generator with venerable constant
992           parameters for this.
993           It is known to have problems with its lower bits are not being
994           very random so probably is not good enough for generic use.
995           However, we only use it to do random dives into MDL_lock objects
996           hash when searching for unused objects to be freed, and for this
997           purposes it is sufficient.
998           We rely on values of "get_random() % 2^k" expression having "2^k"
999           as a period to ensure that random dives eventually cover all hash
1000           (the former can be proven to be true). This also means that there
1001           is no bias towards any specific objects to be expelled (as hash
1002           values don't repeat), which is nice for performance.
1003   */
get_random()1004   uint get_random()
1005   {
1006     if (m_rand_state > INT_MAX32)
1007     {
1008       /*
1009         Perform lazy initialization of LCG. We can't initialize it at the
1010         point when MDL_context is created since THD represented through
1011         MDL_context_owner interface is not fully initialized at this point
1012         itself.
1013       */
1014       m_rand_state= m_owner->get_rand_seed() & INT_MAX32;
1015     }
1016     m_rand_state= (m_rand_state * 1103515245 + 12345) & INT_MAX32;
1017     return m_rand_state;
1018   }
1019 
1020   /**
1021     Within MDL subsystem this one is only used for DEBUG_SYNC.
1022     Do not use it to peek/poke into other parts of THD from MDL.
1023     @sa MDL_context_owner::get_thd().
1024   */
get_thd()1025   THD *get_thd() const { return m_owner->get_thd(); }
1026 
1027 public:
1028   /**
1029     If our request for a lock is scheduled, or aborted by the deadlock
1030     detector, the result is recorded in this class.
1031   */
1032   MDL_wait m_wait;
1033 private:
1034   /**
1035     Lists of all MDL tickets acquired by this connection.
1036 
1037     Lists of MDL tickets:
1038     ---------------------
1039     The entire set of locks acquired by a connection can be separated
1040     in three subsets according to their duration: locks released at
1041     the end of statement, at the end of transaction and locks are
1042     released explicitly.
1043 
1044     Statement and transactional locks are locks with automatic scope.
1045     They are accumulated in the course of a transaction, and released
1046     either at the end of uppermost statement (for statement locks) or
1047     on COMMIT, ROLLBACK or ROLLBACK TO SAVEPOINT (for transactional
1048     locks). They must not be (and never are) released manually,
1049     i.e. with release_lock() call.
1050 
1051     Tickets with explicit duration are taken for locks that span
1052     multiple transactions or savepoints.
1053     These are: HANDLER SQL locks (HANDLER SQL is
1054     transaction-agnostic), LOCK TABLES locks (you can COMMIT/etc
1055     under LOCK TABLES, and the locked tables stay locked), user level
1056     locks (GET_LOCK()/RELEASE_LOCK() functions) and
1057     locks implementing "global read lock".
1058 
1059     Statement/transactional locks are always prepended to the
1060     beginning of the appropriate list. In other words, they are
1061     stored in reverse temporal order. Thus, when we rollback to
1062     a savepoint, we start popping and releasing tickets from the
1063     front until we reach the last ticket acquired after the savepoint.
1064 
1065     Locks with explicit duration are not stored in any
1066     particular order, and among each other can be split into
1067     four sets:
1068     - LOCK TABLES locks
1069     - User-level locks
1070     - HANDLER locks
1071     - GLOBAL READ LOCK locks
1072   */
1073   Ticket_list m_tickets[MDL_DURATION_END];
1074   MDL_context_owner *m_owner;
1075   /**
1076     TRUE -  if for this context we will break protocol and try to
1077             acquire table-level locks while having only S lock on
1078             some table.
1079             To avoid deadlocks which might occur during concurrent
1080             upgrade of SNRW lock on such object to X lock we have to
1081             abort waits for table-level locks for such connections.
1082     FALSE - Otherwise.
1083   */
1084   bool m_needs_thr_lock_abort;
1085 
1086   /**
1087     Indicates that we need to use DEADLOCK_WEIGHT_DML deadlock
1088     weight for this context and ignore the deadlock weight provided
1089     by the MDL_wait_for_subgraph object which we are waiting for.
1090 
1091     @note Can be changed only when there is a guarantee that this
1092           MDL_context is not waiting for a metadata lock or table
1093           definition entry.
1094   */
1095   bool m_force_dml_deadlock_weight;
1096 
1097   /**
1098     Read-write lock protecting m_waiting_for member.
1099 
1100     @note The fact that this read-write lock prefers readers is
1101           important as deadlock detector won't work correctly
1102           otherwise. @sa Comment for MDL_lock::m_rwlock.
1103   */
1104   mysql_prlock_t m_LOCK_waiting_for;
1105   /**
1106     Tell the deadlock detector what metadata lock or table
1107     definition cache entry this session is waiting for.
1108     In principle, this is redundant, as information can be found
1109     by inspecting waiting queues, but we'd very much like it to be
1110     readily available to the wait-for graph iterator.
1111    */
1112   MDL_wait_for_subgraph *m_waiting_for;
1113   /**
1114     Thread's pins (a.k.a. hazard pointers) to be used by lock-free
1115     implementation of MDL_map::m_locks container. NULL if pins are
1116     not yet allocated from container's pinbox.
1117   */
1118   LF_PINS *m_pins;
1119   /**
1120     State for pseudo random numbers generator (PRNG) which output
1121     is used to perform random dives into MDL_lock objects hash
1122     when searching for unused objects to free.
1123   */
1124   uint m_rand_state;
1125 
1126 private:
1127   MDL_ticket *find_ticket(MDL_request *mdl_req,
1128                           enum_mdl_duration *duration);
1129   void release_locks_stored_before(enum_mdl_duration duration, MDL_ticket *sentinel);
1130   void release_lock(enum_mdl_duration duration, MDL_ticket *ticket);
1131   bool try_acquire_lock_impl(MDL_request *mdl_request,
1132                              MDL_ticket **out_ticket);
1133   void materialize_fast_path_locks();
1134   inline bool fix_pins();
1135 
1136 public:
1137   void find_deadlock();
1138 
1139   bool visit_subgraph(MDL_wait_for_graph_visitor *dvisitor);
1140 
1141   /** Inform the deadlock detector there is an edge in the wait-for graph. */
will_wait_for(MDL_wait_for_subgraph * waiting_for_arg)1142   void will_wait_for(MDL_wait_for_subgraph *waiting_for_arg)
1143   {
1144     /*
1145       Before starting wait for any resource we need to materialize
1146       all "fast path" tickets belonging to this thread. Otherwise
1147       locks acquired which are represented by these tickets won't
1148       be present in wait-for graph and could cause missed deadlocks.
1149 
1150       It is OK for context which doesn't wait for any resource to
1151       have "fast path" tickets, as such context can't participate
1152       in any deadlock.
1153     */
1154     materialize_fast_path_locks();
1155 
1156     mysql_prlock_wrlock(&m_LOCK_waiting_for);
1157     m_waiting_for=  waiting_for_arg;
1158     mysql_prlock_unlock(&m_LOCK_waiting_for);
1159   }
1160 
1161   /** Remove the wait-for edge from the graph after we're done waiting. */
done_waiting_for()1162   void done_waiting_for()
1163   {
1164     mysql_prlock_wrlock(&m_LOCK_waiting_for);
1165     m_waiting_for= NULL;
1166     mysql_prlock_unlock(&m_LOCK_waiting_for);
1167   }
lock_deadlock_victim()1168   void lock_deadlock_victim()
1169   {
1170     mysql_prlock_rdlock(&m_LOCK_waiting_for);
1171   }
unlock_deadlock_victim()1172   void unlock_deadlock_victim()
1173   {
1174     mysql_prlock_unlock(&m_LOCK_waiting_for);
1175   }
1176 private:
1177   MDL_context(const MDL_context &rhs);          /* not implemented */
1178   MDL_context &operator=(MDL_context &rhs);     /* not implemented */
1179 };
1180 
1181 
1182 void mdl_init();
1183 void mdl_destroy();
1184 
1185 
1186 #ifndef NDEBUG
1187 extern mysql_mutex_t LOCK_open;
1188 #endif
1189 
1190 
1191 /*
1192   Metadata locking subsystem tries not to grant more than
1193   max_write_lock_count high priority, strong locks successively,
1194   to avoid starving out weak, lower priority locks.
1195 */
1196 extern "C" ulong max_write_lock_count;
1197 
1198 extern int32 mdl_locks_unused_locks_low_water;
1199 
1200 /**
1201   Default value for threshold for number of unused MDL_lock objects after
1202   exceeding which we start considering freeing them. Only unit tests use
1203   different threshold value.
1204 */
1205 const int32 MDL_LOCKS_UNUSED_LOCKS_LOW_WATER_DEFAULT= 1000;
1206 
1207 /**
1208   Ratio of unused/total MDL_lock objects after exceeding which we
1209   start trying to free unused MDL_lock objects (assuming that
1210   mdl_locks_unused_locks_low_water threshold is passed as well).
1211   Note that this value should be high enough for our algorithm
1212   using random dives into hash to work well.
1213 */
1214 const double MDL_LOCKS_UNUSED_LOCKS_MIN_RATIO= 0.25;
1215 
1216 int32 mdl_get_unused_locks_count();
1217 
1218 #endif
1219