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 | |
parent | 7226287c066228a216217c43c48f3a0a833d9909 (diff) | |
download | mariadb-git-04bce7b569f44f3aca3cb21953d41c2a4a02efe6.tar.gz |
5.6.17
Diffstat (limited to 'storage/perfschema')
77 files changed, 972 insertions, 442 deletions
diff --git a/storage/perfschema/cursor_by_account.cc b/storage/perfschema/cursor_by_account.cc index 91e9e3c6e54..6be69f803b2 100644 --- a/storage/perfschema/cursor_by_account.cc +++ b/storage/perfschema/cursor_by_account.cc @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ /** @file storage/perfschema/cursor_by_account.cc diff --git a/storage/perfschema/cursor_by_account.h b/storage/perfschema/cursor_by_account.h index 98321df5751..ac52ada880d 100644 --- a/storage/perfschema/cursor_by_account.h +++ b/storage/perfschema/cursor_by_account.h @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef CURSOR_BY_ACCOUNT_H #define CURSOR_BY_ACCOUNT_H diff --git a/storage/perfschema/cursor_by_host.cc b/storage/perfschema/cursor_by_host.cc index f62005511bf..e405bcad7e6 100644 --- a/storage/perfschema/cursor_by_host.cc +++ b/storage/perfschema/cursor_by_host.cc @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ /** @file storage/perfschema/cursor_by_host.cc diff --git a/storage/perfschema/cursor_by_host.h b/storage/perfschema/cursor_by_host.h index 3fbd09e3018..c0db4c5bf0c 100644 --- a/storage/perfschema/cursor_by_host.h +++ b/storage/perfschema/cursor_by_host.h @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef CURSOR_BY_HOST_H #define CURSOR_BY_HOST_H diff --git a/storage/perfschema/cursor_by_thread.cc b/storage/perfschema/cursor_by_thread.cc index 06ee2f6cbef..400e4bd238c 100644 --- a/storage/perfschema/cursor_by_thread.cc +++ b/storage/perfschema/cursor_by_thread.cc @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ /** @file storage/perfschema/cursor_by_thread.cc diff --git a/storage/perfschema/cursor_by_thread.h b/storage/perfschema/cursor_by_thread.h index 8f2edef6b7e..a671e0edd42 100644 --- a/storage/perfschema/cursor_by_thread.h +++ b/storage/perfschema/cursor_by_thread.h @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef CURSOR_BY_THREAD_H #define CURSOR_BY_THREAD_H diff --git a/storage/perfschema/cursor_by_user.cc b/storage/perfschema/cursor_by_user.cc index 8f8fe99f513..d50a6dde1e2 100644 --- a/storage/perfschema/cursor_by_user.cc +++ b/storage/perfschema/cursor_by_user.cc @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ /** @file storage/perfschema/cursor_by_user.cc diff --git a/storage/perfschema/cursor_by_user.h b/storage/perfschema/cursor_by_user.h index c4f9cabc2dd..c37bb8aa518 100644 --- a/storage/perfschema/cursor_by_user.h +++ b/storage/perfschema/cursor_by_user.h @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef CURSOR_BY_USER_H #define CURSOR_BY_USER_H diff --git a/storage/perfschema/ha_perfschema.cc b/storage/perfschema/ha_perfschema.cc index 3f9c9cf6081..285768be49d 100644 --- a/storage/perfschema/ha_perfschema.cc +++ b/storage/perfschema/ha_perfschema.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2008, 2011, 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 @@ -265,7 +265,10 @@ int ha_perfschema::update_row(const uchar *old_data, uchar *new_data) DBUG_ENTER("ha_perfschema::update_row"); if (!pfs_initialized) DBUG_RETURN(HA_ERR_WRONG_COMMAND); - + + if (is_executed_by_slave()) + DBUG_RETURN(0); + DBUG_ASSERT(m_table); ha_statistic_increment(&SSV::ha_update_count); int result= m_table->update_row(table, old_data, new_data, table->field); @@ -318,7 +321,10 @@ int ha_perfschema::rnd_next(uchar *buf) { DBUG_ENTER("ha_perfschema::rnd_next"); if (!pfs_initialized) + { + table->status= STATUS_NOT_FOUND; DBUG_RETURN(HA_ERR_END_OF_FILE); + } DBUG_ASSERT(m_table); ha_statistic_increment(&SSV::ha_read_rnd_next_count); @@ -330,6 +336,7 @@ int ha_perfschema::rnd_next(uchar *buf) if (result == 0) stats.records++; } + table->status= (result ? STATUS_NOT_FOUND : 0); DBUG_RETURN(result); } @@ -346,13 +353,17 @@ int ha_perfschema::rnd_pos(uchar *buf, uchar *pos) { DBUG_ENTER("ha_perfschema::rnd_pos"); if (!pfs_initialized) + { + table->status= STATUS_NOT_FOUND; DBUG_RETURN(HA_ERR_END_OF_FILE); + } DBUG_ASSERT(m_table); ha_statistic_increment(&SSV::ha_read_rnd_count); int result= m_table->rnd_pos(pos); if (result == 0) result= m_table->read_row(table, buf, table->field); + table->status= (result ? STATUS_NOT_FOUND : 0); DBUG_RETURN(result); } @@ -375,6 +386,9 @@ int ha_perfschema::delete_all_rows(void) if (!pfs_initialized) DBUG_RETURN(0); + if (is_executed_by_slave()) + DBUG_RETURN(0); + DBUG_ASSERT(m_table_share); if (m_table_share->m_delete_all_rows) result= m_table_share->m_delete_all_rows(); diff --git a/storage/perfschema/ha_perfschema.h b/storage/perfschema/ha_perfschema.h index 8e98341a790..481d663f8e4 100644 --- a/storage/perfschema/ha_perfschema.h +++ b/storage/perfschema/ha_perfschema.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2008, 2011, 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 @@ -17,6 +17,8 @@ #define HA_PERFSCHEMA_H #include "handler.h" /* class handler */ +#include "table.h" +#include "sql_class.h" /** @file storage/perfschema/ha_perfschema.h @@ -199,6 +201,39 @@ public: virtual void print_error(int error, myf errflags); private: + /** + Check if the caller is a replication thread or the caller is called + by a client thread executing base64 encoded BINLOG'... statement. + + In theory, performance schema tables are not supposed to be replicated. + This is true and enforced starting with MySQL 5.6.10. + In practice, in previous versions such as MySQL 5.5 (GA) or earlier 5.6 + (non GA) DML on performance schema tables could end up written in the binlog, + both in STATEMENT and ROW format. + While these records are not supposed to be there, they are found when: + - performing replication from a 5.5 master to a 5.6 slave during + upgrades + - performing replication from 5.5 (performance_schema enabled) + to a 5.6 slave + - performing point in time recovery in 5.6 with old archived logs. + + This API detects when the code calling the performance schema storage + engine is a slave thread or whether the code calling isthe client thread + executing a BINLOG'.. statement. + + This API acts as a late filter for the above mentioned cases. + + For ROW format, @see Rows_log_event::do_apply_event() + + */ + bool is_executed_by_slave() const + { + DBUG_ASSERT(table != NULL); + DBUG_ASSERT(table->in_use != NULL); + return table->in_use->slave_thread; + + } + /** MySQL lock */ THR_LOCK_DATA m_thr_lock; /** Performance schema table share for this table handler. */ diff --git a/storage/perfschema/pfs.cc b/storage/perfschema/pfs.cc index 4a0973698ac..876baa47fa6 100644 --- a/storage/perfschema/pfs.cc +++ b/storage/perfschema/pfs.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 @@ -1408,7 +1408,9 @@ static void register_stage_v1(const char *category, if (likely(full_length <= PFS_MAX_INFO_NAME_LENGTH)) { memcpy(formatted_name + prefix_length, info->m_name, len); - info->m_key= register_stage_class(formatted_name, full_length, + info->m_key= register_stage_class(formatted_name, + prefix_length, + full_length, info->m_flags); } else @@ -1706,6 +1708,8 @@ rebind_table_v1(PSI_table_share *share, const void *identity, PSI_table *table) return NULL; PFS_thread *thread= my_pthread_getspecific_ptr(PFS_thread*, THR_PFS); + if (unlikely(thread == NULL)) + return NULL; PFS_table *pfs_table= create_table(pfs_table_share, thread, identity); return reinterpret_cast<PSI_table *> (pfs_table); @@ -1796,7 +1800,12 @@ static void create_file_v1(PSI_file_key key, const char *name, File file) */ struct PFS_spawn_thread_arg { - PFS_thread *m_parent_thread; + ulonglong m_thread_internal_id; + char m_username[USERNAME_LENGTH]; + uint m_username_length; + char m_hostname[HOSTNAME_LENGTH]; + uint m_hostname_length; + PSI_thread_key m_child_key; const void *m_child_identity; void *(*m_user_start_routine)(void*); @@ -1818,17 +1827,15 @@ void* pfs_spawn_thread(void *arg) pfs= create_thread(klass, typed_arg->m_child_identity, 0); if (likely(pfs != NULL)) { - PFS_thread *parent= typed_arg->m_parent_thread; - clear_thread_account(pfs); - pfs->m_parent_thread_internal_id= parent->m_thread_internal_id; + pfs->m_parent_thread_internal_id= typed_arg->m_thread_internal_id; - memcpy(pfs->m_username, parent->m_username, sizeof(pfs->m_username)); - pfs->m_username_length= parent->m_username_length; + memcpy(pfs->m_username, typed_arg->m_username, sizeof(pfs->m_username)); + pfs->m_username_length= typed_arg->m_username_length; - memcpy(pfs->m_hostname, parent->m_hostname, sizeof(pfs->m_hostname)); - pfs->m_hostname_length= parent->m_hostname_length; + memcpy(pfs->m_hostname, typed_arg->m_hostname, sizeof(pfs->m_hostname)); + pfs->m_hostname_length= typed_arg->m_hostname_length; set_thread_account(pfs); } @@ -1864,6 +1871,7 @@ static int spawn_thread_v1(PSI_thread_key key, void *(*start_routine)(void*), void *arg) { PFS_spawn_thread_arg *psi_arg; + PFS_thread *parent; /* psi_arg can not be global, and can not be a local variable. */ psi_arg= (PFS_spawn_thread_arg*) my_malloc(sizeof(PFS_spawn_thread_arg), @@ -1871,12 +1879,34 @@ static int spawn_thread_v1(PSI_thread_key key, if (unlikely(psi_arg == NULL)) return EAGAIN; - psi_arg->m_parent_thread= my_pthread_getspecific_ptr(PFS_thread*, THR_PFS); psi_arg->m_child_key= key; psi_arg->m_child_identity= (arg ? arg : thread); psi_arg->m_user_start_routine= start_routine; psi_arg->m_user_arg= arg; + parent= my_pthread_getspecific_ptr(PFS_thread*, THR_PFS); + if (parent != NULL) + { + /* + Make a copy of the parent attributes. + This is required, because instrumentation for this thread (the parent) + may be destroyed before the child thread instrumentation is created. + */ + psi_arg->m_thread_internal_id= parent->m_thread_internal_id; + + memcpy(psi_arg->m_username, parent->m_username, sizeof(psi_arg->m_username)); + psi_arg->m_username_length= parent->m_username_length; + + memcpy(psi_arg->m_hostname, parent->m_hostname, sizeof(psi_arg->m_hostname)); + psi_arg->m_hostname_length= parent->m_hostname_length; + } + else + { + psi_arg->m_thread_internal_id= 0; + psi_arg->m_username_length= 0; + psi_arg->m_hostname_length= 0; + } + int result= pthread_create(thread, attr, pfs_spawn_thread, psi_arg); if (unlikely(result != 0)) my_free(psi_arg); @@ -1939,9 +1969,9 @@ static void set_thread_user_v1(const char *user, int user_len) if (unlikely(pfs == NULL)) return; - aggregate_thread(pfs); + aggregate_thread(pfs, pfs->m_account, pfs->m_user, pfs->m_host); - pfs->m_lock.allocated_to_dirty(); + pfs->m_session_lock.allocated_to_dirty(); clear_thread_account(pfs); @@ -1971,7 +2001,7 @@ static void set_thread_user_v1(const char *user, int user_len) pfs->m_enabled= enabled; - pfs->m_lock.dirty_to_allocated(); + pfs->m_session_lock.dirty_to_allocated(); } /** @@ -1993,7 +2023,7 @@ static void set_thread_account_v1(const char *user, int user_len, if (unlikely(pfs == NULL)) return; - pfs->m_lock.allocated_to_dirty(); + pfs->m_session_lock.allocated_to_dirty(); clear_thread_account(pfs); @@ -2026,7 +2056,7 @@ static void set_thread_account_v1(const char *user, int user_len, } pfs->m_enabled= enabled; - pfs->m_lock.dirty_to_allocated(); + pfs->m_session_lock.dirty_to_allocated(); } /** @@ -2043,11 +2073,11 @@ static void set_thread_db_v1(const char* db, int db_len) if (likely(pfs != NULL)) { - pfs->m_lock.allocated_to_dirty(); + pfs->m_stmt_lock.allocated_to_dirty(); if (db_len > 0) memcpy(pfs->m_dbname, db, db_len); pfs->m_dbname_length= db_len; - pfs->m_lock.dirty_to_allocated(); + pfs->m_stmt_lock.dirty_to_allocated(); } } @@ -2064,9 +2094,7 @@ static void set_thread_command_v1(int command) if (likely(pfs != NULL)) { - pfs->m_lock.allocated_to_dirty(); pfs->m_command= command; - pfs->m_lock.dirty_to_allocated(); } } @@ -2080,9 +2108,7 @@ static void set_thread_start_time_v1(time_t start_time) if (likely(pfs != NULL)) { - pfs->m_lock.allocated_to_dirty(); pfs->m_start_time= start_time; - pfs->m_lock.dirty_to_allocated(); } } @@ -2092,24 +2118,14 @@ static void set_thread_start_time_v1(time_t start_time) */ static void set_thread_state_v1(const char* state) { - PFS_thread *pfs= my_pthread_getspecific_ptr(PFS_thread*, THR_PFS); - - if (likely(pfs != NULL)) - { - int state_len= state ? strlen(state) : 0; - - pfs->m_processlist_lock.allocated_to_dirty(); - pfs->m_processlist_state_ptr= state; - pfs->m_processlist_state_length= state_len; - pfs->m_processlist_lock.dirty_to_allocated(); - } + /* DEPRECATED. */ } /** Implementation of the thread instrumentation interface. @sa PSI_v1::set_thread_info. */ -static void set_thread_info_v1(const char* info, int info_len) +static void set_thread_info_v1(const char* info, uint info_len) { PFS_thread *pfs= my_pthread_getspecific_ptr(PFS_thread*, THR_PFS); @@ -2117,10 +2133,22 @@ static void set_thread_info_v1(const char* info, int info_len) if (likely(pfs != NULL)) { - pfs->m_processlist_lock.allocated_to_dirty(); - pfs->m_processlist_info_ptr= info; - pfs->m_processlist_info_length= info_len; - pfs->m_processlist_lock.dirty_to_allocated(); + if ((info != NULL) && (info_len > 0)) + { + if (info_len > sizeof(pfs->m_processlist_info)) + info_len= sizeof(pfs->m_processlist_info); + + pfs->m_stmt_lock.allocated_to_dirty(); + memcpy(pfs->m_processlist_info, info, info_len); + pfs->m_processlist_info_length= info_len; + pfs->m_stmt_lock.dirty_to_allocated(); + } + else + { + pfs->m_stmt_lock.allocated_to_dirty(); + pfs->m_processlist_info_length= 0; + pfs->m_stmt_lock.dirty_to_allocated(); + } } } @@ -2143,7 +2171,7 @@ static void delete_current_thread_v1(void) PFS_thread *thread= my_pthread_getspecific_ptr(PFS_thread*, THR_PFS); if (thread != NULL) { - aggregate_thread(thread); + aggregate_thread(thread, thread->m_account, thread->m_user, thread->m_host); my_pthread_setspecific_ptr(THR_PFS, NULL); destroy_thread(thread); } @@ -2159,7 +2187,7 @@ static void delete_thread_v1(PSI_thread *thread) if (pfs != NULL) { - aggregate_thread(pfs); + aggregate_thread(pfs, pfs->m_account, pfs->m_user, pfs->m_host); destroy_thread(pfs); } } @@ -3302,6 +3330,8 @@ start_idle_wait_v1(PSI_idle_locker_state* state, const char *src_file, uint src_ state->m_thread= reinterpret_cast<PSI_thread *> (pfs_thread); flags= STATE_FLAG_THREAD; + DBUG_ASSERT(pfs_thread->m_events_statements_count == 0); + if (global_idle_class.m_timed) { timer_start= get_timer_raw_value_and_function(idle_timer, &state->m_timer); @@ -4194,13 +4224,16 @@ static void start_stage_v1(PSI_stage_key key, const char *src_file, int src_line { ulonglong timer_value= 0; - if (! flag_global_instrumentation) - return; - PFS_thread *pfs_thread= my_pthread_getspecific_ptr(PFS_thread*, THR_PFS); if (unlikely(pfs_thread == NULL)) return; + /* Always update column threads.processlist_state. */ + pfs_thread->m_stage= key; + + if (! flag_global_instrumentation) + return; + if (flag_thread_instrumentation && ! pfs_thread->m_enabled) return; @@ -4209,7 +4242,7 @@ static void start_stage_v1(PSI_stage_key key, const char *src_file, int src_line PFS_events_statements *parent_statement= & pfs_thread->m_statement_stack[0]; PFS_instr_class *old_class= pfs->m_class; - if (likely(old_class != NULL)) + if (old_class != NULL) { PFS_stage_stat *event_name_array; event_name_array= pfs_thread->m_instr_class_stages_stats; @@ -4292,20 +4325,22 @@ static void end_stage_v1() { ulonglong timer_value= 0; - if (! flag_global_instrumentation) - return; - PFS_thread *pfs_thread= my_pthread_getspecific_ptr(PFS_thread*, THR_PFS); if (unlikely(pfs_thread == NULL)) return; + pfs_thread->m_stage= 0; + + if (! flag_global_instrumentation) + return; + if (flag_thread_instrumentation && ! pfs_thread->m_enabled) return; PFS_events_stages *pfs= & pfs_thread->m_stage_current; PFS_instr_class *old_class= pfs->m_class; - if (likely(old_class != NULL)) + if (old_class != NULL) { PFS_stage_stat *event_name_array; event_name_array= pfs_thread->m_instr_class_stages_stats; @@ -4385,6 +4420,7 @@ get_thread_statement_locker_v1(PSI_statement_locker_state *state, return NULL; } + pfs_thread->m_stmt_lock.allocated_to_dirty(); PFS_events_statements *pfs= & pfs_thread->m_statement_stack[pfs_thread->m_events_statements_count]; /* m_thread_internal_id is immutable and already set */ DBUG_ASSERT(pfs->m_thread_internal_id == pfs_thread->m_thread_internal_id); @@ -4435,6 +4471,7 @@ get_thread_statement_locker_v1(PSI_statement_locker_state *state, flags|= STATE_FLAG_EVENT; pfs_thread->m_events_statements_count++; + pfs_thread->m_stmt_lock.dirty_to_allocated(); } } else @@ -4491,23 +4528,26 @@ refine_statement_v1(PSI_statement_locker *locker, PFS_statement_class *klass; /* Only refine statements for mutable instrumentation */ klass= reinterpret_cast<PFS_statement_class*> (state->m_class); - DBUG_ASSERT(klass->m_flags & PSI_FLAG_MUTABLE); + DBUG_ASSERT(klass->is_mutable()); klass= find_statement_class(key); - if (unlikely(klass == NULL)) - { - /* FIXME : pop statement stack */ - state->m_discarded= true; - return NULL; - } - if (! klass->m_enabled) + + uint flags= state->m_flags; + + if (unlikely(klass == NULL) || !klass->m_enabled) { - /* FIXME : pop statement stack */ + /* pop statement stack */ + if (flags & STATE_FLAG_THREAD) + { + PFS_thread *pfs_thread= reinterpret_cast<PFS_thread *> (state->m_thread); + DBUG_ASSERT(pfs_thread != NULL); + if (pfs_thread->m_events_statements_count > 0) + pfs_thread->m_events_statements_count--; + } + state->m_discarded= true; return NULL; } - register uint flags= state->m_flags; - if ((flags & STATE_FLAG_TIMED) && ! klass->m_timed) flags= flags & ~STATE_FLAG_TIMED; @@ -4770,6 +4810,8 @@ static void end_statement_v1(PSI_statement_locker *locker, void *stmt_da) PFS_events_statements *pfs= reinterpret_cast<PFS_events_statements*> (state->m_statement); DBUG_ASSERT(pfs != NULL); + thread->m_stmt_lock.allocated_to_dirty(); + switch(da->status()) { case Diagnostics_area::DA_EMPTY: @@ -4815,6 +4857,7 @@ static void end_statement_v1(PSI_statement_locker *locker, void *stmt_da) DBUG_ASSERT(thread->m_events_statements_count > 0); thread->m_events_statements_count--; + thread->m_stmt_lock.dirty_to_allocated(); } } else @@ -5078,22 +5121,22 @@ static int set_thread_connect_attrs_v1(const char *buffer, uint length, if (likely(thd != NULL) && session_connect_attrs_size_per_thread > 0) { + const CHARSET_INFO *cs = static_cast<const CHARSET_INFO *> (from_cs); + /* copy from the input buffer as much as we can fit */ uint copy_size= (uint)(length < session_connect_attrs_size_per_thread ? length : session_connect_attrs_size_per_thread); - thd->m_lock.allocated_to_dirty(); + thd->m_session_lock.allocated_to_dirty(); memcpy(thd->m_session_connect_attrs, buffer, copy_size); thd->m_session_connect_attrs_length= copy_size; - thd->m_session_connect_attrs_cs= (const CHARSET_INFO *) from_cs; - thd->m_lock.dirty_to_allocated(); - + thd->m_session_connect_attrs_cs_number= cs->number; + thd->m_session_lock.dirty_to_allocated(); + if (copy_size == length) return 0; - else - { - session_connect_attrs_lost++; - return 1; - } + + session_connect_attrs_lost++; + return 1; } return 0; } diff --git a/storage/perfschema/pfs_account.cc b/storage/perfschema/pfs_account.cc index d3e58ed90f8..405364a23d3 100644 --- a/storage/perfschema/pfs_account.cc +++ b/storage/perfschema/pfs_account.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2010, 2013, 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 @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ /** @file storage/perfschema/pfs_account.cc @@ -319,17 +319,17 @@ search: return NULL; } -void PFS_account::aggregate() +void PFS_account::aggregate(PFS_user *safe_user, PFS_host *safe_host) { - aggregate_waits(); - aggregate_stages(); - aggregate_statements(); - aggregate_stats(); + aggregate_waits(safe_user, safe_host); + aggregate_stages(safe_user, safe_host); + aggregate_statements(safe_user, safe_host); + aggregate_stats(safe_user, safe_host); } -void PFS_account::aggregate_waits() +void PFS_account::aggregate_waits(PFS_user *safe_user, PFS_host *safe_host) { - if (likely(m_user != NULL && m_host != NULL)) + if (likely(safe_user != NULL && safe_host != NULL)) { /* Aggregate EVENTS_WAITS_SUMMARY_BY_ACCOUNT_BY_EVENT_NAME to: @@ -338,30 +338,30 @@ void PFS_account::aggregate_waits() in parallel. */ aggregate_all_event_names(m_instr_class_waits_stats, - m_user->m_instr_class_waits_stats, - m_host->m_instr_class_waits_stats); + safe_user->m_instr_class_waits_stats, + safe_host->m_instr_class_waits_stats); return; } - if (m_user != NULL) + if (safe_user != NULL) { /* Aggregate EVENTS_WAITS_SUMMARY_BY_ACCOUNT_BY_EVENT_NAME to: - EVENTS_WAITS_SUMMARY_BY_USER_BY_EVENT_NAME */ aggregate_all_event_names(m_instr_class_waits_stats, - m_user->m_instr_class_waits_stats); + safe_user->m_instr_class_waits_stats); return; } - if (m_host != NULL) + if (safe_host != NULL) { /* Aggregate EVENTS_WAITS_SUMMARY_BY_ACCOUNT_BY_EVENT_NAME to: - EVENTS_WAITS_SUMMARY_BY_HOST_BY_EVENT_NAME */ aggregate_all_event_names(m_instr_class_waits_stats, - m_host->m_instr_class_waits_stats); + safe_host->m_instr_class_waits_stats); return; } @@ -370,9 +370,9 @@ void PFS_account::aggregate_waits() return; } -void PFS_account::aggregate_stages() +void PFS_account::aggregate_stages(PFS_user *safe_user, PFS_host *safe_host) { - if (likely(m_user != NULL && m_host != NULL)) + if (likely(safe_user != NULL && safe_host != NULL)) { /* Aggregate EVENTS_STAGES_SUMMARY_BY_ACCOUNT_BY_EVENT_NAME to: @@ -381,12 +381,12 @@ void PFS_account::aggregate_stages() in parallel. */ aggregate_all_stages(m_instr_class_stages_stats, - m_user->m_instr_class_stages_stats, - m_host->m_instr_class_stages_stats); + safe_user->m_instr_class_stages_stats, + safe_host->m_instr_class_stages_stats); return; } - if (m_user != NULL) + if (safe_user != NULL) { /* Aggregate EVENTS_STAGES_SUMMARY_BY_ACCOUNT_BY_EVENT_NAME to: @@ -395,19 +395,19 @@ void PFS_account::aggregate_stages() in parallel. */ aggregate_all_stages(m_instr_class_stages_stats, - m_user->m_instr_class_stages_stats, + safe_user->m_instr_class_stages_stats, global_instr_class_stages_array); return; } - if (m_host != NULL) + if (safe_host != NULL) { /* Aggregate EVENTS_STAGES_SUMMARY_BY_ACCOUNT_BY_EVENT_NAME to: - EVENTS_STAGES_SUMMARY_BY_HOST_BY_EVENT_NAME */ aggregate_all_stages(m_instr_class_stages_stats, - m_host->m_instr_class_stages_stats); + safe_host->m_instr_class_stages_stats); return; } @@ -420,9 +420,9 @@ void PFS_account::aggregate_stages() return; } -void PFS_account::aggregate_statements() +void PFS_account::aggregate_statements(PFS_user *safe_user, PFS_host *safe_host) { - if (likely(m_user != NULL && m_host != NULL)) + if (likely(safe_user != NULL && safe_host != NULL)) { /* Aggregate EVENTS_STATEMENTS_SUMMARY_BY_ACCOUNT_BY_EVENT_NAME to: @@ -431,12 +431,12 @@ void PFS_account::aggregate_statements() in parallel. */ aggregate_all_statements(m_instr_class_statements_stats, - m_user->m_instr_class_statements_stats, - m_host->m_instr_class_statements_stats); + safe_user->m_instr_class_statements_stats, + safe_host->m_instr_class_statements_stats); return; } - if (m_user != NULL) + if (safe_user != NULL) { /* Aggregate EVENTS_STATEMENTS_SUMMARY_BY_ACCOUNT_BY_EVENT_NAME to: @@ -445,19 +445,19 @@ void PFS_account::aggregate_statements() in parallel. */ aggregate_all_statements(m_instr_class_statements_stats, - m_user->m_instr_class_statements_stats, + safe_user->m_instr_class_statements_stats, global_instr_class_statements_array); return; } - if (m_host != NULL) + if (safe_host != NULL) { /* Aggregate EVENTS_STATEMENTS_SUMMARY_BY_ACCOUNT_BY_EVENT_NAME to: - EVENTS_STATEMENTS_SUMMARY_BY_HOST_BY_EVENT_NAME */ aggregate_all_statements(m_instr_class_statements_stats, - m_host->m_instr_class_statements_stats); + safe_host->m_instr_class_statements_stats); return; } @@ -470,26 +470,26 @@ void PFS_account::aggregate_statements() return; } -void PFS_account::aggregate_stats() +void PFS_account::aggregate_stats(PFS_user *safe_user, PFS_host *safe_host) { - if (likely(m_user != NULL && m_host != NULL)) + if (likely(safe_user != NULL && safe_host != NULL)) { - m_user->m_disconnected_count+= m_disconnected_count; - m_host->m_disconnected_count+= m_disconnected_count; + safe_user->m_disconnected_count+= m_disconnected_count; + safe_host->m_disconnected_count+= m_disconnected_count; m_disconnected_count= 0; return; } - if (m_user != NULL) + if (safe_user != NULL) { - m_user->m_disconnected_count+= m_disconnected_count; + safe_user->m_disconnected_count+= m_disconnected_count; m_disconnected_count= 0; return; } - if (m_host != NULL) + if (safe_host != NULL) { - m_host->m_disconnected_count+= m_disconnected_count; + safe_host->m_disconnected_count+= m_disconnected_count; m_disconnected_count= 0; return; } @@ -511,9 +511,10 @@ PFS_account *sanitize_account(PFS_account *unsafe) return NULL; } -void purge_account(PFS_thread *thread, PFS_account *account) +void purge_account(PFS_thread *thread, PFS_account *account, + PFS_user *safe_user, PFS_host *safe_host) { - account->aggregate(); + account->aggregate(safe_user, safe_host); LF_PINS *pins= get_account_hash_pins(thread); if (unlikely(pins == NULL)) @@ -560,15 +561,19 @@ void purge_all_account(void) PFS_account *pfs= account_array; PFS_account *pfs_last= account_array + account_max; + PFS_user *user; + PFS_host *host; for ( ; pfs < pfs_last; pfs++) { if (pfs->m_lock.is_populated()) { - pfs->aggregate_stats(); + user= sanitize_user(pfs->m_user); + host= sanitize_host(pfs->m_host); + pfs->aggregate_stats(user, host); if (pfs->get_refcount() == 0) - purge_account(thread, pfs); + purge_account(thread, pfs, user, host); } } } diff --git a/storage/perfschema/pfs_account.h b/storage/perfschema/pfs_account.h index 1ac379e0fc9..efd0a424e68 100644 --- a/storage/perfschema/pfs_account.h +++ b/storage/perfschema/pfs_account.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2010, 2013, 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 @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef PFS_ACCOUNT_H #define PFS_ACCOUNT_H @@ -69,11 +69,11 @@ public: PFS_atomic::add_32(& m_refcount, -1); } - void aggregate(void); - void aggregate_waits(void); - void aggregate_stages(void); - void aggregate_statements(void); - void aggregate_stats(void); + void aggregate(PFS_user *safe_user, PFS_host *safe_host); + void aggregate_waits(PFS_user *safe_user, PFS_host *safe_host); + void aggregate_stages(PFS_user *safe_user, PFS_host *safe_host); + void aggregate_statements(PFS_user *safe_user, PFS_host *safe_host); + void aggregate_stats(PFS_user *safe_user, PFS_host *safe_host); void release(void); /** Internal lock. */ diff --git a/storage/perfschema/pfs_check.cc b/storage/perfschema/pfs_check.cc index c9c557f3010..97b23c38065 100644 --- a/storage/perfschema/pfs_check.cc +++ b/storage/perfschema/pfs_check.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2009, 2013, 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 @@ -55,9 +55,8 @@ void check_performance_schema() PFS_engine_table_share::check_all_tables(thd); + thd->restore_globals(); delete thd; - /* Remember that we don't have a THD */ - my_pthread_setspecific_ptr(THR_THD, 0); DBUG_VOID_RETURN; } diff --git a/storage/perfschema/pfs_defaults.cc b/storage/perfschema/pfs_defaults.cc index 4bd24f59ca8..01cf0d73771 100644 --- a/storage/perfschema/pfs_defaults.cc +++ b/storage/perfschema/pfs_defaults.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2010, 2011, 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 diff --git a/storage/perfschema/pfs_digest.cc b/storage/perfschema/pfs_digest.cc index 0d95c0d410e..addfac1f034 100644 --- a/storage/perfschema/pfs_digest.cc +++ b/storage/perfschema/pfs_digest.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2008, 2012, 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 @@ -46,10 +46,10 @@ #define LEX_YYSTYPE YYSTYPE /** - Token array : + Token array : Token array is an array of bytes to store tokens recieved during parsing. Following is the way token array is formed. - + ...<non-id-token><non-id-token><id-token><id_len><id_text>... For Ex: @@ -64,7 +64,7 @@ ulong digest_lost= 0; PFS_statements_digest_stat *statements_digest_stat_array= NULL; /** Consumer flag for table EVENTS_STATEMENTS_SUMMARY_BY_DIGEST. */ bool flag_statements_digest= true; -/** +/** Current index in Stat array where new record is to be inserted. index 0 is reserved for "all else" case when entire array is full. */ @@ -75,7 +75,7 @@ static bool digest_hash_inited= false; /** Initialize table EVENTS_STATEMENTS_SUMMARY_BY_DIGEST. - @param digest_sizing + @param digest_sizing */ int init_digest(const PFS_global_param *param) { @@ -232,6 +232,7 @@ search: { /* digest_stat array is full. Add stat at index 0 and return. */ pfs= &statements_digest_stat_array[0]; + digest_lost++; if (pfs->m_first_seen == 0) pfs->m_first_seen= now; @@ -347,7 +348,7 @@ void reset_esms_by_digest() statements_digest_stat_array[index].reset_data(); } - /* + /* Reset index which indicates where the next calculated digest information to be inserted in statements_digest_stat_array. */ @@ -362,13 +363,20 @@ void get_digest_text(char* digest_text, PSI_digest_storage* digest_storage) DBUG_ASSERT(digest_storage != NULL); bool truncated= false; int byte_count= digest_storage->m_byte_count; + char *digest_output= digest_text; int bytes_needed= 0; uint tok= 0; int current_byte= 0; lex_token_string *tok_data; /* -4 is to make sure extra space for '...' and a '\0' at the end. */ int bytes_available= COL_DIGEST_TEXT_SIZE - 4; - + + if (byte_count <= 0 || byte_count > PSI_MAX_DIGEST_STORAGE_SIZE) + { + *digest_text= '\0'; + return; + } + /* Convert text to utf8 */ const CHARSET_INFO *from_cs= get_charset(digest_storage->m_charset_number, MYF(0)); const CHARSET_INFO *to_cs= &my_charset_utf8_bin; @@ -400,8 +408,15 @@ void get_digest_text(char* digest_text, PSI_digest_storage* digest_storage) !truncated) { current_byte= read_token(digest_storage, current_byte, &tok); + + if (tok <= 0 || tok >= array_elements(lex_token_array)) + { + *digest_text='\0'; + return; + } + tok_data= &lex_token_array[tok]; - + switch (tok) { /* All identifiers are printed with their name. */ @@ -440,19 +455,19 @@ void get_digest_text(char* digest_text, PSI_digest_storage* digest_storage) break; } /* Copy the converted identifier into the digest string. */ - bytes_needed= id_length + (tok == IDENT ? 1 : 3); + bytes_needed= id_length + (tok == IDENT ? 1 : 3); if (bytes_needed <= bytes_available) { if (tok == IDENT_QUOTED) - *digest_text++= '`'; + *digest_output++= '`'; if (id_length > 0) { - memcpy(digest_text, id_string, id_length); - digest_text+= id_length; + memcpy(digest_output, id_string, id_length); + digest_output+= id_length; } if (tok == IDENT_QUOTED) - *digest_text++= '`'; - *digest_text++= ' '; + *digest_output++= '`'; + *digest_output++= ' '; bytes_available-= bytes_needed; } else @@ -464,7 +479,7 @@ void get_digest_text(char* digest_text, PSI_digest_storage* digest_storage) /* Everything else is printed as is. */ default: - /* + /* Make sure not to overflow digest_text buffer. +1 is to make sure extra space for ' '. */ @@ -473,9 +488,9 @@ void get_digest_text(char* digest_text, PSI_digest_storage* digest_storage) if (bytes_needed <= bytes_available) { - strncpy(digest_text, tok_data->m_token_string, tok_length); - digest_text+= tok_length; - *digest_text++= ' '; + strncpy(digest_output, tok_data->m_token_string, tok_length); + digest_output+= tok_length; + *digest_output++= ' '; bytes_available-= bytes_needed; } else @@ -489,11 +504,11 @@ void get_digest_text(char* digest_text, PSI_digest_storage* digest_storage) /* Truncate digest text in case of long queries. */ if (digest_storage->m_full || truncated) { - strcpy(digest_text, "..."); - digest_text+= 3; + strcpy(digest_output, "..."); + digest_output+= 3; } - *digest_text= '\0'; + *digest_output= '\0'; } static inline uint peek_token(const PSI_digest_storage *digest, int index) @@ -509,30 +524,33 @@ static inline uint peek_token(const PSI_digest_storage *digest, int index) /** Function to read last two tokens from token array. If an identifier - is found, do not look for token after that. + is found, do not look for token before that. */ static inline void peek_last_two_tokens(const PSI_digest_storage* digest_storage, int last_id_index, uint *t1, uint *t2) { int byte_count= digest_storage->m_byte_count; + int peek_index= byte_count - PFS_SIZE_OF_A_TOKEN; - if (last_id_index <= byte_count - PFS_SIZE_OF_A_TOKEN) + if (last_id_index <= peek_index) { /* Take last token. */ - *t1= peek_token(digest_storage, byte_count - PFS_SIZE_OF_A_TOKEN); - } - else - { - *t1= TOK_PFS_UNUSED; - } + *t1= peek_token(digest_storage, peek_index); - if (last_id_index <= byte_count - 2*PFS_SIZE_OF_A_TOKEN) - { - /* Take 2nd token from last. */ - *t2= peek_token(digest_storage, byte_count - 2 * PFS_SIZE_OF_A_TOKEN); + peek_index-= PFS_SIZE_OF_A_TOKEN; + if (last_id_index <= peek_index) + { + /* Take 2nd token from last. */ + *t2= peek_token(digest_storage, peek_index); + } + else + { + *t2= TOK_PFS_UNUSED; + } } else { + *t1= TOK_PFS_UNUSED; *t2= TOK_PFS_UNUSED; } } @@ -575,15 +593,12 @@ PSI_digest_locker* pfs_digest_add_token_v1(PSI_digest_locker *locker, if (digest_storage->m_full || token == END_OF_INPUT) return NULL; - /* + /* Take last_token 2 tokens collected till now. These tokens will be used in reduce for normalisation. Make sure not to consider ID tokens in reduce. */ uint last_token; uint last_token2; - - peek_last_two_tokens(digest_storage, state->m_last_id_index, - &last_token, &last_token2); switch (token) { @@ -607,6 +622,9 @@ PSI_digest_locker* pfs_digest_add_token_v1(PSI_digest_locker *locker, /* fall through */ case NULL_SYM: { + peek_last_two_tokens(digest_storage, state->m_last_id_index, + &last_token, &last_token2); + if ((last_token2 == TOK_PFS_GENERIC_VALUE || last_token2 == TOK_PFS_GENERIC_VALUE_LIST || last_token2 == NULL_SYM) && @@ -616,7 +634,7 @@ PSI_digest_locker* pfs_digest_add_token_v1(PSI_digest_locker *locker, REDUCE: TOK_PFS_GENERIC_VALUE_LIST := (TOK_PFS_GENERIC_VALUE|NULL_SYM) ',' (TOK_PFS_GENERIC_VALUE|NULL_SYM) - + REDUCE: TOK_PFS_GENERIC_VALUE_LIST := TOK_PFS_GENERIC_VALUE_LIST ',' (TOK_PFS_GENERIC_VALUE|NULL_SYM) @@ -632,17 +650,20 @@ PSI_digest_locker* pfs_digest_add_token_v1(PSI_digest_locker *locker, } case ')': { + peek_last_two_tokens(digest_storage, state->m_last_id_index, + &last_token, &last_token2); + if (last_token == TOK_PFS_GENERIC_VALUE && - last_token2 == '(') - { + last_token2 == '(') + { /* REDUCE: TOK_PFS_ROW_SINGLE_VALUE := - '(' TOK_PFS_GENERIC_VALUE ')' + '(' TOK_PFS_GENERIC_VALUE ')' */ digest_storage->m_byte_count-= 2*PFS_SIZE_OF_A_TOKEN; token= TOK_PFS_ROW_SINGLE_VALUE; - + /* Read last two tokens again */ peek_last_two_tokens(digest_storage, state->m_last_id_index, &last_token, &last_token2); @@ -653,11 +674,11 @@ PSI_digest_locker* pfs_digest_add_token_v1(PSI_digest_locker *locker, { /* REDUCE: - TOK_PFS_ROW_SINGLE_VALUE_LIST := + TOK_PFS_ROW_SINGLE_VALUE_LIST := TOK_PFS_ROW_SINGLE_VALUE ',' TOK_PFS_ROW_SINGLE_VALUE REDUCE: - TOK_PFS_ROW_SINGLE_VALUE_LIST := + TOK_PFS_ROW_SINGLE_VALUE_LIST := TOK_PFS_ROW_SINGLE_VALUE_LIST ',' TOK_PFS_ROW_SINGLE_VALUE */ digest_storage->m_byte_count-= 2*PFS_SIZE_OF_A_TOKEN; @@ -665,7 +686,7 @@ PSI_digest_locker* pfs_digest_add_token_v1(PSI_digest_locker *locker, } } else if (last_token == TOK_PFS_GENERIC_VALUE_LIST && - last_token2 == '(') + last_token2 == '(') { /* REDUCE: diff --git a/storage/perfschema/pfs_digest.h b/storage/perfschema/pfs_digest.h index d2453dc32c6..03f534b3d7e 100644 --- a/storage/perfschema/pfs_digest.h +++ b/storage/perfschema/pfs_digest.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2011, 2013, 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 @@ -123,10 +123,10 @@ static inline void digest_copy(PSI_digest_storage *to, const PSI_digest_storage inline int read_token(PSI_digest_storage *digest_storage, int index, uint *tok) { - DBUG_ASSERT(index <= digest_storage->m_byte_count); - DBUG_ASSERT(digest_storage->m_byte_count <= PSI_MAX_DIGEST_STORAGE_SIZE); + int safe_byte_count= digest_storage->m_byte_count; - if (index + PFS_SIZE_OF_A_TOKEN <= digest_storage->m_byte_count) + if (index + PFS_SIZE_OF_A_TOKEN <= safe_byte_count && + safe_byte_count <= PSI_MAX_DIGEST_STORAGE_SIZE) { unsigned char *src= & digest_storage->m_token_array[index]; *tok= src[0] | (src[1] << 8); diff --git a/storage/perfschema/pfs_engine_table.cc b/storage/perfschema/pfs_engine_table.cc index 789047f4d11..df4418b4bae 100644 --- a/storage/perfschema/pfs_engine_table.cc +++ b/storage/perfschema/pfs_engine_table.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2008, 2013, 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 @@ -723,7 +723,7 @@ bool pfs_show_status(handlerton *hton, THD *thd, uint buflen; const char *name; int i; - uint size; + size_t size; DBUG_ENTER("pfs_show_status"); @@ -737,7 +737,7 @@ bool pfs_show_status(handlerton *hton, THD *thd, if (stat != HA_ENGINE_STATUS) DBUG_RETURN(false); - uint total_memory= 0; + size_t total_memory= 0; for (i=0; /* empty */; i++) { @@ -1431,7 +1431,7 @@ bool pfs_show_status(handlerton *hton, THD *thd, break; } - buflen= int10_to_str(size, buf, 10) - buf; + buflen= longlong10_to_str(size, buf, 10) - buf; if (print(thd, PERFORMANCE_SCHEMA_str.str, PERFORMANCE_SCHEMA_str.length, name, strlen(name), diff --git a/storage/perfschema/pfs_events_stages.cc b/storage/perfschema/pfs_events_stages.cc index dbdfa6068ed..282071f830e 100644 --- a/storage/perfschema/pfs_events_stages.cc +++ b/storage/perfschema/pfs_events_stages.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2010, 2013, 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 @@ -179,11 +179,19 @@ void reset_events_stages_by_thread() { PFS_thread *thread= thread_array; PFS_thread *thread_last= thread_array + thread_max; + PFS_account *account; + PFS_user *user; + PFS_host *host; for ( ; thread < thread_last; thread++) { if (thread->m_lock.is_populated()) - aggregate_thread_stages(thread); + { + account= sanitize_account(thread->m_account); + user= sanitize_user(thread->m_user); + host= sanitize_host(thread->m_host); + aggregate_thread_stages(thread, account, user, host); + } } } @@ -192,11 +200,17 @@ void reset_events_stages_by_account() { PFS_account *pfs= account_array; PFS_account *pfs_last= account_array + account_max; + PFS_user *user; + PFS_host *host; for ( ; pfs < pfs_last; pfs++) { if (pfs->m_lock.is_populated()) - pfs->aggregate_stages(); + { + user= sanitize_user(pfs->m_user); + host= sanitize_host(pfs->m_host); + pfs->aggregate_stages(user, host); + } } } diff --git a/storage/perfschema/pfs_events_statements.cc b/storage/perfschema/pfs_events_statements.cc index 66def924d80..07810d26dc4 100644 --- a/storage/perfschema/pfs_events_statements.cc +++ b/storage/perfschema/pfs_events_statements.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2010, 2013, 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 @@ -183,11 +183,19 @@ void reset_events_statements_by_thread() { PFS_thread *thread= thread_array; PFS_thread *thread_last= thread_array + thread_max; + PFS_account *account; + PFS_user *user; + PFS_host *host; for ( ; thread < thread_last; thread++) { if (thread->m_lock.is_populated()) - aggregate_thread_statements(thread); + { + account= sanitize_account(thread->m_account); + user= sanitize_user(thread->m_user); + host= sanitize_host(thread->m_host); + aggregate_thread_statements(thread, account, user, host); + } } } @@ -196,11 +204,17 @@ void reset_events_statements_by_account() { PFS_account *pfs= account_array; PFS_account *pfs_last= account_array + account_max; + PFS_user *user; + PFS_host *host; for ( ; pfs < pfs_last; pfs++) { if (pfs->m_lock.is_populated()) - pfs->aggregate_statements(); + { + user= sanitize_user(pfs->m_user); + host= sanitize_host(pfs->m_host); + pfs->aggregate_statements(user, host); + } } } diff --git a/storage/perfschema/pfs_events_waits.cc b/storage/perfschema/pfs_events_waits.cc index c8a9d20a2f1..2799550c81d 100644 --- a/storage/perfschema/pfs_events_waits.cc +++ b/storage/perfschema/pfs_events_waits.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2008, 2013, 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 @@ -183,11 +183,19 @@ void reset_events_waits_by_thread() { PFS_thread *thread= thread_array; PFS_thread *thread_last= thread_array + thread_max; + PFS_account *account; + PFS_user *user; + PFS_host *host; for ( ; thread < thread_last; thread++) { if (thread->m_lock.is_populated()) - aggregate_thread_waits(thread); + { + account= sanitize_account(thread->m_account); + user= sanitize_user(thread->m_user); + host= sanitize_host(thread->m_host); + aggregate_thread_waits(thread, account, user, host); + } } } @@ -196,11 +204,17 @@ void reset_events_waits_by_account() { PFS_account *pfs= account_array; PFS_account *pfs_last= account_array + account_max; + PFS_user *user; + PFS_host *host; for ( ; pfs < pfs_last; pfs++) { if (pfs->m_lock.is_populated()) - pfs->aggregate_waits(); + { + user= sanitize_user(pfs->m_user); + host= sanitize_host(pfs->m_host); + pfs->aggregate_waits(user, host); + } } } diff --git a/storage/perfschema/pfs_global.cc b/storage/perfschema/pfs_global.cc index d0dc26b1bf4..a82ffe58cea 100644 --- a/storage/perfschema/pfs_global.cc +++ b/storage/perfschema/pfs_global.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2008, 2013, 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 @@ -37,7 +37,7 @@ #endif bool pfs_initialized= false; -ulonglong pfs_allocated_memory= 0; +size_t pfs_allocated_memory= 0; /** Memory allocation for the performance schema. diff --git a/storage/perfschema/pfs_global.h b/storage/perfschema/pfs_global.h index cddf688ddf4..2ec76df6f91 100644 --- a/storage/perfschema/pfs_global.h +++ b/storage/perfschema/pfs_global.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2008, 2013, 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 @@ -27,7 +27,7 @@ /** True when the performance schema is initialized. */ extern bool pfs_initialized; /** Total memory allocated by the performance schema, in bytes. */ -extern ulonglong pfs_allocated_memory; +extern size_t pfs_allocated_memory; #if defined(HAVE_POSIX_MEMALIGN) || defined(HAVE_MEMALIGN) || defined(HAVE_ALIGNED_MALLOC) #define PFS_ALIGNEMENT 64 diff --git a/storage/perfschema/pfs_host.cc b/storage/perfschema/pfs_host.cc index 735480b53db..0c6f5cf3627 100644 --- a/storage/perfschema/pfs_host.cc +++ b/storage/perfschema/pfs_host.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2010, 2013, 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 @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ /** @file storage/perfschema/pfs_host.cc @@ -333,6 +333,14 @@ void PFS_host::release() dec_refcount(); } +PFS_host *sanitize_host(PFS_host *unsafe) +{ + if ((&host_array[0] <= unsafe) && + (unsafe < &host_array[host_max])) + return unsafe; + return NULL; +} + void purge_host(PFS_thread *thread, PFS_host *host) { LF_PINS *pins= get_host_hash_pins(thread); diff --git a/storage/perfschema/pfs_host.h b/storage/perfschema/pfs_host.h index eb0ff6efc6f..9c039cf919f 100644 --- a/storage/perfschema/pfs_host.h +++ b/storage/perfschema/pfs_host.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2010, 2013, 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 @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef PFS_HOST_H #define PFS_HOST_H @@ -94,6 +94,7 @@ void cleanup_host_hash(void); PFS_host *find_or_create_host(PFS_thread *thread, const char *hostname, uint hostname_length); +PFS_host *sanitize_host(PFS_host *unsafe); void purge_all_host(void); /* For iterators and show status. */ diff --git a/storage/perfschema/pfs_instr.cc b/storage/perfschema/pfs_instr.cc index 335f85bd45e..cf0e6fd56f8 100644 --- a/storage/perfschema/pfs_instr.cc +++ b/storage/perfschema/pfs_instr.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2008, 2013, 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 @@ -38,22 +38,32 @@ /** Size of the mutex instances array. @sa mutex_array */ ulong mutex_max; +/** True when @c mutex_array is full. */ +bool mutex_full; /** Number of mutexes instance lost. @sa mutex_array */ ulong mutex_lost; /** Size of the rwlock instances array. @sa rwlock_array */ ulong rwlock_max; +/** True when @c rwlock_array is full. */ +bool rwlock_full; /** Number or rwlock instances lost. @sa rwlock_array */ ulong rwlock_lost; /** Size of the conditions instances array. @sa cond_array */ ulong cond_max; +/** True when @c cond_array is full. */ +bool cond_full; /** Number of conditions instances lost. @sa cond_array */ ulong cond_lost; /** Size of the thread instances array. @sa thread_array */ ulong thread_max; +/** True when @c thread_array is full. */ +bool thread_full; /** Number or thread instances lost. @sa thread_array */ ulong thread_lost; /** Size of the file instances array. @sa file_array */ ulong file_max; +/** True when @c file_array is full. */ +bool file_full; /** Number of file instances lost. @sa file_array */ ulong file_lost; /** @@ -61,14 +71,20 @@ ulong file_lost; Signed value, for easier comparisons with a file descriptor number. */ long file_handle_max; +/** True when @c file_handle_array is full. */ +bool file_handle_full; /** Number of file handle lost. @sa file_handle_array */ ulong file_handle_lost; /** Size of the table instances array. @sa table_array */ ulong table_max; +/** True when @c table_array is full. */ +bool table_full; /** Number of table instances lost. @sa table_array */ ulong table_lost; /** Size of the socket instances array. @sa socket_array */ ulong socket_max; +/** True when @c socket_array is full. */ +bool socket_full; /** Number of socket instances lost. @sa socket_array */ ulong socket_lost; /** Number of EVENTS_WAITS_HISTORY records per thread. */ @@ -185,20 +201,28 @@ int init_instruments(const PFS_global_param *param) DBUG_ASSERT(wait_class_max != 0); mutex_max= param->m_mutex_sizing; + mutex_full= false; mutex_lost= 0; rwlock_max= param->m_rwlock_sizing; + rwlock_full= false; rwlock_lost= 0; cond_max= param->m_cond_sizing; + cond_full= false; cond_lost= 0; file_max= param->m_file_sizing; + file_full= false; file_lost= 0; file_handle_max= param->m_file_handle_sizing; + file_handle_full= false; file_handle_lost= 0; table_max= param->m_table_sizing; + table_full= false; table_lost= 0; thread_max= param->m_thread_sizing; + thread_full= false; thread_lost= 0; socket_max= param->m_socket_sizing; + socket_full= false; socket_lost= 0; events_waits_history_per_thread= param->m_events_waits_history_sizing; @@ -601,6 +625,17 @@ PFS_mutex* create_mutex(PFS_mutex_class *klass, const void *identity) uint attempts= 0; PFS_mutex *pfs; + if (mutex_full) + { + /* + This is a safety plug. + When mutex_array is severely undersized, + do not spin to death for each call. + */ + mutex_lost++; + return NULL; + } + while (++attempts <= mutex_max) { /* @@ -645,6 +680,15 @@ PFS_mutex* create_mutex(PFS_mutex_class *klass, const void *identity) } mutex_lost++; + /* + Race condition. + The mutex_array might not be full if a concurrent thread + called destroy_mutex() during the scan, leaving one + empty slot we did not find. + However, 99.999 percent full tables or 100 percent full tables + are treated the same here, we declare the array overloaded. + */ + mutex_full= true; return NULL; } @@ -662,6 +706,7 @@ void destroy_mutex(PFS_mutex *pfs) if (klass->is_singleton()) klass->m_singleton= NULL; pfs->m_lock.allocated_to_free(); + mutex_full= false; } /** @@ -677,6 +722,12 @@ PFS_rwlock* create_rwlock(PFS_rwlock_class *klass, const void *identity) uint attempts= 0; PFS_rwlock *pfs; + if (rwlock_full) + { + rwlock_lost++; + return NULL; + } + while (++attempts <= rwlock_max) { /* See create_mutex() */ @@ -705,6 +756,7 @@ PFS_rwlock* create_rwlock(PFS_rwlock_class *klass, const void *identity) } rwlock_lost++; + rwlock_full= true; return NULL; } @@ -722,6 +774,7 @@ void destroy_rwlock(PFS_rwlock *pfs) if (klass->is_singleton()) klass->m_singleton= NULL; pfs->m_lock.allocated_to_free(); + rwlock_full= false; } /** @@ -737,6 +790,12 @@ PFS_cond* create_cond(PFS_cond_class *klass, const void *identity) uint attempts= 0; PFS_cond *pfs; + if (cond_full) + { + cond_lost++; + return NULL; + } + while (++attempts <= cond_max) { /* See create_mutex() */ @@ -763,6 +822,7 @@ PFS_cond* create_cond(PFS_cond_class *klass, const void *identity) } cond_lost++; + cond_full= true; return NULL; } @@ -780,6 +840,7 @@ void destroy_cond(PFS_cond *pfs) if (klass->is_singleton()) klass->m_singleton= NULL; pfs->m_lock.allocated_to_free(); + cond_full= false; } PFS_thread* PFS_thread::get_current_thread() @@ -791,7 +852,7 @@ PFS_thread* PFS_thread::get_current_thread() void PFS_thread::reset_session_connect_attrs() { m_session_connect_attrs_length= 0; - m_session_connect_attrs_cs= NULL; + m_session_connect_attrs_cs_number= 0; if ((m_session_connect_attrs != NULL) && (session_connect_attrs_size_per_thread > 0) ) @@ -818,6 +879,12 @@ PFS_thread* create_thread(PFS_thread_class *klass, const void *identity, uint attempts= 0; PFS_thread *pfs; + if (thread_full) + { + thread_lost++; + return NULL; + } + while (++attempts <= thread_max) { /* See create_mutex() */ @@ -833,6 +900,8 @@ PFS_thread* create_thread(PFS_thread_class *klass, const void *identity, pfs->m_parent_thread_internal_id= 0; pfs->m_processlist_id= processlist_id; pfs->m_event_id= 1; + pfs->m_stmt_lock.set_allocated(); + pfs->m_session_lock.set_allocated(); pfs->m_enabled= true; pfs->m_class= klass; pfs->m_events_waits_current= & pfs->m_events_waits_stack[WAIT_STACK_BOTTOM]; @@ -860,11 +929,9 @@ PFS_thread* create_thread(PFS_thread_class *klass, const void *identity, pfs->m_dbname_length= 0; pfs->m_command= 0; pfs->m_start_time= 0; - pfs->m_processlist_state_ptr= NULL; - pfs->m_processlist_state_length= 0; - pfs->m_processlist_info_ptr= NULL; + pfs->m_stage= 0; + pfs->m_processlist_info[0]= '\0'; pfs->m_processlist_info_length= 0; - pfs->m_processlist_lock.set_allocated(); pfs->m_host= NULL; pfs->m_user= NULL; @@ -942,6 +1009,7 @@ PFS_thread* create_thread(PFS_thread_class *klass, const void *identity, } thread_lost++; + thread_full= true; return NULL; } @@ -1053,6 +1121,7 @@ void destroy_thread(PFS_thread *pfs) pfs->m_digest_hash_pins= NULL; } pfs->m_lock.allocated_to_free(); + thread_full= false; } /** @@ -1203,6 +1272,12 @@ search: return NULL; } + if (file_full) + { + file_lost++; + return NULL; + } + while (++attempts <= file_max) { /* See create_mutex() */ @@ -1256,6 +1331,7 @@ search: } file_lost++; + file_full= true; return NULL; } @@ -1295,6 +1371,7 @@ void destroy_file(PFS_thread *thread, PFS_file *pfs) if (klass->is_singleton()) klass->m_singleton= NULL; pfs->m_lock.allocated_to_free(); + file_full= false; } /** @@ -1312,6 +1389,12 @@ PFS_table* create_table(PFS_table_share *share, PFS_thread *opening_thread, uint attempts= 0; PFS_table *pfs; + if (table_full) + { + table_lost++; + return NULL; + } + while (++attempts <= table_max) { /* See create_mutex() */ @@ -1342,6 +1425,7 @@ PFS_table* create_table(PFS_table_share *share, PFS_thread *opening_thread, } table_lost++; + table_full= true; return NULL; } @@ -1439,6 +1523,7 @@ void destroy_table(PFS_table *pfs) DBUG_ASSERT(pfs != NULL); pfs->m_share->dec_refcount(); pfs->m_lock.allocated_to_free(); + table_full= false; } /** @@ -1455,6 +1540,12 @@ PFS_socket* create_socket(PFS_socket_class *klass, const my_socket *fd, uint attempts= 0; PFS_socket *pfs; + if (socket_full) + { + socket_lost++; + return NULL; + } + uint fd_used= 0; uint addr_len_used= addr_len; @@ -1504,6 +1595,7 @@ PFS_socket* create_socket(PFS_socket_class *klass, const my_socket *fd, } socket_lost++; + socket_full= true; return NULL; } @@ -1541,6 +1633,7 @@ void destroy_socket(PFS_socket *pfs) pfs->m_fd= 0; pfs->m_addr_len= 0; pfs->m_lock.allocated_to_free(); + socket_full= false; } static void reset_mutex_waits_by_instance(void) @@ -1756,55 +1849,57 @@ void aggregate_all_statements(PFS_statement_stat *from_array, } } -void aggregate_thread_stats(PFS_thread *thread) +void aggregate_thread_stats(PFS_thread *thread, + PFS_account *safe_account, + PFS_user *safe_user, + PFS_host *safe_host) { - if (likely(thread->m_account != NULL)) + if (likely(safe_account != NULL)) { - thread->m_account->m_disconnected_count++; + safe_account->m_disconnected_count++; return; } - if (thread->m_user != NULL) - thread->m_user->m_disconnected_count++; + if (safe_user != NULL) + safe_user->m_disconnected_count++; - if (thread->m_host != NULL) - thread->m_host->m_disconnected_count++; + if (safe_host != NULL) + safe_host->m_disconnected_count++; /* There is no global table for connections statistics. */ return; } -void aggregate_thread(PFS_thread *thread) +void aggregate_thread(PFS_thread *thread, + PFS_account *safe_account, + PFS_user *safe_user, + PFS_host *safe_host) { - aggregate_thread_waits(thread); - aggregate_thread_stages(thread); - aggregate_thread_statements(thread); - aggregate_thread_stats(thread); + aggregate_thread_waits(thread, safe_account, safe_user, safe_host); + aggregate_thread_stages(thread, safe_account, safe_user, safe_host); + aggregate_thread_statements(thread, safe_account, safe_user, safe_host); + aggregate_thread_stats(thread, safe_account, safe_user, safe_host); } -void aggregate_thread_waits(PFS_thread *thread) +void aggregate_thread_waits(PFS_thread *thread, + PFS_account *safe_account, + PFS_user *safe_user, + PFS_host *safe_host) { - if (likely(thread->m_account != NULL)) + if (likely(safe_account != NULL)) { - DBUG_ASSERT(thread->m_user == NULL); - DBUG_ASSERT(thread->m_host == NULL); - DBUG_ASSERT(thread->m_account->get_refcount() > 0); - /* Aggregate EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME to EVENTS_WAITS_SUMMARY_BY_ACCOUNT_BY_EVENT_NAME. */ aggregate_all_event_names(thread->m_instr_class_waits_stats, - thread->m_account->m_instr_class_waits_stats); + safe_account->m_instr_class_waits_stats); return; } - if ((thread->m_user != NULL) && (thread->m_host != NULL)) + if ((safe_user != NULL) && (safe_host != NULL)) { - DBUG_ASSERT(thread->m_user->get_refcount() > 0); - DBUG_ASSERT(thread->m_host->get_refcount() > 0); - /* Aggregate EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME to: - EVENTS_WAITS_SUMMARY_BY_USER_BY_EVENT_NAME @@ -1812,34 +1907,30 @@ void aggregate_thread_waits(PFS_thread *thread) in parallel. */ aggregate_all_event_names(thread->m_instr_class_waits_stats, - thread->m_user->m_instr_class_waits_stats, - thread->m_host->m_instr_class_waits_stats); + safe_user->m_instr_class_waits_stats, + safe_host->m_instr_class_waits_stats); return; } - if (thread->m_user != NULL) + if (safe_user != NULL) { - DBUG_ASSERT(thread->m_user->get_refcount() > 0); - /* Aggregate EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME to EVENTS_WAITS_SUMMARY_BY_USER_BY_EVENT_NAME, directly. */ aggregate_all_event_names(thread->m_instr_class_waits_stats, - thread->m_user->m_instr_class_waits_stats); + safe_user->m_instr_class_waits_stats); return; } - if (thread->m_host != NULL) + if (safe_host != NULL) { - DBUG_ASSERT(thread->m_host->get_refcount() > 0); - /* Aggregate EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME to EVENTS_WAITS_SUMMARY_BY_HOST_BY_EVENT_NAME, directly. */ aggregate_all_event_names(thread->m_instr_class_waits_stats, - thread->m_host->m_instr_class_waits_stats); + safe_host->m_instr_class_waits_stats); return; } @@ -1847,29 +1938,25 @@ void aggregate_thread_waits(PFS_thread *thread) thread->reset_waits_stats(); } -void aggregate_thread_stages(PFS_thread *thread) +void aggregate_thread_stages(PFS_thread *thread, + PFS_account *safe_account, + PFS_user *safe_user, + PFS_host *safe_host) { - if (likely(thread->m_account != NULL)) + if (likely(safe_account != NULL)) { - DBUG_ASSERT(thread->m_user == NULL); - DBUG_ASSERT(thread->m_host == NULL); - DBUG_ASSERT(thread->m_account->get_refcount() > 0); - /* Aggregate EVENTS_STAGES_SUMMARY_BY_THREAD_BY_EVENT_NAME to EVENTS_STAGES_SUMMARY_BY_ACCOUNT_BY_EVENT_NAME. */ aggregate_all_stages(thread->m_instr_class_stages_stats, - thread->m_account->m_instr_class_stages_stats); + safe_account->m_instr_class_stages_stats); return; } - if ((thread->m_user != NULL) && (thread->m_host != NULL)) + if ((safe_user != NULL) && (safe_host != NULL)) { - DBUG_ASSERT(thread->m_user->get_refcount() > 0); - DBUG_ASSERT(thread->m_host->get_refcount() > 0); - /* Aggregate EVENTS_STAGES_SUMMARY_BY_THREAD_BY_EVENT_NAME to: - EVENTS_STAGES_SUMMARY_BY_USER_BY_EVENT_NAME @@ -1877,15 +1964,13 @@ void aggregate_thread_stages(PFS_thread *thread) in parallel. */ aggregate_all_stages(thread->m_instr_class_stages_stats, - thread->m_user->m_instr_class_stages_stats, - thread->m_host->m_instr_class_stages_stats); + safe_user->m_instr_class_stages_stats, + safe_host->m_instr_class_stages_stats); return; } - if (thread->m_user != NULL) + if (safe_user != NULL) { - DBUG_ASSERT(thread->m_user->get_refcount() > 0); - /* Aggregate EVENTS_STAGES_SUMMARY_BY_THREAD_BY_EVENT_NAME to: - EVENTS_STAGES_SUMMARY_BY_USER_BY_EVENT_NAME @@ -1893,21 +1978,19 @@ void aggregate_thread_stages(PFS_thread *thread) in parallel. */ aggregate_all_stages(thread->m_instr_class_stages_stats, - thread->m_user->m_instr_class_stages_stats, + safe_user->m_instr_class_stages_stats, global_instr_class_stages_array); return; } - if (thread->m_host != NULL) + if (safe_host != NULL) { - DBUG_ASSERT(thread->m_host->get_refcount() > 0); - /* Aggregate EVENTS_STAGES_SUMMARY_BY_THREAD_BY_EVENT_NAME to EVENTS_STAGES_SUMMARY_BY_HOST_BY_EVENT_NAME, directly. */ aggregate_all_stages(thread->m_instr_class_stages_stats, - thread->m_host->m_instr_class_stages_stats); + safe_host->m_instr_class_stages_stats); return; } @@ -1919,29 +2002,25 @@ void aggregate_thread_stages(PFS_thread *thread) global_instr_class_stages_array); } -void aggregate_thread_statements(PFS_thread *thread) +void aggregate_thread_statements(PFS_thread *thread, + PFS_account *safe_account, + PFS_user *safe_user, + PFS_host *safe_host) { - if (likely(thread->m_account != NULL)) + if (likely(safe_account != NULL)) { - DBUG_ASSERT(thread->m_user == NULL); - DBUG_ASSERT(thread->m_host == NULL); - DBUG_ASSERT(thread->m_account->get_refcount() > 0); - /* Aggregate EVENTS_STATEMENTS_SUMMARY_BY_THREAD_BY_EVENT_NAME to EVENTS_STATEMENTS_SUMMARY_BY_ACCOUNT_BY_EVENT_NAME. */ aggregate_all_statements(thread->m_instr_class_statements_stats, - thread->m_account->m_instr_class_statements_stats); + safe_account->m_instr_class_statements_stats); return; } - if ((thread->m_user != NULL) && (thread->m_host != NULL)) + if ((safe_user != NULL) && (safe_host != NULL)) { - DBUG_ASSERT(thread->m_user->get_refcount() > 0); - DBUG_ASSERT(thread->m_host->get_refcount() > 0); - /* Aggregate EVENTS_STATEMENT_SUMMARY_BY_THREAD_BY_EVENT_NAME to: - EVENTS_STATEMENT_SUMMARY_BY_USER_BY_EVENT_NAME @@ -1949,15 +2028,13 @@ void aggregate_thread_statements(PFS_thread *thread) in parallel. */ aggregate_all_statements(thread->m_instr_class_statements_stats, - thread->m_user->m_instr_class_statements_stats, - thread->m_host->m_instr_class_statements_stats); + safe_user->m_instr_class_statements_stats, + safe_host->m_instr_class_statements_stats); return; } - if (thread->m_user != NULL) + if (safe_user != NULL) { - DBUG_ASSERT(thread->m_user->get_refcount() > 0); - /* Aggregate EVENTS_STATEMENTS_SUMMARY_BY_THREAD_BY_EVENT_NAME to: - EVENTS_STATEMENTS_SUMMARY_BY_USER_BY_EVENT_NAME @@ -1965,21 +2042,19 @@ void aggregate_thread_statements(PFS_thread *thread) in parallel. */ aggregate_all_statements(thread->m_instr_class_statements_stats, - thread->m_user->m_instr_class_statements_stats, + safe_user->m_instr_class_statements_stats, global_instr_class_statements_array); return; } - if (thread->m_host != NULL) + if (safe_host != NULL) { - DBUG_ASSERT(thread->m_host->get_refcount() > 0); - /* Aggregate EVENTS_STATEMENTS_SUMMARY_BY_THREAD_BY_EVENT_NAME to EVENTS_STATEMENTS_SUMMARY_BY_HOST_BY_EVENT_NAME, directly. */ aggregate_all_statements(thread->m_instr_class_statements_stats, - thread->m_host->m_instr_class_statements_stats); + safe_host->m_instr_class_statements_stats); return; } diff --git a/storage/perfschema/pfs_instr.h b/storage/perfschema/pfs_instr.h index 2ea44830d2b..bd2fe0e4afd 100644 --- a/storage/perfschema/pfs_instr.h +++ b/storage/perfschema/pfs_instr.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2008, 2013, 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 @@ -371,7 +371,13 @@ struct PFS_ALIGNED PFS_thread : PFS_connection_slice PFS_events_waits *m_events_waits_current; /** Event ID counter */ ulonglong m_event_id; - /** Internal lock. */ + /** + Internal lock. + This lock is exclusively used to protect against races + when creating and destroying PFS_thread. + Do not use this lock to protect thread attributes, + use one of @c m_stmt_lock or @c m_session_lock instead. + */ pfs_lock m_lock; /** Pins for filename_hash. */ LF_PINS *m_filename_hash_pins; @@ -460,31 +466,63 @@ struct PFS_ALIGNED PFS_thread : PFS_connection_slice */ PFS_events_statements *m_statements_history; - /** User name. */ + /** + Internal lock, for session attributes. + Statement attributes are expected to be updated in frequently, + typically per session execution. + */ + pfs_lock m_session_lock; + /** + User name. + Protected by @c m_session_lock. + */ char m_username[USERNAME_LENGTH]; - /** Length of @c m_username. */ + /** + Length of @c m_username. + Protected by @c m_session_lock. + */ uint m_username_length; - /** Host name. */ + /** + Host name. + Protected by @c m_session_lock. + */ char m_hostname[HOSTNAME_LENGTH]; - /** Length of @c m_hostname. */ + /** + Length of @c m_hostname. + Protected by @c m_session_lock. + */ uint m_hostname_length; - /** Database name. */ + /** + Database name. + Protected by @c m_stmt_lock. + */ char m_dbname[NAME_LEN]; - /** Length of @c m_dbname. */ + /** + Length of @c m_dbname. + Protected by @c m_stmt_lock. + */ uint m_dbname_length; /** Current command. */ int m_command; /** Start time. */ time_t m_start_time; - /** Lock for Processlist state, Processlist info. */ - pfs_lock m_processlist_lock; - /** Processlist state. */ - const char *m_processlist_state_ptr; - /** Length of @c m_processlist_state_ptr. */ - uint m_processlist_state_length; - /** Processlist info. */ - const char *m_processlist_info_ptr; - /** Length of @c m_processlist_info_length. */ + /** + Internal lock, for statement attributes. + Statement attributes are expected to be updated frequently, + typically per statement execution. + */ + pfs_lock m_stmt_lock; + /** Processlist state (derived from stage). */ + PFS_stage_key m_stage; + /** + Processlist info. + Protected by @c m_stmt_lock. + */ + char m_processlist_info[COL_INFO_SIZE]; + /** + Length of @c m_processlist_info_length. + Protected by @c m_stmt_lock. + */ uint m_processlist_info_length; PFS_events_stages m_stage_current; @@ -500,12 +538,21 @@ struct PFS_ALIGNED PFS_thread : PFS_connection_slice /** Reset session connect attributes */ void reset_session_connect_attrs(); - /** a buffer for the connection attributes */ + /** + Buffer for the connection attributes. + Protected by @c m_session_lock. + */ char *m_session_connect_attrs; - /** length used by @c m_connect_attrs */ + /** + Length used by @c m_connect_attrs. + Protected by @c m_session_lock. + */ uint m_session_connect_attrs_length; - /** character set in which @c m_connect_attrs are encoded */ - const CHARSET_INFO *m_session_connect_attrs_cs; + /** + Character set in which @c m_connect_attrs are encoded. + Protected by @c m_session_lock. + */ + uint m_session_connect_attrs_cs_number; }; extern PFS_stage_stat *global_instr_class_stages_array; @@ -608,10 +655,22 @@ void aggregate_all_statements(PFS_statement_stat *from_array, PFS_statement_stat *to_array_1, PFS_statement_stat *to_array_2); -void aggregate_thread(PFS_thread *thread); -void aggregate_thread_waits(PFS_thread *thread); -void aggregate_thread_stages(PFS_thread *thread); -void aggregate_thread_statements(PFS_thread *thread); +void aggregate_thread(PFS_thread *thread, + PFS_account *safe_account, + PFS_user *safe_user, + PFS_host *safe_host); +void aggregate_thread_waits(PFS_thread *thread, + PFS_account *safe_account, + PFS_user *safe_user, + PFS_host *safe_host); +void aggregate_thread_stages(PFS_thread *thread, + PFS_account *safe_account, + PFS_user *safe_user, + PFS_host *safe_host); +void aggregate_thread_statements(PFS_thread *thread, + PFS_account *safe_account, + PFS_user *safe_user, + PFS_host *safe_host); void clear_thread_account(PFS_thread *thread); void set_thread_account(PFS_thread *thread); diff --git a/storage/perfschema/pfs_instr_class.cc b/storage/perfschema/pfs_instr_class.cc index 05c85104a94..4d73396fc9b 100644 --- a/storage/perfschema/pfs_instr_class.cc +++ b/storage/perfschema/pfs_instr_class.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2008, 2013, 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 @@ -980,11 +980,14 @@ PFS_file_key register_file_class(const char *name, uint name_length, /** Register a stage instrumentation metadata. @param name the instrumented name + @param prefix_length length in bytes of the name prefix @param name_length length in bytes of name @param flags the instrumentation flags @return a stage instrumentation key */ -PFS_stage_key register_stage_class(const char *name, uint name_length, +PFS_stage_key register_stage_class(const char *name, + uint prefix_length, + uint name_length, int flags) { /* See comments in register_mutex_class */ @@ -1000,6 +1003,7 @@ PFS_stage_key register_stage_class(const char *name, uint name_length, { entry= &stage_class_array[index]; init_instr_class(entry, name, name_length, flags, PFS_CLASS_STAGE); + entry->m_prefix_length= prefix_length; entry->m_event_name_index= index; entry->m_enabled= false; /* disabled by default */ entry->m_timed= false; diff --git a/storage/perfschema/pfs_instr_class.h b/storage/perfschema/pfs_instr_class.h index 246c6ee0b76..e50e824aee9 100644 --- a/storage/perfschema/pfs_instr_class.h +++ b/storage/perfschema/pfs_instr_class.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2008, 2013, 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 @@ -148,6 +148,12 @@ struct PFS_instr_class { return m_flags & PSI_FLAG_GLOBAL; } + + bool is_mutable() const + { + return m_flags & PSI_FLAG_MUTABLE; + } + static void set_enabled(PFS_instr_class *pfs, bool enabled); static void set_timed(PFS_instr_class *pfs, bool timed); @@ -363,6 +369,11 @@ struct PFS_ALIGNED PFS_file_class : public PFS_instr_class /** Instrumentation metadata for a stage. */ struct PFS_ALIGNED PFS_stage_class : public PFS_instr_class { + /** + Length of the 'stage/<component>/' prefix. + This is to extract 'foo' from 'stage/sql/foo'. + */ + uint m_prefix_length; /** Stage usage statistics. */ PFS_stage_stat m_stage_stat; }; @@ -422,7 +433,9 @@ PFS_thread_key register_thread_class(const char *name, uint name_length, PFS_file_key register_file_class(const char *name, uint name_length, int flags); -PFS_stage_key register_stage_class(const char *name, uint name_length, +PFS_stage_key register_stage_class(const char *name, + uint prefix_length, + uint name_length, int flags); PFS_statement_key register_statement_class(const char *name, uint name_length, diff --git a/storage/perfschema/pfs_server.h b/storage/perfschema/pfs_server.h index e0c782fde58..aa5dd6862fa 100644 --- a/storage/perfschema/pfs_server.h +++ b/storage/perfschema/pfs_server.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2008, 2013, 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 @@ -25,7 +25,7 @@ #define PFS_MAX_MUTEX_CLASS 200 #endif #ifndef PFS_MAX_RWLOCK_CLASS - #define PFS_MAX_RWLOCK_CLASS 30 + #define PFS_MAX_RWLOCK_CLASS 40 #endif #ifndef PFS_MAX_COND_CLASS #define PFS_MAX_COND_CLASS 80 diff --git a/storage/perfschema/pfs_setup_object.cc b/storage/perfschema/pfs_setup_object.cc index 0ca7986e818..b84456d874c 100644 --- a/storage/perfschema/pfs_setup_object.cc +++ b/storage/perfschema/pfs_setup_object.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2010, 2012, 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 @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ /** @file storage/perfschema/pfs_setup_object.cc diff --git a/storage/perfschema/pfs_stat.h b/storage/perfschema/pfs_stat.h index 2a255a9e5b2..13a32d0e3ad 100644 --- a/storage/perfschema/pfs_stat.h +++ b/storage/perfschema/pfs_stat.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2008, 2013, 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 @@ -58,6 +58,11 @@ struct PFS_single_stat m_max= 0; } + inline bool has_timed_stats() const + { + return (m_min <= m_max); + } + inline void aggregate(const PFS_single_stat *stat) { m_count+= stat->m_count; diff --git a/storage/perfschema/pfs_user.cc b/storage/perfschema/pfs_user.cc index 6ae734c7d72..9f53702dd86 100644 --- a/storage/perfschema/pfs_user.cc +++ b/storage/perfschema/pfs_user.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2010, 2012, 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 @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ /** @file storage/perfschema/pfs_user.cc diff --git a/storage/perfschema/pfs_user.h b/storage/perfschema/pfs_user.h index dda7e221ca8..2cb70e8e4ea 100644 --- a/storage/perfschema/pfs_user.h +++ b/storage/perfschema/pfs_user.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2010, 2012, 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 @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef PFS_USER_H #define PFS_USER_H diff --git a/storage/perfschema/table_esgs_by_account_by_event_name.cc b/storage/perfschema/table_esgs_by_account_by_event_name.cc index e36a0d0d00a..87b414c7c40 100644 --- a/storage/perfschema/table_esgs_by_account_by_event_name.cc +++ b/storage/perfschema/table_esgs_by_account_by_event_name.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2010, 2012, 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 @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ /** @file storage/perfschema/table_esgs_by_account_by_event_name.cc diff --git a/storage/perfschema/table_esgs_by_account_by_event_name.h b/storage/perfschema/table_esgs_by_account_by_event_name.h index c20f129de1e..2cd51783db1 100644 --- a/storage/perfschema/table_esgs_by_account_by_event_name.h +++ b/storage/perfschema/table_esgs_by_account_by_event_name.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2010, 2012, 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 @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef TABLE_ESGS_BY_ACCOUNT_BY_EVENT_NAME_H #define TABLE_ESGS_BY_ACCOUNT_BY_EVENT_NAME_H diff --git a/storage/perfschema/table_esgs_by_host_by_event_name.cc b/storage/perfschema/table_esgs_by_host_by_event_name.cc index 2357d899116..4087b22f98e 100644 --- a/storage/perfschema/table_esgs_by_host_by_event_name.cc +++ b/storage/perfschema/table_esgs_by_host_by_event_name.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2010, 2012, 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 @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ /** @file storage/perfschema/table_esgs_by_host_by_event_name.cc diff --git a/storage/perfschema/table_esgs_by_host_by_event_name.h b/storage/perfschema/table_esgs_by_host_by_event_name.h index 223923f3026..a8404e11e93 100644 --- a/storage/perfschema/table_esgs_by_host_by_event_name.h +++ b/storage/perfschema/table_esgs_by_host_by_event_name.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2010, 2012, 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 @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef TABLE_ESGS_BY_HOST_BY_EVENT_NAME_H #define TABLE_ESGS_BY_HOST_BY_EVENT_NAME_H diff --git a/storage/perfschema/table_esgs_by_user_by_event_name.cc b/storage/perfschema/table_esgs_by_user_by_event_name.cc index c7aff6fdb8d..cbaec6e16e9 100644 --- a/storage/perfschema/table_esgs_by_user_by_event_name.cc +++ b/storage/perfschema/table_esgs_by_user_by_event_name.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2010, 2012, 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 @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ /** @file storage/perfschema/table_esgs_by_user_by_event_name.cc diff --git a/storage/perfschema/table_esgs_by_user_by_event_name.h b/storage/perfschema/table_esgs_by_user_by_event_name.h index 565e633e386..9fc66033caa 100644 --- a/storage/perfschema/table_esgs_by_user_by_event_name.h +++ b/storage/perfschema/table_esgs_by_user_by_event_name.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2010, 2012, 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 @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef TABLE_ESGS_BY_USER_BY_EVENT_NAME_H #define TABLE_ESGS_BY_USER_BY_EVENT_NAME_H diff --git a/storage/perfschema/table_esms_by_account_by_event_name.cc b/storage/perfschema/table_esms_by_account_by_event_name.cc index 77f87182945..941429ad307 100644 --- a/storage/perfschema/table_esms_by_account_by_event_name.cc +++ b/storage/perfschema/table_esms_by_account_by_event_name.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2010, 2013, 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 @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ /** @file storage/perfschema/table_esms_by_account_by_event_name.cc @@ -273,6 +273,9 @@ void table_esms_by_account_by_event_name pfs_lock lock; m_row_exists= false; + if (klass->is_mutable()) + return; + account->m_lock.begin_optimistic_lock(&lock); if (m_row.m_account.make_row(account)) diff --git a/storage/perfschema/table_esms_by_account_by_event_name.h b/storage/perfschema/table_esms_by_account_by_event_name.h index d58bf9e5763..23168d03cd3 100644 --- a/storage/perfschema/table_esms_by_account_by_event_name.h +++ b/storage/perfschema/table_esms_by_account_by_event_name.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2010, 2012, 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 @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef TABLE_ESMS_BY_ACCOUNT_BY_EVENT_NAME_H #define TABLE_ESMS_BY_ACCOUNT_BY_EVENT_NAME_H diff --git a/storage/perfschema/table_esms_by_digest.cc b/storage/perfschema/table_esms_by_digest.cc index d0250c14e5d..99e24316cbb 100644 --- a/storage/perfschema/table_esms_by_digest.cc +++ b/storage/perfschema/table_esms_by_digest.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2010, 2012, 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 @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ /** @file storage/perfschema/table_esms_by_digest.cc diff --git a/storage/perfschema/table_esms_by_digest.h b/storage/perfschema/table_esms_by_digest.h index 2e2e595c056..5df8ec69633 100644 --- a/storage/perfschema/table_esms_by_digest.h +++ b/storage/perfschema/table_esms_by_digest.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2010, 2012, 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 @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef TABLE_ESMS_BY_DIGEST_H #define TABLE_ESMS_BY_DIGEST_H diff --git a/storage/perfschema/table_esms_by_host_by_event_name.cc b/storage/perfschema/table_esms_by_host_by_event_name.cc index 57aaf7602c4..d48808fd5c7 100644 --- a/storage/perfschema/table_esms_by_host_by_event_name.cc +++ b/storage/perfschema/table_esms_by_host_by_event_name.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2010, 2013, 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 @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ /** @file storage/perfschema/table_esms_by_host_by_event_name.cc @@ -270,6 +270,9 @@ void table_esms_by_host_by_event_name pfs_lock lock; m_row_exists= false; + if (klass->is_mutable()) + return; + host->m_lock.begin_optimistic_lock(&lock); if (m_row.m_host.make_row(host)) diff --git a/storage/perfschema/table_esms_by_host_by_event_name.h b/storage/perfschema/table_esms_by_host_by_event_name.h index 00c6beee561..c28f17a4473 100644 --- a/storage/perfschema/table_esms_by_host_by_event_name.h +++ b/storage/perfschema/table_esms_by_host_by_event_name.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2010, 2012, 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 @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef TABLE_ESMS_BY_HOST_BY_EVENT_NAME_H #define TABLE_ESMS_BY_HOST_BY_EVENT_NAME_H diff --git a/storage/perfschema/table_esms_by_thread_by_event_name.cc b/storage/perfschema/table_esms_by_thread_by_event_name.cc index fccdf5dea60..3f3117d6dc1 100644 --- a/storage/perfschema/table_esms_by_thread_by_event_name.cc +++ b/storage/perfschema/table_esms_by_thread_by_event_name.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2010, 2013, 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 @@ -272,6 +272,9 @@ void table_esms_by_thread_by_event_name pfs_lock lock; m_row_exists= false; + if (klass->is_mutable()) + return; + /* Protect this reader against a thread termination */ thread->m_lock.begin_optimistic_lock(&lock); diff --git a/storage/perfschema/table_esms_by_user_by_event_name.cc b/storage/perfschema/table_esms_by_user_by_event_name.cc index d65a255e280..1434966204f 100644 --- a/storage/perfschema/table_esms_by_user_by_event_name.cc +++ b/storage/perfschema/table_esms_by_user_by_event_name.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2010, 2013, 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 @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ /** @file storage/perfschema/table_esms_by_user_by_event_name.cc @@ -270,6 +270,9 @@ void table_esms_by_user_by_event_name pfs_lock lock; m_row_exists= false; + if (klass->is_mutable()) + return; + user->m_lock.begin_optimistic_lock(&lock); if (m_row.m_user.make_row(user)) diff --git a/storage/perfschema/table_esms_by_user_by_event_name.h b/storage/perfschema/table_esms_by_user_by_event_name.h index 4f52b64b6b8..6dc481d3273 100644 --- a/storage/perfschema/table_esms_by_user_by_event_name.h +++ b/storage/perfschema/table_esms_by_user_by_event_name.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2010, 2012, 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 @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef TABLE_ESMS_BY_USER_BY_EVENT_NAME_H #define TABLE_ESMS_BY_USER_BY_EVENT_NAME_H diff --git a/storage/perfschema/table_esms_global_by_event_name.cc b/storage/perfschema/table_esms_global_by_event_name.cc index efcb5b6fa7c..a335c8e6c5d 100644 --- a/storage/perfschema/table_esms_global_by_event_name.cc +++ b/storage/perfschema/table_esms_global_by_event_name.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2010, 2013, 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 @@ -258,6 +258,11 @@ table_esms_global_by_event_name::rnd_pos(const void *pos) void table_esms_global_by_event_name ::make_row(PFS_statement_class *klass) { + m_row_exists= false; + + if (klass->is_mutable()) + return; + m_row.m_event_name.make_row(klass); PFS_connection_statement_visitor visitor(klass); diff --git a/storage/perfschema/table_events_statements.cc b/storage/perfschema/table_events_statements.cc index fb2b4b242d4..84bad033ec3 100644 --- a/storage/perfschema/table_events_statements.cc +++ b/storage/perfschema/table_events_statements.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2010, 2013, 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 @@ -301,7 +301,8 @@ table_events_statements_common::table_events_statements_common Build a row. @param statement the statement the cursor is reading */ -void table_events_statements_common::make_row(PFS_events_statements *statement) +void table_events_statements_common::make_row_part_1(PFS_events_statements *statement, + PSI_digest_storage *digest) { const char *base; const char *safe_source_file; @@ -367,15 +368,28 @@ void table_events_statements_common::make_row(PFS_events_statements *statement) m_row.m_no_index_used= statement->m_no_index_used; m_row.m_no_good_index_used= statement->m_no_good_index_used; /* + Making a copy of digest storage. + */ + digest_copy(digest, & statement->m_digest_storage); + + m_row_exists= true; + return; +} + + +void table_events_statements_common::make_row_part_2(PSI_digest_storage *digest) +{ + /* Filling up statement digest information. */ - PSI_digest_storage *digest= & statement->m_digest_storage; - if (digest->m_byte_count > 0) + int safe_byte_count= digest->m_byte_count; + if (safe_byte_count > 0 && + safe_byte_count <= PSI_MAX_DIGEST_STORAGE_SIZE) { PFS_digest_key md5; compute_md5_hash((char *) md5.m_md5, (char *) digest->m_token_array, - digest->m_byte_count); + safe_byte_count); /* Generate the DIGEST string from the MD5 digest */ MD5_HASH_TO_STRING(md5.m_md5, @@ -385,6 +399,9 @@ void table_events_statements_common::make_row(PFS_events_statements *statement) /* Generate the DIGEST_TEXT string from the token array */ get_digest_text(m_row.m_digest.m_digest_text, digest); m_row.m_digest.m_digest_text_length= strlen(m_row.m_digest.m_digest_text); + + if (m_row.m_digest.m_digest_text_length == 0) + m_row.m_digest.m_digest_length= 0; } else { @@ -392,7 +409,6 @@ void table_events_statements_common::make_row(PFS_events_statements *statement) m_row.m_digest.m_digest_text_length= 0; } - m_row_exists= true; return; } @@ -645,7 +661,7 @@ int table_events_statements_current::rnd_next(void) statement= &pfs_thread->m_statement_stack[m_pos.m_index_2]; - make_row(statement); + make_row(pfs_thread, statement); m_next_pos.set_after(&m_pos); return 0; } @@ -687,10 +703,35 @@ int table_events_statements_current::rnd_pos(const void *pos) if (statement->m_class == NULL) return HA_ERR_RECORD_DELETED; - make_row(statement); + make_row(pfs_thread, statement); return 0; } +void table_events_statements_current::make_row(PFS_thread *pfs_thread, + PFS_events_statements *statement) +{ + PSI_digest_storage digest; + pfs_lock lock; + pfs_lock stmt_lock; + + digest_reset(&digest); + /* Protect this reader against thread termination. */ + pfs_thread->m_lock.begin_optimistic_lock(&lock); + /* Protect this reader against writing on statement information. */ + pfs_thread->m_stmt_lock.begin_optimistic_lock(&stmt_lock); + + table_events_statements_common::make_row_part_1(statement, &digest); + + if (!pfs_thread->m_stmt_lock.end_optimistic_lock(&stmt_lock) || + !pfs_thread->m_lock.end_optimistic_lock(&lock)) + { + m_row_exists= false; + return; + } + table_events_statements_common::make_row_part_2(&digest); + return; +} + int table_events_statements_current::delete_all_rows(void) { reset_events_statements_current(); @@ -756,7 +797,7 @@ int table_events_statements_history::rnd_next(void) if (statement->m_class != NULL) { - make_row(statement); + make_row(pfs_thread, statement); /* Next iteration, look for the next history in this thread */ m_next_pos.set_after(&m_pos); return 0; @@ -790,10 +831,31 @@ int table_events_statements_history::rnd_pos(const void *pos) if (statement->m_class == NULL) return HA_ERR_RECORD_DELETED; - make_row(statement); + make_row(pfs_thread, statement); return 0; } +void table_events_statements_history::make_row(PFS_thread *pfs_thread, + PFS_events_statements *statement) +{ + PSI_digest_storage digest; + pfs_lock lock; + + digest_reset(&digest); + /* Protect this reader against thread termination. */ + pfs_thread->m_lock.begin_optimistic_lock(&lock); + + table_events_statements_common::make_row_part_1(statement, &digest); + + if (!pfs_thread->m_lock.end_optimistic_lock(&lock)) + { + m_row_exists= false; + return; + } + table_events_statements_common::make_row_part_2(&digest); + return; +} + int table_events_statements_history::delete_all_rows(void) { reset_events_statements_history(); @@ -878,6 +940,17 @@ int table_events_statements_history_long::rnd_pos(const void *pos) return 0; } +void table_events_statements_history_long::make_row(PFS_events_statements *statement) +{ + PSI_digest_storage digest; + + digest_reset(&digest); + table_events_statements_common::make_row_part_1(statement, &digest); + + table_events_statements_common::make_row_part_2(&digest); + return; +} + int table_events_statements_history_long::delete_all_rows(void) { reset_events_statements_history_long(); diff --git a/storage/perfschema/table_events_statements.h b/storage/perfschema/table_events_statements.h index dcc6611f555..e33c6b505bd 100644 --- a/storage/perfschema/table_events_statements.h +++ b/storage/perfschema/table_events_statements.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2010, 2013, 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 @@ -174,7 +174,10 @@ protected: ~table_events_statements_common() {} - void make_row(PFS_events_statements *statement); + void make_row_part_1(PFS_events_statements *statement, + PSI_digest_storage *digest); + + void make_row_part_2(PSI_digest_storage *digest); /** Current row. */ row_events_statements m_row; @@ -216,6 +219,8 @@ private: */ static TABLE_FIELD_DEF m_field_def; + void make_row(PFS_thread* pfs_thread, PFS_events_statements *statement); + /** Current position. */ pos_events_statements_current m_pos; /** Next position. */ @@ -247,6 +252,8 @@ private: /** Table share lock. */ static THR_LOCK m_table_lock; + void make_row(PFS_thread* pfs_thread, PFS_events_statements *statement); + /** Current position. */ pos_events_statements_history m_pos; /** Next position. */ @@ -278,6 +285,8 @@ private: /** Table share lock. */ static THR_LOCK m_table_lock; + void make_row(PFS_events_statements *statement); + /** Current position. */ PFS_simple_index m_pos; /** Next position. */ diff --git a/storage/perfschema/table_ews_by_account_by_event_name.cc b/storage/perfschema/table_ews_by_account_by_event_name.cc index 992e7c18f17..a4b44458027 100644 --- a/storage/perfschema/table_ews_by_account_by_event_name.cc +++ b/storage/perfschema/table_ews_by_account_by_event_name.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2010, 2012, 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 @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ /** @file storage/perfschema/table_ews_by_account_by_event_name.cc diff --git a/storage/perfschema/table_ews_by_account_by_event_name.h b/storage/perfschema/table_ews_by_account_by_event_name.h index 0a0ca83131a..8ccfee599eb 100644 --- a/storage/perfschema/table_ews_by_account_by_event_name.h +++ b/storage/perfschema/table_ews_by_account_by_event_name.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2010, 2011, 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 @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef TABLE_EWS_BY_ACCOUNT_BY_EVENT_NAME_H #define TABLE_EWS_BY_ACCOUNT_BY_EVENT_NAME_H diff --git a/storage/perfschema/table_ews_by_host_by_event_name.cc b/storage/perfschema/table_ews_by_host_by_event_name.cc index 8a62990c8ed..5a02235bcb2 100644 --- a/storage/perfschema/table_ews_by_host_by_event_name.cc +++ b/storage/perfschema/table_ews_by_host_by_event_name.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2010, 2012, 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 @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ /** @file storage/perfschema/table_ews_by_host_by_event_name.cc diff --git a/storage/perfschema/table_ews_by_host_by_event_name.h b/storage/perfschema/table_ews_by_host_by_event_name.h index 28b8d0250c2..124b121e8d2 100644 --- a/storage/perfschema/table_ews_by_host_by_event_name.h +++ b/storage/perfschema/table_ews_by_host_by_event_name.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2010, 2011, 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 @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef TABLE_EWS_BY_HOST_BY_EVENT_NAME_H #define TABLE_EWS_BY_HOST_BY_EVENT_NAME_H diff --git a/storage/perfschema/table_ews_by_user_by_event_name.cc b/storage/perfschema/table_ews_by_user_by_event_name.cc index 8a169019e87..46f2ba568fb 100644 --- a/storage/perfschema/table_ews_by_user_by_event_name.cc +++ b/storage/perfschema/table_ews_by_user_by_event_name.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2010, 2012, 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 @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ /** @file storage/perfschema/table_ews_by_user_by_event_name.cc diff --git a/storage/perfschema/table_ews_by_user_by_event_name.h b/storage/perfschema/table_ews_by_user_by_event_name.h index 88b78a1ed7a..123ee2349ae 100644 --- a/storage/perfschema/table_ews_by_user_by_event_name.h +++ b/storage/perfschema/table_ews_by_user_by_event_name.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2010, 2011, 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 @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef TABLE_EWS_BY_USER_BY_EVENT_NAME_H #define TABLE_EWS_BY_USER_BY_EVENT_NAME_H diff --git a/storage/perfschema/table_helper.cc b/storage/perfschema/table_helper.cc index 9f803434ab6..9c10a3ecc88 100644 --- a/storage/perfschema/table_helper.cc +++ b/storage/perfschema/table_helper.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2010, 2013, 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 @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ /** @file storage/perfschema/table_helper.cc @@ -103,16 +103,23 @@ void PFS_account_row::set_field(uint index, Field *f) int PFS_digest_row::make_row(PFS_statements_digest_stat* pfs) { + m_schema_name_length= pfs->m_digest_key.m_schema_name_length; + if (m_schema_name_length > sizeof(m_schema_name)) + m_schema_name_length= 0; + if (m_schema_name_length > 0) + memcpy(m_schema_name, pfs->m_digest_key.m_schema_name, m_schema_name_length); + + int safe_byte_count= pfs->m_digest_storage.m_byte_count; + if (safe_byte_count > PSI_MAX_DIGEST_STORAGE_SIZE) + safe_byte_count= 0; + /* "0" value for byte_count indicates special entry i.e. aggregated stats at index 0 of statements_digest_stat_array. So do not calculate digest/digest_text as it should always be "NULL". */ - if (pfs->m_digest_storage.m_byte_count != 0) + if (safe_byte_count > 0) { - m_schema_name_length= pfs->m_digest_key.m_schema_name_length; - if (m_schema_name_length > 0) - memcpy(m_schema_name, pfs->m_digest_key.m_schema_name, m_schema_name_length); /* Calculate digest from MD5 HASH collected to be shown as DIGEST in this row. @@ -126,10 +133,12 @@ int PFS_digest_row::make_row(PFS_statements_digest_stat* pfs) */ get_digest_text(m_digest_text, &pfs->m_digest_storage); m_digest_text_length= strlen(m_digest_text); + + if (m_digest_text_length == 0) + m_digest_length= 0; } else { - m_schema_name_length= 0; m_digest_length= 0; m_digest_text_length= 0; } diff --git a/storage/perfschema/table_helper.h b/storage/perfschema/table_helper.h index 769122570eb..76bb289c73b 100644 --- a/storage/perfschema/table_helper.h +++ b/storage/perfschema/table_helper.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2008, 2011, 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 @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef PFS_TABLE_HELPER_H #define PFS_TABLE_HELPER_H @@ -222,7 +222,7 @@ struct PFS_stat_row { m_count= stat->m_count; - if (m_count) + if ((m_count != 0) && stat->has_timed_stats()) { m_sum= normalizer->wait_to_pico(stat->m_sum); m_min= normalizer->wait_to_pico(stat->m_min); @@ -437,7 +437,7 @@ struct PFS_statement_stat_row m_select_range= stat->m_select_range; m_select_range_check= stat->m_select_range_check; m_select_scan= stat->m_select_scan; - m_sort_merge_passes= stat->m_sort_range; + m_sort_merge_passes= stat->m_sort_merge_passes; m_sort_range= stat->m_sort_range; m_sort_rows= stat->m_sort_rows; m_sort_scan= stat->m_sort_scan; diff --git a/storage/perfschema/table_host_cache.cc b/storage/perfschema/table_host_cache.cc index 02c7f72140a..57f1ea42a02 100644 --- a/storage/perfschema/table_host_cache.cc +++ b/storage/perfschema/table_host_cache.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2011, 2012, 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 diff --git a/storage/perfschema/table_host_cache.h b/storage/perfschema/table_host_cache.h index 543da1274e9..74795707ac1 100644 --- a/storage/perfschema/table_host_cache.h +++ b/storage/perfschema/table_host_cache.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2011, 2012, 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 diff --git a/storage/perfschema/table_os_global_by_type.cc b/storage/perfschema/table_os_global_by_type.cc index 70d9d6819ac..954128a7647 100644 --- a/storage/perfschema/table_os_global_by_type.cc +++ b/storage/perfschema/table_os_global_by_type.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2010, 2012, 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 @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ /** @file storage/perfschema/table_os_global_by_type.cc diff --git a/storage/perfschema/table_os_global_by_type.h b/storage/perfschema/table_os_global_by_type.h index 585bf6bbca5..888e3760488 100644 --- a/storage/perfschema/table_os_global_by_type.h +++ b/storage/perfschema/table_os_global_by_type.h @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef TABLE_OBJECTS_SUMMARY_GLOBAL_BY_TYPE_H #define TABLE_OBJECTS_SUMMARY_GLOBAL_BY_TYPE_H diff --git a/storage/perfschema/table_session_connect.cc b/storage/perfschema/table_session_connect.cc index bd905b5756c..bea9b7c94db 100644 --- a/storage/perfschema/table_session_connect.cc +++ b/storage/perfschema/table_session_connect.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2008, 2013, 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 @@ -42,9 +42,26 @@ static const TABLE_FIELD_TYPE field_types[]= TABLE_FIELD_DEF table_session_connect::m_field_def= { 4, field_types }; -table_session_connect::table_session_connect(const PFS_engine_table_share *share) : - cursor_by_thread_connect_attr(share) -{} +table_session_connect::table_session_connect(const PFS_engine_table_share *share) + : cursor_by_thread_connect_attr(share) +{ + if (session_connect_attrs_size_per_thread > 0) + { + m_copy_session_connect_attrs= (char *) my_malloc(/* 5.7: PSI_INSTRUMENT_ME, */ + session_connect_attrs_size_per_thread, + MYF(0)); + } + else + { + m_copy_session_connect_attrs= NULL; + } + m_copy_session_connect_attrs_length= 0; +} + +table_session_connect::~table_session_connect() +{ + my_free(m_copy_session_connect_attrs); +} /** Take a length encoded string @@ -175,12 +192,17 @@ bool read_nth_attr(const char *connect_attrs, void table_session_connect::make_row(PFS_thread *pfs, uint ordinal) { pfs_lock lock; + pfs_lock session_lock; PFS_thread_class *safe_class; + const CHARSET_INFO *cs; m_row_exists= false; /* Protect this reader against thread termination */ pfs->m_lock.begin_optimistic_lock(&lock); + /* Protect this reader against writing on session attributes */ + pfs->m_session_lock.begin_optimistic_lock(&session_lock); + safe_class= sanitize_thread_class(pfs->m_class); if (unlikely(safe_class == NULL)) return; @@ -189,10 +211,39 @@ void table_session_connect::make_row(PFS_thread *pfs, uint ordinal) if (! thread_fits(pfs)) return; + /* Make a safe copy of the session attributes */ + + if (m_copy_session_connect_attrs == NULL) + return; + + m_copy_session_connect_attrs_length= pfs->m_session_connect_attrs_length; + + if (m_copy_session_connect_attrs_length > session_connect_attrs_size_per_thread) + return; + + memcpy(m_copy_session_connect_attrs, + pfs->m_session_connect_attrs, + m_copy_session_connect_attrs_length); + + cs= get_charset(pfs->m_session_connect_attrs_cs_number, MYF(0)); + if (cs == NULL) + return; + + if (! pfs->m_session_lock.end_optimistic_lock(& session_lock)) + return; + + if (! pfs->m_lock.end_optimistic_lock(& lock)) + return; + + /* + Now we have a safe copy of the data, + that will not change while parsing it + */ + /* populate the row */ - if (read_nth_attr(pfs->m_session_connect_attrs, - pfs->m_session_connect_attrs_length, - pfs->m_session_connect_attrs_cs, + if (read_nth_attr(m_copy_session_connect_attrs, + m_copy_session_connect_attrs_length, + cs, ordinal, m_row.m_attr_name, (uint) sizeof(m_row.m_attr_name), &m_row.m_attr_name_length, @@ -204,12 +255,9 @@ void table_session_connect::make_row(PFS_thread *pfs, uint ordinal) m_row.m_ordinal_position= ordinal; m_row.m_process_id= pfs->m_processlist_id; - } - else - return; - if (pfs->m_lock.end_optimistic_lock(& lock)) m_row_exists= true; + } } int table_session_connect::read_row_values(TABLE *table, diff --git a/storage/perfschema/table_session_connect.h b/storage/perfschema/table_session_connect.h index 097623d2c80..e6faa283e42 100644 --- a/storage/perfschema/table_session_connect.h +++ b/storage/perfschema/table_session_connect.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2012, 2013, 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 @@ -58,8 +58,7 @@ protected: table_session_connect(const PFS_engine_table_share *share); public: - ~table_session_connect() - {} + ~table_session_connect(); protected: virtual void make_row(PFS_thread *pfs, uint ordinal); @@ -71,6 +70,10 @@ protected: static TABLE_FIELD_DEF m_field_def; /** Current row. */ row_session_connect_attrs m_row; + /** Safe copy of @c PFS_thread::m_session_connect_attrs. */ + char *m_copy_session_connect_attrs; + /** Safe copy of @c PFS_thread::m_session_connect_attrs_length. */ + uint m_copy_session_connect_attrs_length; }; /** @} */ diff --git a/storage/perfschema/table_setup_actors.cc b/storage/perfschema/table_setup_actors.cc index 91dbb942ead..00699a9c2e5 100644 --- a/storage/perfschema/table_setup_actors.cc +++ b/storage/perfschema/table_setup_actors.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2010, 2012, 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 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; diff --git a/storage/perfschema/table_tiws_by_table.cc b/storage/perfschema/table_tiws_by_table.cc index f793b5654a2..ab6ad3f5e3f 100644 --- a/storage/perfschema/table_tiws_by_table.cc +++ b/storage/perfschema/table_tiws_by_table.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2010, 2012, 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 @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ /** @file storage/perfschema/table_tiws_by_table.cc diff --git a/storage/perfschema/table_tiws_by_table.h b/storage/perfschema/table_tiws_by_table.h index 747b1958c8e..ea52b5297d7 100644 --- a/storage/perfschema/table_tiws_by_table.h +++ b/storage/perfschema/table_tiws_by_table.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2010, 2012, 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 @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef TABLE_IO_WAITS_SUMMARY_BY_TABLE_H #define TABLE_IO_WAITS_SUMMARY_BY_TABLE_H diff --git a/storage/perfschema/table_tlws_by_table.cc b/storage/perfschema/table_tlws_by_table.cc index c6f454ac178..7d33b42648e 100644 --- a/storage/perfschema/table_tlws_by_table.cc +++ b/storage/perfschema/table_tlws_by_table.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2010, 2012, 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 @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ /** @file storage/perfschema/table_tlws_by_table.cc diff --git a/storage/perfschema/table_tlws_by_table.h b/storage/perfschema/table_tlws_by_table.h index c5521c72470..fc396447bcf 100644 --- a/storage/perfschema/table_tlws_by_table.h +++ b/storage/perfschema/table_tlws_by_table.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2010, 2012, 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 @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef TABLE_LOCK_WAITS_SUMMARY_BY_TABLE_H #define TABLE_LOCK_WAITS_SUMMARY_BY_TABLE_H diff --git a/storage/perfschema/unittest/CMakeLists.txt b/storage/perfschema/unittest/CMakeLists.txt index 47539ffd211..b237d6b4ee0 100644 --- a/storage/perfschema/unittest/CMakeLists.txt +++ b/storage/perfschema/unittest/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2009, 2013, 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 @@ -11,7 +11,7 @@ # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02111-1307 USA +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/include/mysql @@ -63,7 +63,7 @@ TARGET_LINK_LIBRARIES(pfs_connect_attr-t ${MYSQLD_STATIC_PLUGIN_LIBS}) TARGET_LINK_LIBRARIES(pfs_connect_attr-t sql binlog rpl master slave sql) TARGET_LINK_LIBRARIES(pfs_connect_attr-t mysys mysys_ssl) TARGET_LINK_LIBRARIES(pfs_connect_attr-t vio ${SSL_LIBRARIES}) -TARGET_LINK_LIBRARIES(pfs_connect_attr-t strings dbug regex mysys zlib) +TARGET_LINK_LIBRARIES(pfs_connect_attr-t strings dbug regex mysys ${ZLIB_LIBRARY}) ADD_TEST(pfs_connect_attr pfs_connect_attr-t) # On windows, pfs_connect_attr-t may depend on openssl dlls. diff --git a/storage/perfschema/unittest/pfs_account-oom-t.cc b/storage/perfschema/unittest/pfs_account-oom-t.cc index f877615da0f..7574de542f8 100644 --- a/storage/perfschema/unittest/pfs_account-oom-t.cc +++ b/storage/perfschema/unittest/pfs_account-oom-t.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2011, 2012, 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 diff --git a/storage/perfschema/unittest/pfs_host-oom-t.cc b/storage/perfschema/unittest/pfs_host-oom-t.cc index cdc9764210a..32d9c23cbde 100644 --- a/storage/perfschema/unittest/pfs_host-oom-t.cc +++ b/storage/perfschema/unittest/pfs_host-oom-t.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2011, 2012, 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 diff --git a/storage/perfschema/unittest/stub_pfs_defaults.h b/storage/perfschema/unittest/stub_pfs_defaults.h index 042d069b367..f4fa24245d5 100644 --- a/storage/perfschema/unittest/stub_pfs_defaults.h +++ b/storage/perfschema/unittest/stub_pfs_defaults.h @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #include <my_global.h> #include <pfs.h> diff --git a/storage/perfschema/unittest/stub_server_misc.h b/storage/perfschema/unittest/stub_server_misc.h index 8b008273bd8..946da533727 100644 --- a/storage/perfschema/unittest/stub_server_misc.h +++ b/storage/perfschema/unittest/stub_server_misc.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2010, 2012, 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 @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ /* Minimal code to be able to link a unit test. |