From 04bce7b569f44f3aca3cb21953d41c2a4a02efe6 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Wed, 7 May 2014 10:04:30 +0200 Subject: 5.6.17 --- storage/perfschema/pfs.cc | 179 ++++++++++++++++++++++++++++------------------ 1 file changed, 111 insertions(+), 68 deletions(-) (limited to 'storage/perfschema/pfs.cc') 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 (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 (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 (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 (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 (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 (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; } -- cgit v1.2.1