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