1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-08 11:22:35 +03:00
This commit is contained in:
Brave Galera Crew
2019-01-23 15:30:00 +04:00
committed by Sergey Vojtovich
parent 382115b992
commit 36a2a185fe
791 changed files with 28035 additions and 8865 deletions

View File

@@ -24,9 +24,6 @@
#include <mysql/plugin.h>
#include <mysql/service_thd_wait.h>
#include <mysql/psi/mysql_stage.h>
#include "wsrep_mysqld.h"
#include "wsrep_thd.h"
#ifdef HAVE_PSI_INTERFACE
static PSI_mutex_key key_MDL_wait_LOCK_wait_status;
@@ -1218,10 +1215,9 @@ void MDL_lock::Ticket_list::add_ticket(MDL_ticket *ticket)
wsrep_thd_is_BF(ticket->get_ctx()->get_thd(), false))
{
Ticket_iterator itw(ticket->get_lock()->m_waiting);
Ticket_iterator itg(ticket->get_lock()->m_granted);
DBUG_ASSERT(WSREP_ON);
MDL_ticket *waiting, *granted;
MDL_ticket *waiting;
MDL_ticket *prev=NULL;
bool added= false;
@@ -1240,20 +1236,8 @@ void MDL_lock::Ticket_list::add_ticket(MDL_ticket *ticket)
}
/* Otherwise, insert the ticket at the back of the waiting list. */
if (!added) m_list.push_back(ticket);
while ((granted= itg++))
{
if (granted->get_ctx() != ticket->get_ctx() &&
granted->is_incompatible_when_granted(ticket->get_type()))
{
if (!wsrep_grant_mdl_exception(ticket->get_ctx(), granted,
&ticket->get_lock()->key))
{
WSREP_DEBUG("MDL victim killed at add_ticket");
}
}
}
if (!added)
m_list.push_back(ticket);
}
else
#endif /* WITH_WSREP */
@@ -1709,6 +1693,12 @@ MDL_lock::MDL_backup_lock::m_waiting_incompatible[MDL_BACKUP_END]=
Check if request for the metadata lock can be satisfied given its
current state.
New lock request can be satisfied iff:
- There are no incompatible types of satisfied requests
in other contexts
- There are no waiting requests which have higher priority
than this request when priority was not ignored.
@param type_arg The requested lock type.
@param requestor_ctx The MDL context of the requestor.
@param ignore_lock_priority Ignore lock priority.
@@ -1726,78 +1716,72 @@ MDL_lock::can_grant_lock(enum_mdl_type type_arg,
MDL_context *requestor_ctx,
bool ignore_lock_priority) const
{
bool can_grant= FALSE;
bitmap_t waiting_incompat_map= incompatible_waiting_types_bitmap()[type_arg];
bitmap_t granted_incompat_map= incompatible_granted_types_bitmap()[type_arg];
bool wsrep_can_grant= TRUE;
/*
New lock request can be satisfied iff:
- There are no incompatible types of satisfied requests
in other contexts
- There are no waiting requests which have higher priority
than this request when priority was not ignored.
*/
if (ignore_lock_priority || !(m_waiting.bitmap() & waiting_incompat_map))
{
if (! (m_granted.bitmap() & granted_incompat_map))
can_grant= TRUE;
else
{
Ticket_iterator it(m_granted);
MDL_ticket *ticket;
/* Check that the incompatible lock belongs to some other context. */
while ((ticket= it++))
{
if (ticket->get_ctx() != requestor_ctx &&
ticket->is_incompatible_when_granted(type_arg))
{
#ifdef WITH_WSREP
if (wsrep_thd_is_BF(requestor_ctx->get_thd(),false) &&
key.mdl_namespace() == MDL_key::BACKUP)
{
WSREP_DEBUG("global lock granted for BF: %lu %s",
thd_get_thread_id(requestor_ctx->get_thd()),
wsrep_thd_query(requestor_ctx->get_thd()));
can_grant = true;
}
else if (!wsrep_grant_mdl_exception(requestor_ctx, ticket, &key))
{
wsrep_can_grant= FALSE;
if (wsrep_log_conflicts)
{
MDL_lock * lock = ticket->get_lock();
WSREP_INFO(
"MDL conflict db=%s table=%s ticket=%d solved by %s",
lock->key.db_name(), lock->key.name(), ticket->get_type(),
"abort" );
}
}
else
can_grant= TRUE;
/* Continue loop */
#else
break;
#endif /* WITH_WSREP */
}
}
if ((ticket == NULL) && wsrep_can_grant)
can_grant= TRUE; /* Incompatible locks are our own. */
}
}
else
/*
Approve lock request in BACKUP namespace for BF threads.
We should get rid of this code and forbid FTWRL/BACKUP statements
when wsrep is active.
*/
if ((wsrep_thd_is_toi(requestor_ctx->get_thd()) ||
wsrep_thd_is_applying(requestor_ctx->get_thd())) &&
key.mdl_namespace() == MDL_key::BACKUP)
{
if (wsrep_thd_is_BF(requestor_ctx->get_thd(), false) &&
key.mdl_namespace() == MDL_key::BACKUP)
bool waiting_incompatible= m_waiting.bitmap() & waiting_incompat_map;
bool granted_incompatible= m_granted.bitmap() & granted_incompat_map;
if (waiting_incompatible || granted_incompatible)
{
WSREP_DEBUG("global lock granted for BF (waiting queue): %lu %s",
WSREP_DEBUG("global lock granted for BF%s: %lu %s",
waiting_incompatible ? " (waiting queue)" : "",
thd_get_thread_id(requestor_ctx->get_thd()),
wsrep_thd_query(requestor_ctx->get_thd()));
can_grant = true;
}
return true;
}
return can_grant;
#endif /* WITH_WSREP */
if (!ignore_lock_priority && (m_waiting.bitmap() & waiting_incompat_map))
return false;
if (m_granted.bitmap() & granted_incompat_map)
{
Ticket_iterator it(m_granted);
bool can_grant= true;
/* Check that the incompatible lock belongs to some other context. */
while (auto ticket= it++)
{
if (ticket->get_ctx() != requestor_ctx &&
ticket->is_incompatible_when_granted(type_arg))
{
can_grant= false;
#ifdef WITH_WSREP
/*
non WSREP threads must report conflict immediately
note: RSU processing wsrep threads, have wsrep_on==OFF
*/
if (WSREP(requestor_ctx->get_thd()) ||
requestor_ctx->get_thd()->wsrep_cs().mode() ==
wsrep::client_state::m_rsu)
{
wsrep_handle_mdl_conflict(requestor_ctx, ticket, &key);
if (wsrep_log_conflicts)
{
auto key= ticket->get_key();
WSREP_INFO("MDL conflict db=%s table=%s ticket=%d solved by abort",
key->db_name(), key->name(), ticket->get_type());
}
continue;
}
#endif /* WITH_WSREP */
break;
}
}
return can_grant;
}
return true;
}