summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksey Midenkov <midenok@gmail.com>2022-06-18 02:19:41 +0300
committerAleksey Midenkov <midenok@gmail.com>2022-06-28 23:36:39 +0300
commitd89cac0884a5fa0c1c66ebd03757a007b8003a20 (patch)
treea44f0eb378e050b9ff43446b58d6317346738b11
parentdbd562787ac652593aacc13eeaa12eb2f06bac24 (diff)
downloadmariadb-git-d89cac0884a5fa0c1c66ebd03757a007b8003a20.tar.gz
MDEV-28567 MDL debug logging
Log MDL state transitions. Trace-friendly message format. DBUG_LOCK_FILE replaced by thread-local storage. Logged states legend: Seized lock was acquired without waiting Waiting lock is waiting Acquired lock was acquired after waiting Released lock was released Deadlock lock was aborted due to deadlock Timeout lock was aborted due to timeout >0 Nowait lock was aborted due to zero timeout Killed lock was aborted due to kill message OOM can not acquire because out of memory Usage: mtr --mysqld=--debug=d,mdl,query:i:o,/tmp/mdl.log Cleanup from garbage messages: sed -i -re \ '/(mysql|performance_schema|sys|mtr)\// d; /MDL_BACKUP_/ d' \ /tmp/mdl.log
-rw-r--r--sql/mdl.cc53
1 files changed, 38 insertions, 15 deletions
diff --git a/sql/mdl.cc b/sql/mdl.cc
index 11bd6f6ed16..f67aa2c2de1 100644
--- a/sql/mdl.cc
+++ b/sql/mdl.cc
@@ -230,25 +230,32 @@ private:
Print a list of all locks to DBUG trace to help with debugging
*/
+const char *dbug_print_mdl(MDL_ticket *mdl_ticket)
+{
+ thread_local char buffer[256];
+ MDL_key *mdl_key= mdl_ticket->get_key();
+ my_snprintf(buffer, sizeof(buffer) - 1, "%.*s/%.*s (%s)",
+ (int) mdl_key->db_name_length(), mdl_key->db_name(),
+ (int) mdl_key->name_length(), mdl_key->name(),
+ mdl_ticket->get_type_name()->str);
+ return buffer;
+}
+
+
static int mdl_dbug_print_lock(MDL_ticket *mdl_ticket, void *arg, bool granted)
{
String *tmp= (String*) arg;
- char buffer[128];
- MDL_key *mdl_key= mdl_ticket->get_key();
- size_t length;
- length= my_snprintf(buffer, sizeof(buffer)-1,
- "\nname: %s db: %.*s key_name: %.*s (%s)",
- mdl_ticket->get_type_name()->str,
- (int) mdl_key->db_name_length(), mdl_key->db_name(),
- (int) mdl_key->name_length(), mdl_key->name(),
- granted ? "granted" : "waiting");
+ char buffer[256];
+ size_t length= my_snprintf(buffer, sizeof(buffer) - 1,
+ "\n %s (%s)", dbug_print_mdl(mdl_ticket),
+ granted ? "granted" : "waiting");
tmp->append(buffer, length);
return 0;
}
const char *mdl_dbug_print_locks()
{
- static String tmp;
+ thread_local String tmp;
mdl_iterate(mdl_dbug_print_lock, (void*) &tmp);
return tmp.c_ptr();
}
@@ -2268,13 +2275,19 @@ MDL_context::acquire_lock(MDL_request *mdl_request, double lock_wait_timeout)
MDL_ticket *ticket;
MDL_wait::enum_wait_status wait_status;
DBUG_ENTER("MDL_context::acquire_lock");
+#ifndef DBUG_OFF
+ const char *mdl_lock_name= get_mdl_lock_name(
+ mdl_request->key.mdl_namespace(), mdl_request->type)->str;
+#endif
DBUG_PRINT("enter", ("lock_type: %s timeout: %f",
- get_mdl_lock_name(mdl_request->key.mdl_namespace(),
- mdl_request->type)->str,
+ mdl_lock_name,
lock_wait_timeout));
if (try_acquire_lock_impl(mdl_request, &ticket))
+ {
+ DBUG_PRINT("mdl", ("OOM: %s", mdl_lock_name));
DBUG_RETURN(TRUE);
+ }
if (mdl_request->ticket)
{
@@ -2284,9 +2297,14 @@ MDL_context::acquire_lock(MDL_request *mdl_request, double lock_wait_timeout)
accordingly, so we can simply return success.
*/
DBUG_PRINT("info", ("Got lock without waiting"));
+ DBUG_PRINT("mdl", ("Seized: %s", dbug_print_mdl(mdl_request->ticket)));
DBUG_RETURN(FALSE);
}
+#ifndef DBUG_OFF
+ const char *ticket_msg= dbug_print_mdl(ticket);
+#endif
+
/*
Our attempt to acquire lock without waiting has failed.
As a result of this attempt we got MDL_ticket with m_lock
@@ -2297,6 +2315,7 @@ MDL_context::acquire_lock(MDL_request *mdl_request, double lock_wait_timeout)
if (lock_wait_timeout == 0)
{
+ DBUG_PRINT("mdl", ("Nowait: %s", ticket_msg));
mysql_prlock_unlock(&lock->m_rwlock);
MDL_ticket::destroy(ticket);
my_error(ER_LOCK_WAIT_TIMEOUT, MYF(0));
@@ -2335,6 +2354,7 @@ MDL_context::acquire_lock(MDL_request *mdl_request, double lock_wait_timeout)
mysql_prlock_unlock(&lock->m_rwlock);
+ DBUG_PRINT("mdl", ("Waiting: %s", ticket_msg));
will_wait_for(ticket);
/* There is a shared or exclusive lock on the object. */
@@ -2387,15 +2407,16 @@ MDL_context::acquire_lock(MDL_request *mdl_request, double lock_wait_timeout)
switch (wait_status)
{
case MDL_wait::VICTIM:
- DBUG_LOCK_FILE;
- DBUG_PRINT("mdl_locks", ("%s", mdl_dbug_print_locks()));
- DBUG_UNLOCK_FILE;
+ DBUG_PRINT("mdl", ("Deadlock: %s", ticket_msg));
+ DBUG_PRINT("mdl_locks", ("Existing locks:%s", mdl_dbug_print_locks()));
my_error(ER_LOCK_DEADLOCK, MYF(0));
break;
case MDL_wait::TIMEOUT:
+ DBUG_PRINT("mdl", ("Timeout: %s", ticket_msg));
my_error(ER_LOCK_WAIT_TIMEOUT, MYF(0));
break;
case MDL_wait::KILLED:
+ DBUG_PRINT("mdl", ("Killed: %s", ticket_msg));
get_thd()->send_kill_message();
break;
default:
@@ -2417,6 +2438,7 @@ MDL_context::acquire_lock(MDL_request *mdl_request, double lock_wait_timeout)
mdl_request->ticket= ticket;
+ DBUG_PRINT("mdl", ("Acquired: %s", ticket_msg));
DBUG_RETURN(FALSE);
}
@@ -2845,6 +2867,7 @@ void MDL_context::release_lock(enum_mdl_duration duration, MDL_ticket *ticket)
lock->key.db_name(), lock->key.name()));
DBUG_ASSERT(this == ticket->get_ctx());
+ DBUG_PRINT("mdl", ("Released: %s", dbug_print_mdl(ticket)));
lock->remove_ticket(m_pins, &MDL_lock::m_granted, ticket);