diff options
author | Sergei Golubchik <sergii@pisem.net> | 2014-05-07 10:04:30 +0200 |
---|---|---|
committer | Sergei Golubchik <sergii@pisem.net> | 2014-05-07 10:04:30 +0200 |
commit | 04bce7b569f44f3aca3cb21953d41c2a4a02efe6 (patch) | |
tree | 2530ccd90b42afa39b0a60f4454fd5ddb97c95e1 /storage/perfschema/table_threads.cc | |
parent | 7226287c066228a216217c43c48f3a0a833d9909 (diff) | |
download | mariadb-git-04bce7b569f44f3aca3cb21953d41c2a4a02efe6.tar.gz |
5.6.17
Diffstat (limited to 'storage/perfschema/table_threads.cc')
-rw-r--r-- | storage/perfschema/table_threads.cc | 85 |
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; |