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