diff --git a/sql/sql_class.cc b/sql/sql_class.cc index c200dd9..7cee565 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -373,6 +373,8 @@ char *thd_security_context(THD *thd, char *buffer, unsigned int length, const Security_context *sctx= &thd->main_security_ctx; char header[64]; int len; + int err; + /* The pointers thd->query and thd->proc_info might change since they are being modified concurrently. This is acceptable for proc_info since its @@ -414,20 +416,42 @@ char *thd_security_context(THD *thd, char *buffer, unsigned int length, str.append(proc_info); } - pthread_mutex_lock(&thd->LOCK_thd_data); + /* + InnoDB might be holding a big kernel lock like kernel_mutex. Don't + block here to avoid deadlock -- http://bugs.mysql.com/60682 + */ + err= pthread_mutex_trylock(&thd->LOCK_thd_data); + + DBUG_EXECUTE_IF("pretend_thd_security_context_busy", + { if (!err) { + pthread_mutex_unlock(&thd->LOCK_thd_data); + err= EBUSY; + } }); + + if (!err) + { + if (thd->query()) + { + if (max_query_len < 1) + len= thd->query_length(); + else + len= min(thd->query_length(), max_query_len); + str.append('\n'); + str.append(thd->query(), len); + } - if (thd->query()) + pthread_mutex_unlock(&thd->LOCK_thd_data); + } + else { - if (max_query_len < 1) - len= thd->query_length(); - else - len= min(thd->query_length(), max_query_len); + const char* busy_msg= "::BUSY::"; + + DBUG_ASSERT(err == EBUSY); + str.append('\n'); - str.append(thd->query(), len); + str.append(busy_msg, strlen(busy_msg)); } - pthread_mutex_unlock(&thd->LOCK_thd_data); - if (str.c_ptr_safe() == buffer) return buffer;