summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNirbhay Choubey <nirbhay@mariadb.com>2016-07-30 14:36:41 -0400
committerNirbhay Choubey <nirbhay@mariadb.com>2016-07-30 14:36:41 -0400
commit355bf4fbb52123dc1c81d88c31844cdd1ea4f824 (patch)
tree18a48faced145a0f79970080e7dc2e0ded7d5bbf
parentfb076581f6eeeb931108b689211cbc662e35478f (diff)
downloadmariadb-git-355bf4fbb52123dc1c81d88c31844cdd1ea4f824.tar.gz
Cleanup around wsrep mdl exception.
-rw-r--r--sql/mdl.cc74
-rw-r--r--sql/wsrep_mysqld.cc82
2 files changed, 98 insertions, 58 deletions
diff --git a/sql/mdl.cc b/sql/mdl.cc
index cb616c30b1e..8fec368e3be 100644
--- a/sql/mdl.cc
+++ b/sql/mdl.cc
@@ -2929,34 +2929,54 @@ bool MDL_context::has_explicit_locks()
}
#ifdef WITH_WSREP
-void MDL_ticket::wsrep_report(bool debug)
+static
+const char *wsrep_get_mdl_type_name(enum_mdl_type type)
{
- if (debug)
+ switch (type)
{
- const PSI_stage_info *psi_stage = m_lock->key.get_wait_state_name();
-
- WSREP_DEBUG("MDL ticket: type: %s space: %s db: %s name: %s (%s)",
- (get_type() == MDL_INTENTION_EXCLUSIVE) ? "intention exclusive" :
- ((get_type() == MDL_SHARED) ? "shared" :
- ((get_type() == MDL_SHARED_HIGH_PRIO ? "shared high prio" :
- ((get_type() == MDL_SHARED_READ) ? "shared read" :
- ((get_type() == MDL_SHARED_WRITE) ? "shared write" :
- ((get_type() == MDL_SHARED_NO_WRITE) ? "shared no write" :
- ((get_type() == MDL_SHARED_NO_READ_WRITE) ? "shared no read write" :
- ((get_type() == MDL_EXCLUSIVE) ? "exclusive" :
- "UNKNOWN")))))))),
- (m_lock->key.mdl_namespace() == MDL_key::GLOBAL) ? "GLOBAL" :
- ((m_lock->key.mdl_namespace() == MDL_key::SCHEMA) ? "SCHEMA" :
- ((m_lock->key.mdl_namespace() == MDL_key::TABLE) ? "TABLE" :
- ((m_lock->key.mdl_namespace() == MDL_key::TABLE) ? "FUNCTION" :
- ((m_lock->key.mdl_namespace() == MDL_key::TABLE) ? "PROCEDURE" :
- ((m_lock->key.mdl_namespace() == MDL_key::TABLE) ? "TRIGGER" :
- ((m_lock->key.mdl_namespace() == MDL_key::TABLE) ? "EVENT" :
- ((m_lock->key.mdl_namespace() == MDL_key::COMMIT) ? "COMMIT" :
- (char *)"UNKNOWN"))))))),
- m_lock->key.db_name(),
- m_lock->key.name(),
- psi_stage->m_name);
- }
+ case MDL_INTENTION_EXCLUSIVE : return "intention exclusive";
+ case MDL_SHARED : return "shared";
+ case MDL_SHARED_HIGH_PRIO : return "shared high prio";
+ case MDL_SHARED_READ : return "shared read";
+ case MDL_SHARED_WRITE : return "shared write";
+ case MDL_SHARED_UPGRADABLE : return "shared upgradable";
+ case MDL_SHARED_NO_WRITE : return "shared no write";
+ case MDL_SHARED_NO_READ_WRITE : return "shared no read write";
+ case MDL_EXCLUSIVE : return "exclusive";
+ default: break;
+ }
+ return "UNKNOWN";
+}
+
+static
+const char *wsrep_get_mdl_namespace_name(MDL_key::enum_mdl_namespace ns)
+{
+ switch (ns)
+ {
+ case MDL_key::GLOBAL : return "GLOBAL";
+ case MDL_key::SCHEMA : return "SCHEMA";
+ case MDL_key::TABLE : return "TABLE";
+ case MDL_key::FUNCTION : return "FUNCTION";
+ case MDL_key::PROCEDURE : return "PROCEDURE";
+ case MDL_key::TRIGGER : return "TRIGGER";
+ case MDL_key::EVENT : return "EVENT";
+ case MDL_key::COMMIT : return "COMMIT";
+ case MDL_key::USER_LOCK : return "USER_LOCK";
+ default: break;
+ }
+ return "UNKNOWN";
+}
+
+void MDL_ticket::wsrep_report(bool debug)
+{
+ if (!debug) return;
+
+ const PSI_stage_info *psi_stage= m_lock->key.get_wait_state_name();
+ WSREP_DEBUG("MDL ticket: type: %s space: %s db: %s name: %s (%s)",
+ wsrep_get_mdl_type_name(get_type()),
+ wsrep_get_mdl_namespace_name(m_lock->key.mdl_namespace()),
+ m_lock->key.db_name(),
+ m_lock->key.name(),
+ psi_stage->m_name);
}
#endif /* WITH_WSREP */
diff --git a/sql/wsrep_mysqld.cc b/sql/wsrep_mysqld.cc
index e3b503a82fb..c00c7bf82db 100644
--- a/sql/wsrep_mysqld.cc
+++ b/sql/wsrep_mysqld.cc
@@ -1684,22 +1684,41 @@ void wsrep_to_isolation_end(THD *thd)
@retval FALSE Lock request cannot be granted
*/
-bool
-wsrep_grant_mdl_exception(MDL_context *requestor_ctx,
- MDL_ticket *ticket,
- const MDL_key *key
-) {
+bool wsrep_grant_mdl_exception(MDL_context *requestor_ctx,
+ MDL_ticket *ticket,
+ const MDL_key *key)
+{
/* Fallback to the non-wsrep behaviour */
if (!WSREP_ON) return FALSE;
- THD *request_thd = requestor_ctx->get_thd();
- THD *granted_thd = ticket->get_ctx()->get_thd();
- bool ret = FALSE;
+ THD *request_thd= requestor_ctx->get_thd();
+ THD *granted_thd= ticket->get_ctx()->get_thd();
+ bool ret= false;
const char* schema= key->db_name();
int schema_len= key->db_name_length();
mysql_mutex_lock(&request_thd->LOCK_wsrep_thd);
+
+ /*
+ We consider granting MDL exceptions only for appliers (BF THD) and ones
+ executing under TOI mode.
+
+ Rules:
+ 1. If granted/owner THD is also an applier (BF THD) or one executing
+ under TOI mode, then we grant the requested lock to the requester
+ THD.
+ @return true
+
+ 2. If granted/owner THD is executing a FLUSH command or already has an
+ explicit lock, then do not grant the requested lock to the requester
+ THD and it has to wait.
+ @return false
+
+ 3. In all other cases the granted/owner THD is aborted and the requested
+ lock is not granted to the requester THD, thus it has to wait.
+ @return false
+ */
if (request_thd->wsrep_exec_mode == TOTAL_ORDER ||
request_thd->wsrep_exec_mode == REPL_RECV)
{
@@ -1716,7 +1735,7 @@ wsrep_grant_mdl_exception(MDL_context *requestor_ctx,
request_thd, granted_thd);
ticket->wsrep_report(true);
mysql_mutex_unlock(&granted_thd->LOCK_wsrep_thd);
- ret = TRUE;
+ ret= true;
}
else if (granted_thd->lex->sql_command == SQLCOM_FLUSH ||
granted_thd->mdl_context.has_explicit_locks())
@@ -1724,38 +1743,39 @@ wsrep_grant_mdl_exception(MDL_context *requestor_ctx,
WSREP_DEBUG("BF thread waiting for FLUSH");
ticket->wsrep_report(wsrep_debug);
mysql_mutex_unlock(&granted_thd->LOCK_wsrep_thd);
- ret = FALSE;
- }
- else if (request_thd->lex->sql_command == SQLCOM_DROP_TABLE)
- {
- WSREP_DEBUG("DROP caused BF abort");
- ticket->wsrep_report(wsrep_debug);
- mysql_mutex_unlock(&granted_thd->LOCK_wsrep_thd);
- wsrep_abort_thd((void*)request_thd, (void*)granted_thd, 1);
- ret = FALSE;
- }
- else if (granted_thd->wsrep_query_state == QUERY_COMMITTING)
- {
- WSREP_DEBUG("MDL granted, but committing thd abort scheduled");
- ticket->wsrep_report(wsrep_debug);
- mysql_mutex_unlock(&granted_thd->LOCK_wsrep_thd);
- wsrep_abort_thd((void*)request_thd, (void*)granted_thd, 1);
- ret = FALSE;
+ ret= false;
}
else
{
- WSREP_MDL_LOG(DEBUG, "MDL conflict-> BF abort", schema, schema_len,
- request_thd, granted_thd);
- ticket->wsrep_report(wsrep_debug);
+ /* Print some debug information. */
+ if (wsrep_debug)
+ {
+ if ((request_thd->lex->sql_command == SQLCOM_DROP_TABLE))
+ {
+ WSREP_DEBUG("DROP caused BF abort");
+ }
+ else if ((granted_thd->wsrep_query_state == QUERY_COMMITTING))
+ {
+ WSREP_DEBUG("MDL granted, but committing thd abort scheduled");
+ }
+ else
+ {
+ WSREP_MDL_LOG(DEBUG, "MDL conflict-> BF abort", schema, schema_len,
+ request_thd, granted_thd);
+ }
+ ticket->wsrep_report(true);
+ }
+
mysql_mutex_unlock(&granted_thd->LOCK_wsrep_thd);
- wsrep_abort_thd((void*)request_thd, (void*)granted_thd, 1);
- ret = FALSE;
+ wsrep_abort_thd((void *) request_thd, (void *) granted_thd, 1);
+ ret= false;
}
}
else
{
mysql_mutex_unlock(&request_thd->LOCK_wsrep_thd);
}
+
return ret;
}