summaryrefslogtreecommitdiff
path: root/storage/perfschema/table_threads.cc
diff options
context:
space:
mode:
authorSergei Golubchik <sergii@pisem.net>2014-05-07 10:04:30 +0200
committerSergei Golubchik <sergii@pisem.net>2014-05-07 10:04:30 +0200
commit04bce7b569f44f3aca3cb21953d41c2a4a02efe6 (patch)
tree2530ccd90b42afa39b0a60f4454fd5ddb97c95e1 /storage/perfschema/table_threads.cc
parent7226287c066228a216217c43c48f3a0a833d9909 (diff)
downloadmariadb-git-04bce7b569f44f3aca3cb21953d41c2a4a02efe6.tar.gz
5.6.17
Diffstat (limited to 'storage/perfschema/table_threads.cc')
-rw-r--r--storage/perfschema/table_threads.cc85
1 files changed, 66 insertions, 19 deletions
diff --git a/storage/perfschema/table_threads.cc b/storage/perfschema/table_threads.cc
index b1ec2ad754e..0774858ca92 100644
--- a/storage/perfschema/table_threads.cc
+++ b/storage/perfschema/table_threads.cc
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -129,7 +129,9 @@ table_threads::table_threads()
void table_threads::make_row(PFS_thread *pfs)
{
pfs_lock lock;
- pfs_lock processlist_lock;
+ pfs_lock session_lock;
+ pfs_lock stmt_lock;
+ PFS_stage_class *stage_class;
PFS_thread_class *safe_class;
m_row_exists= false;
@@ -147,6 +149,9 @@ void table_threads::make_row(PFS_thread *pfs)
m_row.m_name= safe_class->m_name;
m_row.m_name_length= safe_class->m_name_length;
+ /* Protect this reader against session attribute changes */
+ pfs->m_session_lock.begin_optimistic_lock(&session_lock);
+
m_row.m_username_length= pfs->m_username_length;
if (unlikely(m_row.m_username_length > sizeof(m_row.m_username)))
return;
@@ -159,38 +164,66 @@ void table_threads::make_row(PFS_thread *pfs)
if (m_row.m_hostname_length != 0)
memcpy(m_row.m_hostname, pfs->m_hostname, m_row.m_hostname_length);
+ if (! pfs->m_session_lock.end_optimistic_lock(& session_lock))
+ {
+ /*
+ One of the columns:
+ - PROCESSLIST_USER
+ - PROCESSLIST_HOST
+ is being updated.
+ Do not discard the entire row.
+ Do not loop waiting for a stable value.
+ Just return NULL values.
+ */
+ m_row.m_username_length= 0;
+ m_row.m_hostname_length= 0;
+ }
+
+ /* Protect this reader against statement attributes changes */
+ pfs->m_stmt_lock.begin_optimistic_lock(&stmt_lock);
+
m_row.m_dbname_length= pfs->m_dbname_length;
if (unlikely(m_row.m_dbname_length > sizeof(m_row.m_dbname)))
return;
if (m_row.m_dbname_length != 0)
memcpy(m_row.m_dbname, pfs->m_dbname, m_row.m_dbname_length);
- m_row.m_command= pfs->m_command;
- m_row.m_start_time= pfs->m_start_time;
-
- /* Protect this reader against attribute changes. */
- pfs->m_processlist_lock.begin_optimistic_lock(&processlist_lock);
-
- /* FIXME: need to copy it ? */
- m_row.m_processlist_state_ptr= pfs->m_processlist_state_ptr;
- m_row.m_processlist_state_length= pfs->m_processlist_state_length;
- /* FIXME: need to copy it ? */
- m_row.m_processlist_info_ptr= pfs->m_processlist_info_ptr;
+ m_row.m_processlist_info_ptr= & pfs->m_processlist_info[0];
m_row.m_processlist_info_length= pfs->m_processlist_info_length;
- if (! pfs->m_processlist_lock.end_optimistic_lock(& processlist_lock))
+ if (! pfs->m_stmt_lock.end_optimistic_lock(& stmt_lock))
{
/*
- Columns PROCESSLIST_STATE or PROCESSLIST_INFO are being
- updated while we read them, and are unsafe to use.
+ One of the columns:
+ - PROCESSLIST_DB
+ - PROCESSLIST_INFO
+ is being updated.
Do not discard the entire row.
Do not loop waiting for a stable value.
- Just return NULL values for these columns.
+ Just return NULL values.
*/
- m_row.m_processlist_state_length= 0;
+ m_row.m_dbname_length= 0;
m_row.m_processlist_info_length= 0;
}
+ /* Dirty read, sanitize the command. */
+ m_row.m_command= pfs->m_command;
+ if ((m_row.m_command < 0) || (m_row.m_command > COM_END))
+ m_row.m_command= COM_END;
+
+ m_row.m_start_time= pfs->m_start_time;
+
+ stage_class= find_stage_class(pfs->m_stage);
+ if (stage_class != NULL)
+ {
+ m_row.m_processlist_state_ptr= stage_class->m_name + stage_class->m_prefix_length;
+ m_row.m_processlist_state_length= stage_class->m_name_length - stage_class->m_prefix_length;
+ }
+ else
+ {
+ m_row.m_processlist_state_length= 0;
+ }
+
m_row.m_enabled_ptr= &pfs->m_enabled;
if (pfs->m_lock.end_optimistic_lock(& lock))
@@ -276,8 +309,22 @@ int table_threads::read_row_values(TABLE *table,
break;
case 9: /* PROCESSLIST_STATE */
if (m_row.m_processlist_state_length > 0)
+ {
+ /* This column's datatype is declared as varchar(64). But in current
+ code, there are few process state messages which are greater than
+ 64 characters(Eg:stage_slave_has_read_all_relay_log).
+ In those cases, we will end up in 'data truncated'
+ warning/error (depends sql_mode setting) when server is updating
+ this column for those threads. Since 5.6 is GAed, neither the
+ metadata of this column can be changed, nor those state messages.
+ So server will silently truncate the state message to 64 characters
+ if it is longer. In Upper versions(5.7+), these state messages are
+ changed to less than or equal to 64 characters.
+ */
set_field_varchar_utf8(f, m_row.m_processlist_state_ptr,
- m_row.m_processlist_state_length);
+ std::min<uint>(m_row.m_processlist_state_length,
+ f->char_length()));
+ }
else
f->set_null();
break;