summaryrefslogtreecommitdiff
path: root/sql/sql_show.cc
diff options
context:
space:
mode:
authorSergei Golubchik <serg@mariadb.org>2018-06-12 12:37:28 +0200
committerSergei Golubchik <serg@mariadb.org>2018-06-13 20:26:51 +0200
commit51254da52c144781695250a98f365fbc090ef619 (patch)
treee29a844eafdcea467d57682172b9b4beac47c2bd /sql/sql_show.cc
parentd2e1ed8b936a78ceeec0e64231997d7ed18a4daf (diff)
downloadmariadb-git-51254da52c144781695250a98f365fbc090ef619.tar.gz
MDEV-15359 Thread stay in "cleaning up" status after finishing
make thd_get_error_context_description() to show not just thd->proc_info, but exactly the same thread state that SHOW PROCESSLIST shows.
Diffstat (limited to 'sql/sql_show.cc')
-rw-r--r--sql/sql_show.cc85
1 files changed, 85 insertions, 0 deletions
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index 965bed80148..d7641a6a96d 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -9773,3 +9773,88 @@ static void get_cs_converted_string_value(THD *thd,
return;
}
#endif
+
+/**
+ Dumps a text description of a thread, its security context
+ (user, host) and the current query.
+
+ @param thd thread context
+ @param buffer pointer to preferred result buffer
+ @param length length of buffer
+ @param max_query_len how many chars of query to copy (0 for all)
+
+ @return Pointer to string
+*/
+
+extern "C"
+char *thd_get_error_context_description(THD *thd, char *buffer,
+ unsigned int length,
+ unsigned int max_query_len)
+{
+ String str(buffer, length, &my_charset_latin1);
+ const Security_context *sctx= &thd->main_security_ctx;
+ char header[256];
+ int len;
+
+ mysql_mutex_lock(&LOCK_thread_count);
+
+ len= my_snprintf(header, sizeof(header),
+ "MySQL thread id %lu, OS thread handle 0x%lx, query id %lu",
+ thd->thread_id, (ulong) thd->real_id, (ulong) thd->query_id);
+ str.length(0);
+ str.append(header, len);
+
+ if (sctx->host)
+ {
+ str.append(' ');
+ str.append(sctx->host);
+ }
+
+ if (sctx->ip)
+ {
+ str.append(' ');
+ str.append(sctx->ip);
+ }
+
+ if (sctx->user)
+ {
+ str.append(' ');
+ str.append(sctx->user);
+ }
+
+ /* Don't wait if LOCK_thd_data is used as this could cause a deadlock */
+ if (!mysql_mutex_trylock(&thd->LOCK_thd_data))
+ {
+ if (const char *info= thread_state_info(thd))
+ {
+ str.append(' ');
+ str.append(info);
+ }
+
+ if (thd->query())
+ {
+ if (max_query_len < 1)
+ len= thd->query_length();
+ else
+ len= MY_MIN(thd->query_length(), max_query_len);
+ str.append('\n');
+ str.append(thd->query(), len);
+ }
+ mysql_mutex_unlock(&thd->LOCK_thd_data);
+ }
+ mysql_mutex_unlock(&LOCK_thread_count);
+
+ if (str.c_ptr_safe() == buffer)
+ return buffer;
+
+ /*
+ We have to copy the new string to the destination buffer because the string
+ was reallocated to a larger buffer to be able to fit.
+ */
+ DBUG_ASSERT(buffer != NULL);
+ length= MY_MIN(str.length(), length-1);
+ memcpy(buffer, str.c_ptr_quick(), length);
+ /* Make sure that the new string is null terminated */
+ buffer[length]= '\0';
+ return buffer;
+}