19 #include "sql_array.h"
21 #include <mysqld_error.h>
22 #include <mysql/plugin.h>
26 #ifdef HAVE_PSI_INTERFACE
27 static PSI_mutex_key key_MDL_map_mutex;
28 static PSI_mutex_key key_MDL_wait_LOCK_wait_status;
30 static PSI_mutex_info all_mdl_mutexes[]=
32 { &key_MDL_map_mutex,
"MDL_map::mutex", 0},
33 { &key_MDL_wait_LOCK_wait_status,
"MDL_wait::LOCK_wait_status", 0}
36 static PSI_rwlock_key key_MDL_lock_rwlock;
37 static PSI_rwlock_key key_MDL_context_LOCK_waiting_for;
39 static PSI_rwlock_info all_mdl_rwlocks[]=
41 { &key_MDL_lock_rwlock,
"MDL_lock::rwlock", 0},
42 { &key_MDL_context_LOCK_waiting_for,
"MDL_context::LOCK_waiting_for", 0}
45 static PSI_cond_key key_MDL_wait_COND_wait_status;
47 static PSI_cond_info all_mdl_conds[]=
49 { &key_MDL_wait_COND_wait_status,
"MDL_context::COND_wait_status", 0}
56 static void init_mdl_psi_keys(
void)
60 count= array_elements(all_mdl_mutexes);
63 count= array_elements(all_mdl_rwlocks);
66 count= array_elements(all_mdl_conds);
69 MDL_key::init_psi_keys();
79 PSI_stage_info MDL_key::m_namespace_to_wait_state_name[NAMESPACE_END]=
81 {0,
"Waiting for global read lock", 0},
82 {0,
"Waiting for schema metadata lock", 0},
83 {0,
"Waiting for table metadata lock", 0},
84 {0,
"Waiting for stored function metadata lock", 0},
85 {0,
"Waiting for stored procedure metadata lock", 0},
86 {0,
"Waiting for trigger metadata lock", 0},
87 {0,
"Waiting for event metadata lock", 0},
88 {0,
"Waiting for commit lock", 0}
91 #ifdef HAVE_PSI_INTERFACE
92 void MDL_key::init_psi_keys()
98 count= array_elements(MDL_key::m_namespace_to_wait_state_name);
99 for (i= 0; i<count; i++)
102 info= & MDL_key::m_namespace_to_wait_state_name[
i];
108 static bool mdl_initialized= 0;
127 my_hash_value_type hash_value);
129 my_hash_value_type get_key_hash(
const MDL_key *mdl_key)
const
131 return my_calc_hash(&m_locks, mdl_key->ptr(), mdl_key->length());
134 bool move_from_hash_to_lock_mutex(
MDL_lock *lock);
164 ulong mdl_locks_hash_partitions;
198 : m_start_node(start_node_arg),
200 m_current_search_depth(0),
201 m_found_deadlock(FALSE)
208 MDL_context *get_victim()
const {
return m_victim; }
214 void opt_change_victim_to(
MDL_context *new_victim);
229 uint m_current_search_depth;
231 bool m_found_deadlock;
245 static const uint MAX_SEARCH_DEPTH= 32;
263 m_found_deadlock= ++m_current_search_depth >= MAX_SEARCH_DEPTH;
264 if (m_found_deadlock)
266 DBUG_ASSERT(! m_victim);
267 opt_change_victim_to(node);
269 return m_found_deadlock;
283 --m_current_search_depth;
284 if (m_found_deadlock)
285 opt_change_victim_to(node);
298 m_found_deadlock= node == m_start_node;
299 return m_found_deadlock;
312 Deadlock_detection_visitor::opt_change_victim_to(
MDL_context *new_victim)
314 if (m_victim == NULL ||
319 m_victim= new_victim;
320 m_victim->lock_deadlock_victim();
322 tmp->unlock_deadlock_victim();
332 #define MDL_BIT(A) static_cast<MDL_lock::bitmap_t>(1U << A)
348 typedef unsigned short bitmap_t;
356 &MDL_ticket::prev_in_lock>,
360 operator const List &()
const {
return m_list; }
365 bool is_empty()
const {
return m_list.is_empty(); }
366 bitmap_t bitmap()
const {
return m_bitmap; }
368 void clear_bit_if_not_in_list(enum_mdl_type
type);
416 bool is_empty()
const
421 virtual const bitmap_t *incompatible_granted_types_bitmap()
const = 0;
422 virtual const bitmap_t *incompatible_waiting_types_bitmap()
const = 0;
427 bool ignore_lock_priority)
const;
439 virtual bool needs_notification(
const MDL_ticket *ticket)
const = 0;
440 virtual void notify_conflicting_locks(
MDL_context *ctx) = 0;
442 virtual bitmap_t hog_lock_types_bitmap()
const = 0;
462 m_is_destroyed(FALSE),
473 inline static void destroy(
MDL_lock *lock);
535 virtual const bitmap_t *incompatible_granted_types_bitmap()
const
537 return m_granted_incompatible;
539 virtual const bitmap_t *incompatible_waiting_types_bitmap()
const
541 return m_waiting_incompatible;
543 virtual bool needs_notification(
const MDL_ticket *ticket)
const
545 return (ticket->get_type() == MDL_SHARED);
553 virtual bitmap_t hog_lock_types_bitmap()
const
559 static const bitmap_t m_granted_incompatible[MDL_TYPE_END];
560 static const bitmap_t m_waiting_incompatible[MDL_TYPE_END];
585 DBUG_ASSERT(is_empty());
587 DBUG_ASSERT(! m_is_destroyed);
596 virtual const bitmap_t *incompatible_granted_types_bitmap()
const
598 return m_granted_incompatible;
600 virtual const bitmap_t *incompatible_waiting_types_bitmap()
const
602 return m_waiting_incompatible;
604 virtual bool needs_notification(
const MDL_ticket *ticket)
const
606 return (ticket->get_type() >= MDL_SHARED_NO_WRITE);
615 virtual bitmap_t hog_lock_types_bitmap()
const
617 return (MDL_BIT(MDL_SHARED_NO_WRITE) |
618 MDL_BIT(MDL_SHARED_NO_READ_WRITE) |
619 MDL_BIT(MDL_EXCLUSIVE));
623 static const bitmap_t m_granted_incompatible[MDL_TYPE_END];
624 static const bitmap_t m_waiting_incompatible[MDL_TYPE_END];
637 &MDL_object_lock::prev_in_cache>
646 ulong mdl_locks_cache_size;
652 mdl_locks_key(
const uchar *
record,
size_t *length,
653 my_bool not_used __attribute__((unused)))
656 *length= lock->
key.length();
657 return (uchar*) lock->
key.ptr();
675 DBUG_ASSERT(! mdl_initialized);
676 mdl_initialized= TRUE;
678 #ifdef HAVE_PSI_INTERFACE
697 mdl_initialized= FALSE;
707 MDL_key global_lock_key(MDL_key::GLOBAL,
"",
"");
708 MDL_key commit_lock_key(MDL_key::COMMIT,
"",
"");
713 for (uint i= 0; i < mdl_locks_hash_partitions; i++)
716 m_partitions.
append(part);
726 my_hash_init(&m_locks, &my_charset_bin, 16 , 0, 0,
727 mdl_locks_key, 0, 0);
741 while (m_partitions.elements() > 0)
756 DBUG_ASSERT(!m_locks.records);
758 my_hash_free(&m_locks);
761 while ((lock= m_unused_locks_cache.pop_front()))
762 MDL_lock::destroy(lock);
779 if (mdl_key->mdl_namespace() == MDL_key::GLOBAL ||
780 mdl_key->mdl_namespace() == MDL_key::COMMIT)
791 DBUG_ASSERT(mdl_key->length() == 3);
793 lock= (mdl_key->mdl_namespace() == MDL_key::GLOBAL) ? m_global_lock :
801 my_hash_value_type hash_value= m_partitions.
at(0)->get_key_hash(mdl_key);
802 uint part_id= hash_value % mdl_locks_hash_partitions;
819 my_hash_value_type hash_value)
825 if (!(lock= (
MDL_lock*) my_hash_search_using_hash_value(&m_locks,
836 if (mdl_key->mdl_namespace() != MDL_key::SCHEMA &&
837 m_unused_locks_cache.elements())
844 DBUG_ASSERT(mdl_key->mdl_namespace() != MDL_key::GLOBAL &&
845 mdl_key->mdl_namespace() != MDL_key::COMMIT);
847 unused_lock= m_unused_locks_cache.pop_front();
848 unused_lock->
reset(mdl_key);
857 if (!lock || my_hash_insert(&m_locks, (uchar*)lock))
866 m_unused_locks_cache.push_front(unused_lock);
870 MDL_lock::destroy(lock);
877 if (move_from_hash_to_lock_mutex(lock))
894 bool MDL_map_partition::move_from_hash_to_lock_mutex(
MDL_lock *lock)
898 DBUG_ASSERT(! lock->m_is_destroyed);
912 lock->m_ref_release++;
914 if (unlikely(lock->
m_version != version))
923 if (unlikely(lock->m_is_destroyed))
935 uint ref_release= lock->m_ref_release;
937 if (ref_usage == ref_release)
938 MDL_lock::destroy(lock);
965 if (lock->
key.mdl_namespace() == MDL_key::GLOBAL ||
966 lock->
key.mdl_namespace() == MDL_key::COMMIT)
989 my_hash_delete(&m_locks, (uchar*) lock);
999 if ((lock->
key.mdl_namespace() != MDL_key::SCHEMA) &&
1000 (m_unused_locks_cache.elements() <
1001 mdl_locks_cache_size/mdl_locks_hash_partitions))
1012 DBUG_ASSERT(lock->
key.mdl_namespace() != MDL_key::GLOBAL &&
1013 lock->
key.mdl_namespace() != MDL_key::COMMIT);
1038 uint ref_usage, ref_release;
1040 lock->m_is_destroyed= TRUE;
1042 ref_release= lock->m_ref_release;
1045 if (ref_usage == ref_release)
1046 MDL_lock::destroy(lock);
1060 m_needs_thr_lock_abort(FALSE),
1081 DBUG_ASSERT(m_tickets[MDL_STATEMENT].is_empty());
1082 DBUG_ASSERT(m_tickets[MDL_TRANSACTION].is_empty());
1083 DBUG_ASSERT(m_tickets[MDL_EXPLICIT].is_empty());
1111 const char *name_arg,
1112 enum_mdl_type mdl_type_arg,
1113 enum_mdl_duration mdl_duration_arg)
1132 enum_mdl_type mdl_type_arg,
1133 enum_mdl_duration mdl_duration_arg)
1151 switch (mdl_key->mdl_namespace())
1153 case MDL_key::GLOBAL:
1154 case MDL_key::SCHEMA:
1155 case MDL_key::COMMIT:
1163 void MDL_lock::destroy(
MDL_lock *lock)
1179 , enum_mdl_duration duration_arg
1183 return new (std::nothrow)
1207 return (m_lock->
key.mdl_namespace() == MDL_key::GLOBAL ||
1208 m_type >= MDL_SHARED_UPGRADABLE ?
1209 DEADLOCK_WEIGHT_DDL : DEADLOCK_WEIGHT_DML);
1216 :m_wait_status(EMPTY)
1218 mysql_mutex_init(key_MDL_wait_LOCK_wait_status, &m_LOCK_wait_status, NULL);
1219 mysql_cond_init(key_MDL_wait_COND_wait_status, &m_COND_wait_status, NULL);
1239 bool was_occupied= TRUE;
1241 if (m_wait_status == EMPTY)
1243 was_occupied= FALSE;
1244 m_wait_status= status_arg;
1248 return was_occupied;
1256 enum_wait_status result;
1258 result= m_wait_status;
1269 m_wait_status= EMPTY;
1288 MDL_wait::enum_wait_status
1290 bool set_status_on_timeout,
1294 enum_wait_status result;
1299 owner->ENTER_COND(&m_COND_wait_status, &m_LOCK_wait_status,
1300 wait_state_name, & old_stage);
1302 while (!m_wait_status && !owner->
is_killed() &&
1303 wait_result != ETIMEDOUT && wait_result != ETIME)
1310 if (m_wait_status == EMPTY)
1325 m_wait_status= KILLED;
1326 else if (set_status_on_timeout)
1327 m_wait_status= TIMEOUT;
1329 result= m_wait_status;
1331 owner->EXIT_COND(& old_stage);
1346 void MDL_lock::Ticket_list::clear_bit_if_not_in_list(enum_mdl_type
type)
1351 while ((ticket= it++))
1352 if (ticket->get_type() ==
type)
1354 m_bitmap&= ~ MDL_BIT(type);
1370 DBUG_ASSERT(ticket->get_lock());
1375 m_list.push_back(ticket);
1376 m_bitmap|= MDL_BIT(ticket->get_type());
1387 m_list.remove(ticket);
1398 clear_bit_if_not_in_list(ticket->get_type());
1417 bool skip_high_priority=
false;
1418 bitmap_t hog_lock_types= hog_lock_types_bitmap();
1428 if ((
m_waiting.bitmap() & ~hog_lock_types) != 0)
1449 skip_high_priority=
true;
1471 while ((ticket= it++))
1477 if (skip_high_priority &&
1478 ((MDL_BIT(ticket->get_type()) & hog_lock_types) != 0))
1482 skip_high_priority))
1501 if ((MDL_BIT(ticket->get_type()) & hog_lock_types) != 0)
1515 if ((
m_waiting.bitmap() & ~hog_lock_types) == 0)
1584 const MDL_lock::bitmap_t MDL_scoped_lock::m_granted_incompatible[MDL_TYPE_END] =
1586 MDL_BIT(MDL_EXCLUSIVE) | MDL_BIT(MDL_SHARED),
1587 MDL_BIT(MDL_EXCLUSIVE) | MDL_BIT(MDL_INTENTION_EXCLUSIVE), 0, 0, 0, 0, 0, 0,
1588 MDL_BIT(MDL_EXCLUSIVE) | MDL_BIT(MDL_SHARED) | MDL_BIT(MDL_INTENTION_EXCLUSIVE)
1591 const MDL_lock::bitmap_t MDL_scoped_lock::m_waiting_incompatible[MDL_TYPE_END] =
1593 MDL_BIT(MDL_EXCLUSIVE) | MDL_BIT(MDL_SHARED),
1594 MDL_BIT(MDL_EXCLUSIVE), 0, 0, 0, 0, 0, 0, 0
1652 const MDL_lock::bitmap_t
1653 MDL_object_lock::m_granted_incompatible[MDL_TYPE_END] =
1656 MDL_BIT(MDL_EXCLUSIVE),
1657 MDL_BIT(MDL_EXCLUSIVE),
1658 MDL_BIT(MDL_EXCLUSIVE) | MDL_BIT(MDL_SHARED_NO_READ_WRITE),
1659 MDL_BIT(MDL_EXCLUSIVE) | MDL_BIT(MDL_SHARED_NO_READ_WRITE) |
1660 MDL_BIT(MDL_SHARED_NO_WRITE),
1661 MDL_BIT(MDL_EXCLUSIVE) | MDL_BIT(MDL_SHARED_NO_READ_WRITE) |
1662 MDL_BIT(MDL_SHARED_NO_WRITE) | MDL_BIT(MDL_SHARED_UPGRADABLE),
1663 MDL_BIT(MDL_EXCLUSIVE) | MDL_BIT(MDL_SHARED_NO_READ_WRITE) |
1664 MDL_BIT(MDL_SHARED_NO_WRITE) | MDL_BIT(MDL_SHARED_UPGRADABLE) |
1665 MDL_BIT(MDL_SHARED_WRITE),
1666 MDL_BIT(MDL_EXCLUSIVE) | MDL_BIT(MDL_SHARED_NO_READ_WRITE) |
1667 MDL_BIT(MDL_SHARED_NO_WRITE) | MDL_BIT(MDL_SHARED_UPGRADABLE) |
1668 MDL_BIT(MDL_SHARED_WRITE) | MDL_BIT(MDL_SHARED_READ),
1669 MDL_BIT(MDL_EXCLUSIVE) | MDL_BIT(MDL_SHARED_NO_READ_WRITE) |
1670 MDL_BIT(MDL_SHARED_NO_WRITE) | MDL_BIT(MDL_SHARED_UPGRADABLE) |
1671 MDL_BIT(MDL_SHARED_WRITE) | MDL_BIT(MDL_SHARED_READ) |
1672 MDL_BIT(MDL_SHARED_HIGH_PRIO) | MDL_BIT(MDL_SHARED)
1676 const MDL_lock::bitmap_t
1677 MDL_object_lock::m_waiting_incompatible[MDL_TYPE_END] =
1680 MDL_BIT(MDL_EXCLUSIVE),
1682 MDL_BIT(MDL_EXCLUSIVE) | MDL_BIT(MDL_SHARED_NO_READ_WRITE),
1683 MDL_BIT(MDL_EXCLUSIVE) | MDL_BIT(MDL_SHARED_NO_READ_WRITE) |
1684 MDL_BIT(MDL_SHARED_NO_WRITE),
1685 MDL_BIT(MDL_EXCLUSIVE),
1686 MDL_BIT(MDL_EXCLUSIVE),
1687 MDL_BIT(MDL_EXCLUSIVE),
1711 bool ignore_lock_priority)
const
1713 bool can_grant= FALSE;
1714 bitmap_t waiting_incompat_map= incompatible_waiting_types_bitmap()[type_arg];
1715 bitmap_t granted_incompat_map= incompatible_granted_types_bitmap()[type_arg];
1724 if (ignore_lock_priority || !(
m_waiting.bitmap() & waiting_incompat_map))
1726 if (! (
m_granted.bitmap() & granted_incompat_map))
1734 while ((ticket= it++))
1736 if (ticket->get_ctx() != requestor_ctx &&
1737 ticket->is_incompatible_when_granted(type_arg))
1794 result= (
m_waiting.bitmap() & incompatible_granted_types_bitmap()[
type]);
1800 MDL_wait_for_graph_visitor::~MDL_wait_for_graph_visitor()
1805 MDL_wait_for_subgraph::~MDL_wait_for_subgraph()
1820 const MDL_lock::bitmap_t *
1821 granted_incompat_map= m_lock->incompatible_granted_types_bitmap();
1823 return ! (granted_incompat_map[
type] & ~(granted_incompat_map[m_type]));
1827 bool MDL_ticket::is_incompatible_when_granted(enum_mdl_type type)
const
1829 return (MDL_BIT(m_type) &
1830 m_lock->incompatible_granted_types_bitmap()[
type]);
1834 bool MDL_ticket::is_incompatible_when_waiting(enum_mdl_type type)
const
1836 return (MDL_BIT(m_type) &
1837 m_lock->incompatible_waiting_types_bitmap()[
type]);
1857 MDL_context::find_ticket(
MDL_request *mdl_request,
1858 enum_mdl_duration *result_duration)
1863 for (i= 0; i < MDL_DURATION_END; i++)
1865 enum_mdl_duration duration= (enum_mdl_duration)((mdl_request->
duration+i) %
1867 Ticket_iterator it(m_tickets[duration]);
1869 while ((ticket= it++))
1871 if (mdl_request->
key.is_equal(&ticket->m_lock->
key) &&
1874 *result_duration= duration;
1914 if (try_acquire_lock_impl(mdl_request, &ticket))
1917 if (! mdl_request->
ticket)
1925 DBUG_ASSERT(! ticket->m_lock->is_empty());
1927 MDL_ticket::destroy(ticket);
1951 MDL_context::try_acquire_lock_impl(
MDL_request *mdl_request,
1957 enum_mdl_duration found_duration;
1959 DBUG_ASSERT(mdl_request->
type != MDL_EXCLUSIVE ||
1960 is_lock_owner(MDL_key::GLOBAL,
"",
"", MDL_INTENTION_EXCLUSIVE));
1961 DBUG_ASSERT(mdl_request->
ticket == NULL);
1964 mdl_request->
ticket= NULL;
1971 if ((ticket= find_ticket(mdl_request, &found_duration)))
1973 DBUG_ASSERT(ticket->m_lock);
1992 mdl_request->
ticket= ticket;
1993 if ((found_duration != mdl_request->
duration ||
1994 mdl_request->
duration == MDL_EXPLICIT) &&
1995 clone_ticket(mdl_request))
1998 mdl_request->
ticket= NULL;
2004 if (!(ticket= MDL_ticket::create(
this, mdl_request->
type
2014 MDL_ticket::destroy(ticket);
2018 ticket->m_lock= lock;
2026 m_tickets[mdl_request->
duration].push_front(ticket);
2028 mdl_request->
ticket= ticket;
2031 *out_ticket= ticket;
2061 if (!(ticket= MDL_ticket::create(
this, mdl_request->
type
2071 ticket->m_lock= mdl_request->
ticket->m_lock;
2072 mdl_request->
ticket= ticket;
2078 m_tickets[mdl_request->
duration].push_front(ticket);
2096 while ((conflicting_ticket= it++))
2099 if (conflicting_ticket->get_ctx() != ctx &&
2100 conflicting_ticket->get_type() < MDL_SHARED_UPGRADABLE)
2103 MDL_context *conflicting_ctx= conflicting_ticket->get_ctx();
2111 notify_shared_lock(conflicting_ctx->get_owner(),
2112 conflicting_ctx->get_needs_thr_lock_abort());
2129 while ((conflicting_ticket= it++))
2131 if (conflicting_ticket->get_ctx() != ctx &&
2132 conflicting_ticket->get_type() == MDL_INTENTION_EXCLUSIVE)
2135 MDL_context *conflicting_ctx= conflicting_ticket->get_ctx();
2143 notify_shared_lock(conflicting_ctx->get_owner(),
2144 conflicting_ctx->get_needs_thr_lock_abort());
2168 MDL_wait::enum_wait_status wait_status;
2170 set_timespec(abs_timeout, lock_wait_timeout);
2172 if (try_acquire_lock_impl(mdl_request, &ticket))
2191 lock= ticket->m_lock;
2201 m_wait.reset_status();
2203 if (lock->needs_notification(ticket))
2204 lock->notify_conflicting_locks(
this);
2208 will_wait_for(ticket);
2211 DEBUG_SYNC(get_thd(),
"mdl_acquire_lock_wait");
2215 if (lock->needs_notification(ticket))
2218 set_timespec(abs_shortwait, 1);
2219 wait_status= MDL_wait::EMPTY;
2221 while (cmp_timespec(abs_shortwait, abs_timeout) <= 0)
2224 wait_status= m_wait.timed_wait(m_owner, &abs_shortwait, FALSE,
2227 if (wait_status != MDL_wait::EMPTY)
2231 lock->notify_conflicting_locks(
this);
2233 set_timespec(abs_shortwait, 1);
2235 if (wait_status == MDL_wait::EMPTY)
2236 wait_status= m_wait.timed_wait(m_owner, &abs_timeout, TRUE,
2240 wait_status= m_wait.timed_wait(m_owner, &abs_timeout, TRUE,
2245 if (wait_status != MDL_wait::GRANTED)
2248 MDL_ticket::destroy(ticket);
2249 switch (wait_status)
2251 case MDL_wait::VICTIM:
2252 my_error(ER_LOCK_DEADLOCK, MYF(0));
2254 case MDL_wait::TIMEOUT:
2255 my_error(ER_LOCK_WAIT_TIMEOUT, MYF(0));
2257 case MDL_wait::KILLED:
2272 DBUG_ASSERT(wait_status == MDL_wait::GRANTED);
2274 m_tickets[mdl_request->
duration].push_front(ticket);
2276 mdl_request->
ticket= ticket;
2282 extern "C" int mdl_request_ptr_cmp(
const void* ptr1,
const void* ptr2)
2311 ulong lock_wait_timeout)
2316 ssize_t req_count=
static_cast<ssize_t
>(mdl_requests->elements());
2322 if (! (sort_buf= (
MDL_request **)my_malloc(req_count *
2327 for (p_req= sort_buf; p_req < sort_buf + req_count; p_req++)
2330 my_qsort(sort_buf, req_count,
sizeof(
MDL_request*),
2331 mdl_request_ptr_cmp);
2333 for (p_req= sort_buf; p_req < sort_buf + req_count; p_req++)
2335 if (acquire_lock(*p_req, lock_wait_timeout))
2347 rollback_to_savepoint(mdl_svp);
2349 for (req_count= p_req - sort_buf, p_req= sort_buf;
2350 p_req < sort_buf + req_count; p_req++)
2352 (*p_req)->ticket= NULL;
2386 enum_mdl_type new_type,
2387 ulong lock_wait_timeout)
2393 DBUG_ENTER(
"MDL_context::upgrade_shared_lock");
2394 DEBUG_SYNC(get_thd(),
"mdl_upgrade_lock");
2403 mdl_xlock_request.
init(&mdl_ticket->m_lock->
key, new_type,
2406 if (acquire_lock(&mdl_xlock_request, lock_wait_timeout))
2409 is_new_ticket= ! has_lock(mdl_svp, mdl_xlock_request.
ticket);
2421 mdl_ticket->m_type= new_type;
2428 m_tickets[MDL_TRANSACTION].remove(mdl_xlock_request.
ticket);
2429 MDL_ticket::destroy(mdl_xlock_request.
ticket);
2515 if (gvisitor->enter_node(src_ctx))
2524 while ((ticket= granted_it++))
2527 if (ticket->get_ctx() != src_ctx &&
2528 ticket->is_incompatible_when_granted(waiting_ticket->get_type()) &&
2529 gvisitor->inspect_edge(ticket->get_ctx()))
2531 goto end_leave_node;
2535 while ((ticket= waiting_it++))
2538 if (ticket->get_ctx() != src_ctx &&
2539 ticket->is_incompatible_when_waiting(waiting_ticket->get_type()) &&
2540 gvisitor->inspect_edge(ticket->get_ctx()))
2542 goto end_leave_node;
2547 granted_it.rewind();
2548 while ((ticket= granted_it++))
2550 if (ticket->get_ctx() != src_ctx &&
2551 ticket->is_incompatible_when_granted(waiting_ticket->get_type()) &&
2554 goto end_leave_node;
2558 waiting_it.rewind();
2559 while ((ticket= waiting_it++))
2561 if (ticket->get_ctx() != src_ctx &&
2562 ticket->is_incompatible_when_waiting(waiting_ticket->get_type()) &&
2565 goto end_leave_node;
2572 gvisitor->leave_node(src_ctx);
2592 return m_lock->visit_subgraph(
this, gvisitor);
2619 result= m_waiting_for->accept_visitor(gvisitor);
2656 victim= dvisitor.get_victim();
2671 victim->unlock_deadlock_victim();
2697 DBUG_ENTER(
"MDL_context::release_lock");
2698 DBUG_PRINT(
"enter", (
"db=%s name=%s", lock->
key.db_name(),
2701 DBUG_ASSERT(
this == ticket->get_ctx());
2706 m_tickets[duration].remove(ticket);
2707 MDL_ticket::destroy(ticket);
2722 DBUG_ASSERT(ticket->m_duration == MDL_EXPLICIT);
2724 release_lock(MDL_EXPLICIT, ticket);
2741 void MDL_context::release_locks_stored_before(enum_mdl_duration duration,
2745 Ticket_iterator it(m_tickets[duration]);
2746 DBUG_ENTER(
"MDL_context::release_locks_stored_before");
2748 if (m_tickets[duration].is_empty())
2751 while ((ticket= it++) && ticket != sentinel)
2753 DBUG_PRINT(
"info", (
"found lock to release ticket=%p", ticket));
2754 release_lock(duration, ticket);
2778 while ((ticket= it_ticket++))
2780 DBUG_ASSERT(ticket->m_lock);
2781 if (ticket->m_lock == lock)
2782 release_lock(MDL_EXPLICIT, ticket);
2804 if (m_type == type || !has_stronger_or_equal_type(type))
2808 DBUG_ASSERT(m_type == MDL_EXCLUSIVE ||
2809 m_type == MDL_SHARED_NO_WRITE);
2816 m_lock->m_granted.remove_ticket(
this);
2818 m_lock->m_granted.add_ticket(
this);
2819 m_lock->reschedule_waiters();
2840 const char *db,
const char *
name,
2841 enum_mdl_type mdl_type)
2844 enum_mdl_duration not_unused;
2846 mdl_request.
init(mdl_namespace, db, name, mdl_type, MDL_TRANSACTION);
2847 MDL_ticket *ticket= find_ticket(&mdl_request, ¬_unused);
2849 DBUG_ASSERT(ticket == NULL || ticket->m_lock);
2865 return m_lock->has_pending_conflicting_lock(m_type);
2880 DBUG_ENTER(
"MDL_context::rollback_to_savepoint");
2883 release_locks_stored_before(MDL_STATEMENT, mdl_savepoint.m_stmt_ticket);
2884 release_locks_stored_before(MDL_TRANSACTION, mdl_savepoint.m_trans_ticket);
2901 DBUG_ENTER(
"MDL_context::release_transactional_locks");
2902 release_locks_stored_before(MDL_STATEMENT, NULL);
2903 release_locks_stored_before(MDL_TRANSACTION, NULL);
2908 void MDL_context::release_statement_locks()
2910 DBUG_ENTER(
"MDL_context::release_transactional_locks");
2911 release_locks_stored_before(MDL_STATEMENT, NULL);
2934 while ((ticket= s_it++) && ticket != mdl_savepoint.m_stmt_ticket)
2936 if (ticket == mdl_ticket)
2940 while ((ticket= t_it++) && ticket != mdl_savepoint.m_trans_ticket)
2942 if (ticket == mdl_ticket)
2960 enum_mdl_duration duration)
2962 DBUG_ASSERT(mdl_ticket->m_duration == MDL_TRANSACTION &&
2963 duration != MDL_TRANSACTION);
2965 m_tickets[MDL_TRANSACTION].remove(mdl_ticket);
2966 m_tickets[duration].push_front(mdl_ticket);
2968 mdl_ticket->m_duration= duration;
2991 m_tickets[MDL_EXPLICIT].swap(m_tickets[MDL_TRANSACTION]);
2993 for (i= 0; i < MDL_EXPLICIT; i++)
2997 while ((ticket= it_ticket++))
2999 m_tickets[
i].remove(ticket);
3000 m_tickets[MDL_EXPLICIT].push_front(ticket);
3007 while ((ticket= exp_it++))
3008 ticket->m_duration= MDL_EXPLICIT;
3030 DBUG_ASSERT(m_tickets[MDL_STATEMENT].is_empty());
3032 m_tickets[MDL_TRANSACTION].swap(m_tickets[MDL_EXPLICIT]);
3036 while ((ticket= it_ticket++))
3038 m_tickets[MDL_EXPLICIT].remove(ticket);
3039 m_tickets[MDL_TRANSACTION].push_front(ticket);
3045 while ((ticket= trans_it++))
3046 ticket->m_duration= MDL_TRANSACTION;