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, Suite 500, 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
24class THD;
25
26class MDL_context;
27class MDL_lock;
28class MDL_ticket;
29bool 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
54class MDL_context_owner
55{
56public:
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
117enum 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
242enum 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
275class MDL_key
276{
277public:
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
310 const uchar *ptr() const { return (uchar*) m_ptr; }
311 uint length() const { return m_length; }
312
313 const char *db_name() const { return m_ptr + 1; }
314 uint db_name_length() const { return m_db_name_length; }
315
316 const char *name() const { return m_ptr + m_db_name_length + 2; }
317 uint name_length() const { return m_length - m_db_name_length - 3; }
318
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 */
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 }
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 }
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 */
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
378 MDL_key(const MDL_key *rhs)
379 {
380 mdl_key_init(rhs);
381 }
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 }
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 */
393 const PSI_stage_info * get_wait_state_name() const
394 {
395 return & m_namespace_to_wait_state_name[(int)mdl_namespace()];
396 }
397 my_hash_value_type hash_value() const
398 {
399 return m_hash_value + mdl_namespace();
400 }
401 my_hash_value_type tc_hash_value() const
402 {
403 return m_hash_value;
404 }
405
406private:
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];
412private:
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
433class MDL_request
434{
435public:
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
455public:
456
457 static void *operator new(size_t size, MEM_ROOT *mem_root) throw ()
458 { return alloc_root(mem_root, size); }
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. */
468 inline void set_type(enum_mdl_type type_arg)
469 {
470 DBUG_ASSERT(ticket == NULL);
471 type= type_arg;
472 }
473
474 /**
475 Is this a request for a lock which allow data to be updated?
476
477 @note This method returns true for MDL_SHARED_UPGRADABLE type of
478 lock. Even though this type of lock doesn't allow updates
479 it will always be upgraded to one that does.
480 */
481 bool is_write_lock_request() const
482 {
483 return (type >= MDL_SHARED_WRITE &&
484 type != MDL_SHARED_READ_ONLY);
485 }
486
487 /*
488 This is to work around the ugliness of TABLE_LIST
489 compiler-generated assignment operator. It is currently used
490 in several places to quickly copy "most" of the members of the
491 table list. These places currently never assume that the mdl
492 request is carried over to the new TABLE_LIST, or shared
493 between lists.
494
495 This method does not initialize the instance being assigned!
496 Use of init() for initialization after this assignment operator
497 is mandatory. Can only be used before the request has been
498 granted.
499 */
500 MDL_request& operator=(const MDL_request &)
501 {
502 ticket= NULL;
503 /* Do nothing, in particular, don't try to copy the key. */
504 return *this;
505 }
506 /* Another piece of ugliness for TABLE_LIST constructor */
507 MDL_request() {}
508
509 MDL_request(const MDL_request *rhs)
510 :type(rhs->type),
511 duration(rhs->duration),
512 ticket(NULL),
513 key(&rhs->key)
514 {}
515};
516
517
518typedef void (*mdl_cached_object_release_hook)(void *);
519
520
521/**
522 An abstract class for inspection of a connected
523 subgraph of the wait-for graph.
524*/
525
526class MDL_wait_for_graph_visitor
527{
528public:
529 virtual bool enter_node(MDL_context *node) = 0;
530 virtual void leave_node(MDL_context *node) = 0;
531
532 virtual bool inspect_edge(MDL_context *dest) = 0;
533 virtual ~MDL_wait_for_graph_visitor();
534 MDL_wait_for_graph_visitor() {}
535};
536
537/**
538 Abstract class representing an edge in the waiters graph
539 to be traversed by deadlock detection algorithm.
540*/
541
542class MDL_wait_for_subgraph
543{
544public:
545 virtual ~MDL_wait_for_subgraph();
546
547 /**
548 Accept a wait-for graph visitor to inspect the node
549 this edge is leading to.
550 */
551 virtual bool accept_visitor(MDL_wait_for_graph_visitor *gvisitor) = 0;
552
553 enum enum_deadlock_weight
554 {
555 DEADLOCK_WEIGHT_DML= 0,
556 DEADLOCK_WEIGHT_DDL= 100
557 };
558 /* A helper used to determine which lock request should be aborted. */
559 virtual uint get_deadlock_weight() const = 0;
560};
561
562
563/**
564 A granted metadata lock.
565
566 @warning MDL_ticket members are private to the MDL subsystem.
567
568 @note Multiple shared locks on a same object are represented by a
569 single ticket. The same does not apply for other lock types.
570
571 @note There are two groups of MDL_ticket members:
572 - "Externally accessible". These members can be accessed from
573 threads/contexts different than ticket owner in cases when
574 ticket participates in some list of granted or waiting tickets
575 for a lock. Therefore one should change these members before
576 including then to waiting/granted lists or while holding lock
577 protecting those lists.
578 - "Context private". Such members are private to thread/context
579 owning this ticket. I.e. they should not be accessed from other
580 threads/contexts.
581*/
582
583class MDL_ticket : public MDL_wait_for_subgraph
584{
585public:
586 /**
587 Pointers for participating in the list of lock requests for this context.
588 Context private.
589 */
590 MDL_ticket *next_in_context;
591 MDL_ticket **prev_in_context;
592 /**
593 Pointers for participating in the list of satisfied/pending requests
594 for the lock. Externally accessible.
595 */
596 MDL_ticket *next_in_lock;
597 MDL_ticket **prev_in_lock;
598public:
599#ifdef WITH_WSREP
600 void wsrep_report(bool debug);
601#endif /* WITH_WSREP */
602 bool has_pending_conflicting_lock() const;
603
604 MDL_context *get_ctx() const { return m_ctx; }
605 bool is_upgradable_or_exclusive() const
606 {
607 return m_type == MDL_SHARED_UPGRADABLE ||
608 m_type == MDL_SHARED_NO_WRITE ||
609 m_type == MDL_SHARED_NO_READ_WRITE ||
610 m_type == MDL_EXCLUSIVE;
611 }
612 enum_mdl_type get_type() const { return m_type; }
613 MDL_lock *get_lock() const { return m_lock; }
614 MDL_key *get_key() const;
615 void downgrade_lock(enum_mdl_type type);
616
617 bool has_stronger_or_equal_type(enum_mdl_type type) const;
618
619 bool is_incompatible_when_granted(enum_mdl_type type) const;
620 bool is_incompatible_when_waiting(enum_mdl_type type) const;
621
622 /** Implement MDL_wait_for_subgraph interface. */
623 virtual bool accept_visitor(MDL_wait_for_graph_visitor *dvisitor);
624 virtual uint get_deadlock_weight() const;
625private:
626 friend class MDL_context;
627
628 MDL_ticket(MDL_context *ctx_arg, enum_mdl_type type_arg
629#ifndef DBUG_OFF
630 , enum_mdl_duration duration_arg
631#endif
632 )
633 : m_type(type_arg),
634#ifndef DBUG_OFF
635 m_duration(duration_arg),
636#endif
637 m_ctx(ctx_arg),
638 m_lock(NULL)
639 {}
640
641 static MDL_ticket *create(MDL_context *ctx_arg, enum_mdl_type type_arg
642#ifndef DBUG_OFF
643 , enum_mdl_duration duration_arg
644#endif
645 );
646 static void destroy(MDL_ticket *ticket);
647private:
648 /** Type of metadata lock. Externally accessible. */
649 enum enum_mdl_type m_type;
650#ifndef DBUG_OFF
651 /**
652 Duration of lock represented by this ticket.
653 Context private. Debug-only.
654 */
655 enum_mdl_duration m_duration;
656#endif
657 /**
658 Context of the owner of the metadata lock ticket. Externally accessible.
659 */
660 MDL_context *m_ctx;
661
662 /**
663 Pointer to the lock object for this lock ticket. Externally accessible.
664 */
665 MDL_lock *m_lock;
666
667private:
668 MDL_ticket(const MDL_ticket &); /* not implemented */
669 MDL_ticket &operator=(const MDL_ticket &); /* not implemented */
670};
671
672
673/**
674 Savepoint for MDL context.
675
676 Doesn't include metadata locks with explicit duration as
677 they are not released during rollback to savepoint.
678*/
679
680class MDL_savepoint
681{
682public:
683 MDL_savepoint() {};
684
685private:
686 MDL_savepoint(MDL_ticket *stmt_ticket, MDL_ticket *trans_ticket)
687 : m_stmt_ticket(stmt_ticket), m_trans_ticket(trans_ticket)
688 {}
689
690 friend class MDL_context;
691
692private:
693 /**
694 Pointer to last lock with statement duration which was taken
695 before creation of savepoint.
696 */
697 MDL_ticket *m_stmt_ticket;
698 /**
699 Pointer to last lock with transaction duration which was taken
700 before creation of savepoint.
701 */
702 MDL_ticket *m_trans_ticket;
703};
704
705
706/**
707 A reliable way to wait on an MDL lock.
708*/
709
710class MDL_wait
711{
712public:
713 MDL_wait();
714 ~MDL_wait();
715
716 enum enum_wait_status { EMPTY = 0, GRANTED, VICTIM, TIMEOUT, KILLED };
717
718 bool set_status(enum_wait_status result_arg);
719 enum_wait_status get_status();
720 void reset_status();
721 enum_wait_status timed_wait(MDL_context_owner *owner,
722 struct timespec *abs_timeout,
723 bool signal_timeout,
724 const PSI_stage_info *wait_state_name);
725private:
726 /**
727 Condvar which is used for waiting until this context's pending
728 request can be satisfied or this thread has to perform actions
729 to resolve a potential deadlock (we subscribe to such
730 notification by adding a ticket corresponding to the request
731 to an appropriate queue of waiters).
732 */
733 mysql_mutex_t m_LOCK_wait_status;
734 mysql_cond_t m_COND_wait_status;
735 enum_wait_status m_wait_status;
736};
737
738
739typedef I_P_List<MDL_request, I_P_List_adapter<MDL_request,
740 &MDL_request::next_in_list,
741 &MDL_request::prev_in_list>,
742 I_P_List_counter>
743 MDL_request_list;
744
745/**
746 Context of the owner of metadata locks. I.e. each server
747 connection has such a context.
748*/
749
750class MDL_context
751{
752public:
753 typedef I_P_List<MDL_ticket,
754 I_P_List_adapter<MDL_ticket,
755 &MDL_ticket::next_in_context,
756 &MDL_ticket::prev_in_context> >
757 Ticket_list;
758
759 typedef Ticket_list::Iterator Ticket_iterator;
760
761 MDL_context();
762 void destroy();
763
764 bool try_acquire_lock(MDL_request *mdl_request);
765 bool acquire_lock(MDL_request *mdl_request, double lock_wait_timeout);
766 bool acquire_locks(MDL_request_list *requests, double lock_wait_timeout);
767 bool upgrade_shared_lock(MDL_ticket *mdl_ticket,
768 enum_mdl_type new_type,
769 double lock_wait_timeout);
770
771 bool clone_ticket(MDL_request *mdl_request);
772
773 void release_all_locks_for_name(MDL_ticket *ticket);
774 void release_lock(MDL_ticket *ticket);
775
776 bool is_lock_owner(MDL_key::enum_mdl_namespace mdl_namespace,
777 const char *db, const char *name,
778 enum_mdl_type mdl_type);
779 unsigned long get_lock_owner(MDL_key *mdl_key);
780
781 bool has_lock(const MDL_savepoint &mdl_savepoint, MDL_ticket *mdl_ticket);
782
783 inline bool has_locks() const
784 {
785 return !(m_tickets[MDL_STATEMENT].is_empty() &&
786 m_tickets[MDL_TRANSACTION].is_empty() &&
787 m_tickets[MDL_EXPLICIT].is_empty());
788 }
789 inline bool has_transactional_locks() const
790 {
791 return !m_tickets[MDL_TRANSACTION].is_empty();
792 }
793
794 MDL_savepoint mdl_savepoint()
795 {
796 return MDL_savepoint(m_tickets[MDL_STATEMENT].front(),
797 m_tickets[MDL_TRANSACTION].front());
798 }
799
800 void set_explicit_duration_for_all_locks();
801 void set_transaction_duration_for_all_locks();
802 void set_lock_duration(MDL_ticket *mdl_ticket, enum_mdl_duration duration);
803
804 void release_statement_locks();
805 void release_transactional_locks();
806 void release_explicit_locks();
807 void rollback_to_savepoint(const MDL_savepoint &mdl_savepoint);
808
809 MDL_context_owner *get_owner() { return m_owner; }
810
811 /** @pre Only valid if we started waiting for lock. */
812 inline uint get_deadlock_weight() const
813 { return m_waiting_for->get_deadlock_weight(); }
814 /**
815 Post signal to the context (and wake it up if necessary).
816
817 @retval FALSE - Success, signal was posted.
818 @retval TRUE - Failure, signal was not posted since context
819 already has received some signal or closed
820 signal slot.
821 */
822 void init(MDL_context_owner *arg) { m_owner= arg; }
823
824 void set_needs_thr_lock_abort(bool needs_thr_lock_abort)
825 {
826 /*
827 @note In theory, this member should be modified under protection
828 of some lock since it can be accessed from different threads.
829 In practice, this is not necessary as code which reads this
830 value and so might miss the fact that value was changed will
831 always re-try reading it after small timeout and therefore
832 will see the new value eventually.
833 */
834 m_needs_thr_lock_abort= needs_thr_lock_abort;
835 }
836 bool get_needs_thr_lock_abort() const
837 {
838 return m_needs_thr_lock_abort;
839 }
840public:
841 /**
842 If our request for a lock is scheduled, or aborted by the deadlock
843 detector, the result is recorded in this class.
844 */
845 MDL_wait m_wait;
846private:
847 /**
848 Lists of all MDL tickets acquired by this connection.
849
850 Lists of MDL tickets:
851 ---------------------
852 The entire set of locks acquired by a connection can be separated
853 in three subsets according to their duration: locks released at
854 the end of statement, at the end of transaction and locks are
855 released explicitly.
856
857 Statement and transactional locks are locks with automatic scope.
858 They are accumulated in the course of a transaction, and released
859 either at the end of uppermost statement (for statement locks) or
860 on COMMIT, ROLLBACK or ROLLBACK TO SAVEPOINT (for transactional
861 locks). They must not be (and never are) released manually,
862 i.e. with release_lock() call.
863
864 Tickets with explicit duration are taken for locks that span
865 multiple transactions or savepoints.
866 These are: HANDLER SQL locks (HANDLER SQL is
867 transaction-agnostic), LOCK TABLES locks (you can COMMIT/etc
868 under LOCK TABLES, and the locked tables stay locked), user level
869 locks (GET_LOCK()/RELEASE_LOCK() functions) and
870 locks implementing "global read lock".
871
872 Statement/transactional locks are always prepended to the
873 beginning of the appropriate list. In other words, they are
874 stored in reverse temporal order. Thus, when we rollback to
875 a savepoint, we start popping and releasing tickets from the
876 front until we reach the last ticket acquired after the savepoint.
877
878 Locks with explicit duration are not stored in any
879 particular order, and among each other can be split into
880 four sets:
881
882 [LOCK TABLES locks] [USER locks] [HANDLER locks] [GLOBAL READ LOCK locks]
883
884 The following is known about these sets:
885
886 * GLOBAL READ LOCK locks are always stored last.
887 This is because one can't say SET GLOBAL read_only=1 or
888 FLUSH TABLES WITH READ LOCK if one has locked tables. One can,
889 however, LOCK TABLES after having entered the read only mode.
890 Note, that subsequent LOCK TABLES statement will unlock the previous
891 set of tables, but not the GRL!
892 There are no HANDLER locks after GRL locks because
893 SET GLOBAL read_only performs a FLUSH TABLES WITH
894 READ LOCK internally, and FLUSH TABLES, in turn, implicitly
895 closes all open HANDLERs.
896 However, one can open a few HANDLERs after entering the
897 read only mode.
898 * LOCK TABLES locks include intention exclusive locks on
899 involved schemas and global intention exclusive lock.
900 */
901 Ticket_list m_tickets[MDL_DURATION_END];
902 MDL_context_owner *m_owner;
903 /**
904 TRUE - if for this context we will break protocol and try to
905 acquire table-level locks while having only S lock on
906 some table.
907 To avoid deadlocks which might occur during concurrent
908 upgrade of SNRW lock on such object to X lock we have to
909 abort waits for table-level locks for such connections.
910 FALSE - Otherwise.
911 */
912 bool m_needs_thr_lock_abort;
913
914 /**
915 Read-write lock protecting m_waiting_for member.
916
917 @note The fact that this read-write lock prefers readers is
918 important as deadlock detector won't work correctly
919 otherwise. @sa Comment for MDL_lock::m_rwlock.
920 */
921 mysql_prlock_t m_LOCK_waiting_for;
922 /**
923 Tell the deadlock detector what metadata lock or table
924 definition cache entry this session is waiting for.
925 In principle, this is redundant, as information can be found
926 by inspecting waiting queues, but we'd very much like it to be
927 readily available to the wait-for graph iterator.
928 */
929 MDL_wait_for_subgraph *m_waiting_for;
930 LF_PINS *m_pins;
931private:
932 MDL_ticket *find_ticket(MDL_request *mdl_req,
933 enum_mdl_duration *duration);
934 void release_locks_stored_before(enum_mdl_duration duration, MDL_ticket *sentinel);
935 void release_lock(enum_mdl_duration duration, MDL_ticket *ticket);
936 bool try_acquire_lock_impl(MDL_request *mdl_request,
937 MDL_ticket **out_ticket);
938 bool fix_pins();
939
940public:
941 THD *get_thd() const { return m_owner->get_thd(); }
942 bool has_explicit_locks();
943 void find_deadlock();
944
945 ulong get_thread_id() const { return thd_get_thread_id(get_thd()); }
946
947 bool visit_subgraph(MDL_wait_for_graph_visitor *dvisitor);
948
949 /** Inform the deadlock detector there is an edge in the wait-for graph. */
950 void will_wait_for(MDL_wait_for_subgraph *waiting_for_arg)
951 {
952 mysql_prlock_wrlock(&m_LOCK_waiting_for);
953 m_waiting_for= waiting_for_arg;
954 mysql_prlock_unlock(&m_LOCK_waiting_for);
955 }
956
957 /** Remove the wait-for edge from the graph after we're done waiting. */
958 void done_waiting_for()
959 {
960 mysql_prlock_wrlock(&m_LOCK_waiting_for);
961 m_waiting_for= NULL;
962 mysql_prlock_unlock(&m_LOCK_waiting_for);
963 }
964 void lock_deadlock_victim()
965 {
966 mysql_prlock_rdlock(&m_LOCK_waiting_for);
967 }
968 void unlock_deadlock_victim()
969 {
970 mysql_prlock_unlock(&m_LOCK_waiting_for);
971 }
972private:
973 MDL_context(const MDL_context &rhs); /* not implemented */
974 MDL_context &operator=(MDL_context &rhs); /* not implemented */
975
976 /* metadata_lock_info plugin */
977 friend int i_s_metadata_lock_info_fill_row(MDL_ticket*, void*);
978};
979
980
981void mdl_init();
982void mdl_destroy();
983
984extern "C" unsigned long thd_get_thread_id(const MYSQL_THD thd);
985
986/**
987 Check if a connection in question is no longer connected.
988
989 @details
990 Replication apply thread is always connected. Otherwise,
991 does a poll on the associated socket to check if the client
992 is gone.
993*/
994extern "C" int thd_is_connected(MYSQL_THD thd);
995
996
997/*
998 Metadata locking subsystem tries not to grant more than
999 max_write_lock_count high-prio, strong locks successively,
1000 to avoid starving out weak, low-prio locks.
1001*/
1002extern "C" ulong max_write_lock_count;
1003
1004extern MYSQL_PLUGIN_IMPORT
1005int mdl_iterate(int (*callback)(MDL_ticket *ticket, void *arg), void *arg);
1006#endif
1007