diff options
Diffstat (limited to 'storage/perfschema/pfs.cc')
-rw-r--r-- | storage/perfschema/pfs.cc | 595 |
1 files changed, 414 insertions, 181 deletions
diff --git a/storage/perfschema/pfs.cc b/storage/perfschema/pfs.cc index d3de38d025c..33b21ee2817 100644 --- a/storage/perfschema/pfs.cc +++ b/storage/perfschema/pfs.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 @@ -688,6 +688,7 @@ static inline int mysql_mutex_lock(...) - socket io (MYSQL_SOCKET) - table io - table lock + - idle The flow of data between aggregates tables varies for each instrumentation. @@ -857,24 +858,35 @@ static inline int mysql_mutex_lock(...) @subsection IMPL_WAIT_SOCKET Socket waits @verbatim - socket_locker(T, F) + socket_locker(T, S) | | [1] | - |-> pfs_socket(F) =====>> [A], [B], [C], [D], [E] + |-> pfs_socket(S) =====>> [A], [B], [C], [D], [E] | | [2] | - |-> pfs_socket_class(F.class) =====>> [C], [D] + |-> pfs_socket_class(S.class) =====>> [C], [D] | - |-> pfs_thread(T).event_name(F) =====>> [A] + |-> pfs_thread(T).event_name(S) =====>> [A] | - ... + | [3] + | + 3a |-> pfs_account(U, H).event_name(S) =====>> [F], [G], [H] + . | + . | [4-RESET] + . | + 3b .....+-> pfs_user(U).event_name(S) =====>> [G] + . | + 3c .....+-> pfs_host(H).event_name(S) =====>> [H] @endverbatim Implemented as: - [1] @c start_socket_wait_v1(), @c end_socket_wait_v1(). - [2] @c close_socket_v1() + - [3] @c aggregate_thread_waits() + - [4] @c PFS_account::aggregate_waits() + - [5] @c PFS_host::aggregate_waits() - [A] EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME, @c table_ews_by_thread_by_event_name::make_row() - [B] EVENTS_WAITS_SUMMARY_BY_INSTANCE, @@ -885,37 +897,78 @@ static inline int mysql_mutex_lock(...) @c table_socket_summary_by_event_name::make_row() - [E] SOCKET_SUMMARY_BY_INSTANCE, @c table_socket_summary_by_instance::make_row() + - [F] EVENTS_WAITS_SUMMARY_BY_ACCOUNT_BY_EVENT_NAME, + @c table_ews_by_account_by_event_name::make_row() + - [G] EVENTS_WAITS_SUMMARY_BY_USER_BY_EVENT_NAME, + @c table_ews_by_user_by_event_name::make_row() + - [H] EVENTS_WAITS_SUMMARY_BY_HOST_BY_EVENT_NAME, + @c table_ews_by_host_by_event_name::make_row() @subsection IMPL_WAIT_TABLE Table waits @verbatim - table_locker(T, Tb) + table_locker(Thread Th, Table Tb, Event = io or lock) | | [1] | - |-> pfs_table(Tb) =====>> [B], [C], [D] - | - | [2] - | - |-> pfs_table_share(Tb.share) =====>> [C], [D] - | - |-> pfs_thread(T).event_name(Tb) =====>> [A] - | - ... +1a |-> pfs_table(Tb) =====>> [A], [B], [C] + | | + | | [2] + | | + | |-> pfs_table_share(Tb.share) =====>> [B], [C] + | | + | | [3] + | | + | |-> global_table_io_stat =====>> [C] + | | + | |-> global_table_lock_stat =====>> [C] + | +1b |-> pfs_thread(Th).event_name(E) =====>> [D], [E], [F], [G] + | | + | | [ 4-RESET] + | | + | |-> pfs_account(U, H).event_name(E) =====>> [E], [F], [G] + | . | + | . | [5-RESET] + | . | + | .....+-> pfs_user(U).event_name(E) =====>> [F] + | . | + | .....+-> pfs_host(H).event_name(E) =====>> [G] + | +1c |-> pfs_thread(Th).waits_current(W) =====>> [H] + | +1d |-> pfs_thread(Th).waits_history(W) =====>> [I] + | +1e |-> waits_history_long(W) =====>> [J] @endverbatim Implemented as: - [1] @c start_table_io_wait_v1(), @c end_table_io_wait_v1() - [2] @c close_table_v1() - - [A] EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME, - @c table_ews_by_thread_by_event_name::make_row() - - [B] EVENTS_WAITS_SUMMARY_BY_INSTANCE, + - [3] @c drop_table_share_v1() + - [4] @c TRUNCATE TABLE EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME + - [5] @c TRUNCATE TABLE EVENTS_WAITS_SUMMARY_BY_ACCOUNT_BY_EVENT_NAME + - [A] EVENTS_WAITS_SUMMARY_BY_INSTANCE, @c table_events_waits_summary_by_instance::make_table_row() + - [B] OBJECTS_SUMMARY_GLOBAL_BY_TYPE, + @c table_os_global_by_type::make_row() - [C] EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME, @c table_ews_global_by_event_name::make_table_io_row(), @c table_ews_global_by_event_name::make_table_lock_row() - - [D] OBJECTS_SUMMARY_GLOBAL_BY_TYPE, - @c table_os_global_by_type::make_row() + - [D] EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME, + @c table_ews_by_thread_by_event_name::make_row() + - [E] EVENTS_WAITS_SUMMARY_BY_ACCOUNT_BY_EVENT_NAME, + @c table_ews_by_user_by_account_name::make_row() + - [F] EVENTS_WAITS_SUMMARY_BY_USER_BY_EVENT_NAME, + @c table_ews_by_user_by_event_name::make_row() + - [G] EVENTS_WAITS_SUMMARY_BY_HOST_BY_EVENT_NAME, + @c table_ews_by_host_by_event_name::make_row() + - [H] EVENTS_WAITS_CURRENT, + @c table_events_waits_common::make_row() + - [I] EVENTS_WAITS_HISTORY, + @c table_events_waits_common::make_row() + - [J] EVENTS_WAITS_HISTORY_LONG, + @c table_events_waits_common::make_row() @section IMPL_STAGE Implementation for stages aggregates @@ -1594,7 +1647,6 @@ static void unbind_table_v1(PSI_table *table) PFS_table *pfs= reinterpret_cast<PFS_table*> (table); if (likely(pfs != NULL)) { - pfs->aggregate(); pfs->m_thread_owner= NULL; } } @@ -1615,12 +1667,6 @@ rebind_table_v1(PSI_table_share *share, const void *identity, PSI_table *table) /* The table handle was already instrumented, reuse it for this thread. */ thread= my_pthread_getspecific_ptr(PFS_thread*, THR_PFS); - if (unlikely(thread == NULL)) - { - destroy_table(pfs); - return NULL; - } - if (unlikely(! pfs->m_share->m_enabled)) { destroy_table(pfs); @@ -1660,8 +1706,6 @@ 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); @@ -1681,9 +1725,18 @@ static void close_table_v1(PSI_table *table) } static PSI_socket* -init_socket_v1(PSI_socket_key key, const my_socket *fd) +init_socket_v1(PSI_socket_key key, const my_socket *fd, + const struct sockaddr *addr, socklen_t addr_len) { - INIT_BODY_V1(socket, key, fd); + PFS_socket_class *klass; + PFS_socket *pfs; + klass= find_socket_class(key); + if (unlikely(klass == NULL)) + return NULL; + if (! klass->m_enabled) + return NULL; + pfs= create_socket(klass, fd, addr, addr_len); + return reinterpret_cast<PSI_socket *> (pfs); } static void destroy_socket_v1(PSI_socket *socket) @@ -1731,7 +1784,7 @@ static void create_file_v1(PSI_file_key key, const char *name, File file) } uint len= strlen(name); - PFS_file *pfs_file= find_or_create_file(pfs_thread, klass, name, len); + PFS_file *pfs_file= find_or_create_file(pfs_thread, klass, name, len, true); file_handle_array[index]= pfs_file; } @@ -1835,13 +1888,13 @@ static int spawn_thread_v1(PSI_thread_key key, @sa PSI_v1::new_thread. */ static PSI_thread* -new_thread_v1(PSI_thread_key key, const void *identity, ulong thread_id) +new_thread_v1(PSI_thread_key key, const void *identity, ulonglong processlist_id) { PFS_thread *pfs; PFS_thread_class *klass= find_thread_class(key); if (likely(klass != NULL)) - pfs= create_thread(klass, identity, thread_id); + pfs= create_thread(klass, identity, processlist_id); else pfs= NULL; @@ -1852,12 +1905,12 @@ new_thread_v1(PSI_thread_key key, const void *identity, ulong thread_id) Implementation of the thread instrumentation interface. @sa PSI_v1::set_thread_id. */ -static void set_thread_id_v1(PSI_thread *thread, unsigned long id) +static void set_thread_id_v1(PSI_thread *thread, ulonglong processlist_id) { PFS_thread *pfs= reinterpret_cast<PFS_thread*> (thread); if (unlikely(pfs == NULL)) return; - pfs->m_thread_id= id; + pfs->m_processlist_id= processlist_id; } /** @@ -2045,10 +2098,10 @@ static void set_thread_state_v1(const char* state) { int state_len= state ? strlen(state) : 0; - pfs->m_lock.allocated_to_dirty(); + pfs->m_processlist_lock.allocated_to_dirty(); pfs->m_processlist_state_ptr= state; pfs->m_processlist_state_length= state_len; - pfs->m_lock.dirty_to_allocated(); + pfs->m_processlist_lock.dirty_to_allocated(); } } @@ -2060,12 +2113,14 @@ static void set_thread_info_v1(const char* info, int info_len) { PFS_thread *pfs= my_pthread_getspecific_ptr(PFS_thread*, THR_PFS); + DBUG_ASSERT((info != NULL) || (info_len == 0)); + if (likely(pfs != NULL)) { - pfs->m_lock.allocated_to_dirty(); + pfs->m_processlist_lock.allocated_to_dirty(); pfs->m_processlist_info_ptr= info; pfs->m_processlist_info_length= info_len; - pfs->m_lock.dirty_to_allocated(); + pfs->m_processlist_lock.dirty_to_allocated(); } } @@ -2196,7 +2251,7 @@ start_mutex_wait_v1(PSI_mutex_locker_state *state, Complete shortcut. */ /* Aggregate to EVENTS_WAITS_SUMMARY_BY_INSTANCE (counted) */ - pfs_mutex->m_wait_stat.aggregate_counted(); + pfs_mutex->m_mutex_stat.m_wait_stat.aggregate_counted(); return NULL; } } @@ -2294,7 +2349,7 @@ start_rwlock_wait_v1(PSI_rwlock_locker_state *state, Complete shortcut. */ /* Aggregate to EVENTS_WAITS_SUMMARY_BY_INSTANCE (counted) */ - pfs_rwlock->m_wait_stat.aggregate_counted(); + pfs_rwlock->m_rwlock_stat.m_wait_stat.aggregate_counted(); return NULL; } } @@ -2401,7 +2456,7 @@ start_cond_wait_v1(PSI_cond_locker_state *state, Complete shortcut. */ /* Aggregate to EVENTS_WAITS_SUMMARY_BY_INSTANCE (counted) */ - pfs_cond->m_wait_stat.aggregate_counted(); + pfs_cond->m_cond_stat.m_wait_stat.aggregate_counted(); return NULL; } } @@ -2478,8 +2533,6 @@ start_table_io_wait_v1(PSI_table_locker_state *state, return NULL; PFS_thread *pfs_thread= pfs_table->m_thread_owner; - if (unlikely(pfs_thread == NULL)) - return NULL; DBUG_ASSERT(pfs_thread == my_pthread_getspecific_ptr(PFS_thread*, THR_PFS)); @@ -2489,6 +2542,8 @@ start_table_io_wait_v1(PSI_table_locker_state *state, if (flag_thread_instrumentation) { + if (pfs_thread == NULL) + return NULL; if (! pfs_thread->m_enabled) return NULL; state->m_thread= reinterpret_cast<PSI_thread *> (pfs_thread); @@ -2538,7 +2593,6 @@ start_table_io_wait_v1(PSI_table_locker_state *state, pfs_thread->m_events_waits_current++; } - /* TODO: consider a shortcut here */ } else { @@ -2585,11 +2639,6 @@ start_table_lock_wait_v1(PSI_table_locker_state *state, return NULL; PFS_thread *pfs_thread= pfs_table->m_thread_owner; - if (unlikely(pfs_thread == NULL)) - return NULL; - - DBUG_ASSERT(pfs_thread == - my_pthread_getspecific_ptr(PFS_thread*, THR_PFS)); PFS_TL_LOCK_TYPE lock_type; @@ -2619,6 +2668,8 @@ start_table_lock_wait_v1(PSI_table_locker_state *state, if (flag_thread_instrumentation) { + if (pfs_thread == NULL) + return NULL; if (! pfs_thread->m_enabled) return NULL; state->m_thread= reinterpret_cast<PSI_thread *> (pfs_thread); @@ -2668,7 +2719,6 @@ start_table_lock_wait_v1(PSI_table_locker_state *state, pfs_thread->m_events_waits_current++; } - /* TODO: consider a shortcut here */ } else { @@ -2729,11 +2779,6 @@ get_thread_file_name_locker_v1(PSI_file_locker_state *state, if (klass->m_timed) flags|= STATE_FLAG_TIMED; - uint len= strlen(name); - PFS_file *pfs_file= find_or_create_file(pfs_thread, klass, name, len); - if (unlikely(pfs_file == NULL)) - return NULL; - if (flag_events_waits_current) { if (unlikely(pfs_thread->m_events_waits_current >= @@ -2755,9 +2800,9 @@ get_thread_file_name_locker_v1(PSI_file_locker_state *state, wait->m_class= klass; wait->m_timer_start= 0; wait->m_timer_end= 0; - wait->m_object_instance_addr= pfs_file; - wait->m_weak_file= pfs_file; - wait->m_weak_version= pfs_file->get_version(); + wait->m_object_instance_addr= NULL; + wait->m_weak_file= NULL; + wait->m_weak_version= 0; wait->m_event_id= pfs_thread->m_event_id++; wait->m_end_event_id= 0; wait->m_operation= file_operation_map[static_cast<int> (op)]; @@ -2767,7 +2812,9 @@ get_thread_file_name_locker_v1(PSI_file_locker_state *state, } state->m_flags= flags; - state->m_file= reinterpret_cast<PSI_file*> (pfs_file); + state->m_file= NULL; + state->m_name= name; + state->m_class= klass; state->m_operation= op; return reinterpret_cast<PSI_file_locker*> (state); } @@ -2788,6 +2835,7 @@ get_thread_file_stream_locker_v1(PSI_file_locker_state *state, if (unlikely(pfs_file == NULL)) return NULL; DBUG_ASSERT(pfs_file->m_class != NULL); + PFS_file_class *klass= pfs_file->m_class; if (! pfs_file->m_enabled) return NULL; @@ -2825,7 +2873,7 @@ get_thread_file_stream_locker_v1(PSI_file_locker_state *state, wait->m_nesting_event_type= parent_event->m_event_type; wait->m_thread= pfs_thread; - wait->m_class= pfs_file->m_class; + wait->m_class= klass; wait->m_timer_start= 0; wait->m_timer_end= 0; wait->m_object_instance_addr= pfs_file; @@ -2856,6 +2904,8 @@ get_thread_file_stream_locker_v1(PSI_file_locker_state *state, state->m_flags= flags; state->m_file= reinterpret_cast<PSI_file*> (pfs_file); state->m_operation= op; + state->m_name= NULL; + state->m_class= klass; return reinterpret_cast<PSI_file_locker*> (state); } @@ -2890,10 +2940,12 @@ get_thread_file_descriptor_locker_v1(PSI_file_locker_state *state, if (op == PSI_FILE_CLOSE) file_handle_array[index]= NULL; - DBUG_ASSERT(pfs_file->m_class != NULL); if (! pfs_file->m_enabled) return NULL; + DBUG_ASSERT(pfs_file->m_class != NULL); + PFS_file_class *klass= pfs_file->m_class; + register uint flags; if (flag_thread_instrumentation) @@ -2927,7 +2979,7 @@ get_thread_file_descriptor_locker_v1(PSI_file_locker_state *state, wait->m_nesting_event_type= parent_event->m_event_type; wait->m_thread= pfs_thread; - wait->m_class= pfs_file->m_class; + wait->m_class= klass; wait->m_timer_start= 0; wait->m_timer_end= 0; wait->m_object_instance_addr= pfs_file; @@ -2958,6 +3010,8 @@ get_thread_file_descriptor_locker_v1(PSI_file_locker_state *state, state->m_flags= flags; state->m_file= reinterpret_cast<PSI_file*> (pfs_file); state->m_operation= op; + state->m_name= NULL; + state->m_class= klass; return reinterpret_cast<PSI_file_locker*> (state); } @@ -2991,14 +3045,6 @@ start_socket_wait_v1(PSI_socket_locker_state *state, if (unlikely(pfs_thread == NULL)) return NULL; -#ifdef LATER - /* - Needs refinement, because of KILL. - */ - DBUG_ASSERT(pfs_thread == - my_pthread_getspecific_ptr(PFS_thread*, THR_PFS)); -#endif - if (!pfs_thread->m_enabled) return NULL; @@ -3112,22 +3158,15 @@ static void unlock_mutex_v1(PSI_mutex *mutex) PFS_mutex::m_lock_stat is not exposed in user visible tables currently, so there is no point spending time computing it. */ - PFS_thread *pfs_thread= reinterpret_cast<PFS_thread*> (thread); - DBUG_ASSERT(pfs_thread != NULL); - - if (unlikely(! flag_events_waits_current)) - return; - if (! pfs_mutex->m_class->m_enabled) + if (! pfs_mutex->m_enabled) return; - if (! pfs_thread->m_enabled) + + if (! pfs_mutex->m_timed) return; - if (pfs_mutex->m_class->m_timed) - { - ulonglong locked_time; - locked_time= get_timer_pico_value(wait_timer) - pfs_mutex->m_last_locked; - aggregate_single_stat_chain(&pfs_mutex->m_lock_stat, locked_time); - } + ulonglong locked_time; + locked_time= get_timer_pico_value(wait_timer) - pfs_mutex->m_last_locked; + pfs_mutex->m_mutex_stat.m_lock_stat.aggregate_value(locked_time); #endif } @@ -3185,32 +3224,23 @@ static void unlock_rwlock_v1(PSI_rwlock *rwlock) #ifdef LATER_WL2333 /* See WL#2333: SHOW ENGINE ... LOCK STATUS. */ - PFS_thread *pfs_thread= reinterpret_cast<PFS_thread*> (thread); - DBUG_ASSERT(pfs_thread != NULL); - if (unlikely(! flag_events_waits_current)) - return; - if (! pfs_rwlock->m_class->m_enabled) + if (! pfs_rwlock->m_enabled) return; - if (! pfs_thread->m_enabled) + + if (! pfs_rwlock->m_timed) return; ulonglong locked_time; if (last_writer) { - if (pfs_rwlock->m_class->m_timed) - { - locked_time= get_timer_pico_value(wait_timer) - pfs_rwlock->m_last_written; - aggregate_single_stat_chain(&pfs_rwlock->m_write_lock_stat, locked_time); - } + locked_time= get_timer_pico_value(wait_timer) - pfs_rwlock->m_last_written; + pfs_rwlock->m_rwlock_stat.m_write_lock_stat.aggregate_value(locked_time); } else if (last_reader) { - if (pfs_rwlock->m_class->m_timed) - { - locked_time= get_timer_pico_value(wait_timer) - pfs_rwlock->m_last_read; - aggregate_single_stat_chain(&pfs_rwlock->m_read_lock_stat, locked_time); - } + locked_time= get_timer_pico_value(wait_timer) - pfs_rwlock->m_last_read; + pfs_rwlock->m_rwlock_stat.m_read_lock_stat.aggregate_value(locked_time); } #else (void) last_reader; @@ -3352,17 +3382,16 @@ static void end_idle_wait_v1(PSI_idle_locker* locker) PFS_thread *thread= reinterpret_cast<PFS_thread *> (state->m_thread); PFS_single_stat *event_name_array; event_name_array= thread->m_instr_class_waits_stats; - uint index= global_idle_class.m_event_name_index; if (flags & STATE_FLAG_TIMED) { /* Aggregate to EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME (timed) */ - event_name_array[index].aggregate_value(wait_time); + event_name_array[GLOBAL_IDLE_EVENT_INDEX].aggregate_value(wait_time); } else { /* Aggregate to EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME (counted) */ - event_name_array[index].aggregate_counted(); + event_name_array[GLOBAL_IDLE_EVENT_INDEX].aggregate_counted(); } if (flags & STATE_FLAG_EVENT) @@ -3379,6 +3408,17 @@ static void end_idle_wait_v1(PSI_idle_locker* locker) thread->m_events_waits_current--; } } + + if (flags & STATE_FLAG_TIMED) + { + /* Aggregate to EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME (timed) */ + global_idle_stat.aggregate_value(wait_time); + } + else + { + /* Aggregate to EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME (counted) */ + global_idle_stat.aggregate_counted(); + } } /** @@ -3404,12 +3444,12 @@ static void end_mutex_wait_v1(PSI_mutex_locker* locker, int rc) timer_end= state->m_timer(); wait_time= timer_end - state->m_timer_start; /* Aggregate to EVENTS_WAITS_SUMMARY_BY_INSTANCE (timed) */ - mutex->m_wait_stat.aggregate_value(wait_time); + mutex->m_mutex_stat.m_wait_stat.aggregate_value(wait_time); } else { /* Aggregate to EVENTS_WAITS_SUMMARY_BY_INSTANCE (counted) */ - mutex->m_wait_stat.aggregate_counted(); + mutex->m_mutex_stat.m_wait_stat.aggregate_counted(); } if (likely(rc == 0)) @@ -3471,12 +3511,12 @@ static void end_rwlock_rdwait_v1(PSI_rwlock_locker* locker, int rc) timer_end= state->m_timer(); wait_time= timer_end - state->m_timer_start; /* Aggregate to EVENTS_WAITS_SUMMARY_BY_INSTANCE (timed) */ - rwlock->m_wait_stat.aggregate_value(wait_time); + rwlock->m_rwlock_stat.m_wait_stat.aggregate_value(wait_time); } else { /* Aggregate to EVENTS_WAITS_SUMMARY_BY_INSTANCE (counted) */ - rwlock->m_wait_stat.aggregate_counted(); + rwlock->m_rwlock_stat.m_wait_stat.aggregate_counted(); } if (rc == 0) @@ -3551,12 +3591,12 @@ static void end_rwlock_wrwait_v1(PSI_rwlock_locker* locker, int rc) timer_end= state->m_timer(); wait_time= timer_end - state->m_timer_start; /* Aggregate to EVENTS_WAITS_SUMMARY_BY_INSTANCE (timed) */ - rwlock->m_wait_stat.aggregate_value(wait_time); + rwlock->m_rwlock_stat.m_wait_stat.aggregate_value(wait_time); } else { /* Aggregate to EVENTS_WAITS_SUMMARY_BY_INSTANCE (counted) */ - rwlock->m_wait_stat.aggregate_counted(); + rwlock->m_rwlock_stat.m_wait_stat.aggregate_counted(); } if (likely(rc == 0)) @@ -3622,12 +3662,12 @@ static void end_cond_wait_v1(PSI_cond_locker* locker, int rc) timer_end= state->m_timer(); wait_time= timer_end - state->m_timer_start; /* Aggregate to EVENTS_WAITS_SUMMARY_BY_INSTANCE (timed) */ - cond->m_wait_stat.aggregate_value(wait_time); + cond->m_cond_stat.m_wait_stat.aggregate_value(wait_time); } else { /* Aggregate to EVENTS_WAITS_SUMMARY_BY_INSTANCE (counted) */ - cond->m_wait_stat.aggregate_counted(); + cond->m_cond_stat.m_wait_stat.aggregate_counted(); } if (state->m_flags & STATE_FLAG_THREAD) @@ -3682,23 +3722,27 @@ static void end_table_io_wait_v1(PSI_table_locker* locker) DBUG_ASSERT(table != NULL); PFS_single_stat *stat; + PFS_table_io_stat *table_io_stat; DBUG_ASSERT((state->m_index < table->m_share->m_key_count) || - (state->m_index == MAX_KEY)); + (state->m_index == MAX_INDEXES)); + + table_io_stat= & table->m_table_stat.m_index_stat[state->m_index]; + table_io_stat->m_has_data= true; switch (state->m_io_operation) { case PSI_TABLE_FETCH_ROW: - stat= & table->m_table_stat.m_index_stat[state->m_index].m_fetch; + stat= & table_io_stat->m_fetch; break; case PSI_TABLE_WRITE_ROW: - stat= & table->m_table_stat.m_index_stat[state->m_index].m_insert; + stat= & table_io_stat->m_insert; break; case PSI_TABLE_UPDATE_ROW: - stat= & table->m_table_stat.m_index_stat[state->m_index].m_update; + stat= & table_io_stat->m_update; break; case PSI_TABLE_DELETE_ROW: - stat= & table->m_table_stat.m_index_stat[state->m_index].m_delete; + stat= & table_io_stat->m_delete; break; default: DBUG_ASSERT(false); @@ -3719,22 +3763,40 @@ static void end_table_io_wait_v1(PSI_table_locker* locker) stat->aggregate_counted(); } - if (flags & STATE_FLAG_EVENT) + if (flags & STATE_FLAG_THREAD) { - DBUG_ASSERT(flags & STATE_FLAG_THREAD); PFS_thread *thread= reinterpret_cast<PFS_thread *> (state->m_thread); DBUG_ASSERT(thread != NULL); - PFS_events_waits *wait= reinterpret_cast<PFS_events_waits*> (state->m_wait); - DBUG_ASSERT(wait != NULL); + PFS_single_stat *event_name_array; + event_name_array= thread->m_instr_class_waits_stats; - wait->m_timer_end= timer_end; - wait->m_end_event_id= thread->m_event_id; - if (flag_events_waits_history) - insert_events_waits_history(thread, wait); - if (flag_events_waits_history_long) - insert_events_waits_history_long(wait); - thread->m_events_waits_current--; + /* + Aggregate to EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME + (for wait/io/table/sql/handler) + */ + if (flags & STATE_FLAG_TIMED) + { + event_name_array[GLOBAL_TABLE_IO_EVENT_INDEX].aggregate_value(wait_time); + } + else + { + event_name_array[GLOBAL_TABLE_IO_EVENT_INDEX].aggregate_counted(); + } + + if (flags & STATE_FLAG_EVENT) + { + PFS_events_waits *wait= reinterpret_cast<PFS_events_waits*> (state->m_wait); + DBUG_ASSERT(wait != NULL); + + wait->m_timer_end= timer_end; + wait->m_end_event_id= thread->m_event_id; + if (flag_events_waits_history) + insert_events_waits_history(thread, wait); + if (flag_events_waits_history_long) + insert_events_waits_history_long(wait); + thread->m_events_waits_current--; + } } table->m_has_io_stats= true; @@ -3770,22 +3832,40 @@ static void end_table_lock_wait_v1(PSI_table_locker* locker) stat->aggregate_counted(); } - if (flags & STATE_FLAG_EVENT) + if (flags & STATE_FLAG_THREAD) { - DBUG_ASSERT(flags & STATE_FLAG_THREAD); PFS_thread *thread= reinterpret_cast<PFS_thread *> (state->m_thread); DBUG_ASSERT(thread != NULL); - PFS_events_waits *wait= reinterpret_cast<PFS_events_waits*> (state->m_wait); - DBUG_ASSERT(wait != NULL); + PFS_single_stat *event_name_array; + event_name_array= thread->m_instr_class_waits_stats; - wait->m_timer_end= timer_end; - wait->m_end_event_id= thread->m_event_id; - if (flag_events_waits_history) - insert_events_waits_history(thread, wait); - if (flag_events_waits_history_long) - insert_events_waits_history_long(wait); - thread->m_events_waits_current--; + /* + Aggregate to EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME + (for wait/lock/table/sql/handler) + */ + if (flags & STATE_FLAG_TIMED) + { + event_name_array[GLOBAL_TABLE_LOCK_EVENT_INDEX].aggregate_value(wait_time); + } + else + { + event_name_array[GLOBAL_TABLE_LOCK_EVENT_INDEX].aggregate_counted(); + } + + if (flags & STATE_FLAG_EVENT) + { + PFS_events_waits *wait= reinterpret_cast<PFS_events_waits*> (state->m_wait); + DBUG_ASSERT(wait != NULL); + + wait->m_timer_end= timer_end; + wait->m_end_event_id= thread->m_event_id; + if (flag_events_waits_history) + insert_events_waits_history(thread, wait); + if (flag_events_waits_history_long) + insert_events_waits_history_long(wait); + thread->m_events_waits_current--; + } } table->m_has_lock_stats= true; @@ -3803,25 +3883,50 @@ static void end_file_wait_v1(PSI_file_locker *locker, Implementation of the file instrumentation interface. @sa PSI_v1::start_file_open_wait. */ -static PSI_file* start_file_open_wait_v1(PSI_file_locker *locker, - const char *src_file, - uint src_line) +static void start_file_open_wait_v1(PSI_file_locker *locker, + const char *src_file, + uint src_line) { - PSI_file_locker_state *state= reinterpret_cast<PSI_file_locker_state*> (locker); - DBUG_ASSERT(state != NULL); - start_file_wait_v1(locker, 0, src_file, src_line); - return state->m_file; + return; } /** Implementation of the file instrumentation interface. @sa PSI_v1::end_file_open_wait. */ -static void end_file_open_wait_v1(PSI_file_locker *locker) +static PSI_file* end_file_open_wait_v1(PSI_file_locker *locker, + void *result) { + PSI_file_locker_state *state= reinterpret_cast<PSI_file_locker_state*> (locker); + DBUG_ASSERT(state != NULL); + + switch (state->m_operation) + { + case PSI_FILE_STAT: + break; + case PSI_FILE_STREAM_OPEN: + case PSI_FILE_CREATE: + if (result != NULL) + { + PFS_file_class *klass= reinterpret_cast<PFS_file_class*> (state->m_class); + PFS_thread *thread= reinterpret_cast<PFS_thread*> (state->m_thread); + const char *name= state->m_name; + uint len= strlen(name); + PFS_file *pfs_file= find_or_create_file(thread, klass, name, len, true); + state->m_file= reinterpret_cast<PSI_file*> (pfs_file); + } + break; + case PSI_FILE_OPEN: + default: + DBUG_ASSERT(false); + break; + } + end_file_wait_v1(locker, 0); + + return state->m_file; } /** @@ -3831,25 +3936,33 @@ static void end_file_open_wait_v1(PSI_file_locker *locker) static void end_file_open_wait_and_bind_to_descriptor_v1 (PSI_file_locker *locker, File file) { + PFS_file *pfs_file= NULL; int index= (int) file; PSI_file_locker_state *state= reinterpret_cast<PSI_file_locker_state*> (locker); DBUG_ASSERT(state != NULL); - end_file_wait_v1(locker, 0); + if (index >= 0) + { + PFS_file_class *klass= reinterpret_cast<PFS_file_class*> (state->m_class); + PFS_thread *thread= reinterpret_cast<PFS_thread*> (state->m_thread); + const char *name= state->m_name; + uint len= strlen(name); + pfs_file= find_or_create_file(thread, klass, name, len, true); + state->m_file= reinterpret_cast<PSI_file*> (pfs_file); + } - PFS_file *pfs_file= reinterpret_cast<PFS_file*> (state->m_file); - DBUG_ASSERT(pfs_file != NULL); + end_file_wait_v1(locker, 0); if (likely(index >= 0)) { if (likely(index < file_handle_max)) file_handle_array[index]= pfs_file; else + { + if (pfs_file != NULL) + release_file(pfs_file); file_handle_lost++; - } - else - { - release_file(pfs_file); + } } } @@ -3896,7 +4009,7 @@ static void end_file_wait_v1(PSI_file_locker *locker, PSI_file_locker_state *state= reinterpret_cast<PSI_file_locker_state*> (locker); DBUG_ASSERT(state != NULL); PFS_file *file= reinterpret_cast<PFS_file *> (state->m_file); - DBUG_ASSERT(file != NULL); + PFS_file_class *klass= reinterpret_cast<PFS_file_class *> (state->m_class); PFS_thread *thread= reinterpret_cast<PFS_thread *> (state->m_thread); ulonglong timer_end= 0; @@ -3905,15 +4018,26 @@ static void end_file_wait_v1(PSI_file_locker *locker, register uint flags= state->m_flags; size_t bytes= ((int)byte_count > -1 ? byte_count : 0); + PFS_file_stat *file_stat; + + if (file != NULL) + { + file_stat= & file->m_file_stat; + } + else + { + file_stat= & klass->m_file_stat; + } + switch (state->m_operation) { /* Group read operations */ case PSI_FILE_READ: - byte_stat= &file->m_file_stat.m_io_stat.m_read; + byte_stat= &file_stat->m_io_stat.m_read; break; /* Group write operations */ case PSI_FILE_WRITE: - byte_stat= &file->m_file_stat.m_io_stat.m_write; + byte_stat= &file_stat->m_io_stat.m_write; break; /* Group remaining operations as miscellaneous */ case PSI_FILE_CREATE: @@ -3931,7 +4055,7 @@ static void end_file_wait_v1(PSI_file_locker *locker, case PSI_FILE_SYNC: case PSI_FILE_STAT: case PSI_FILE_CLOSE: - byte_stat= &file->m_file_stat.m_io_stat.m_misc; + byte_stat= &file_stat->m_io_stat.m_misc; break; default: DBUG_ASSERT(false); @@ -3959,7 +4083,7 @@ static void end_file_wait_v1(PSI_file_locker *locker, PFS_single_stat *event_name_array; event_name_array= thread->m_instr_class_waits_stats; - uint index= file->m_class->m_event_name_index; + uint index= klass->m_event_name_index; if (flags & STATE_FLAG_TIMED) { @@ -3980,6 +4104,9 @@ static void end_file_wait_v1(PSI_file_locker *locker, wait->m_timer_end= timer_end; wait->m_number_of_bytes= bytes; wait->m_end_event_id= thread->m_event_id; + wait->m_object_instance_addr= file; + wait->m_weak_file= file; + wait->m_weak_version= (file ? file->get_version() : 0); if (flag_events_waits_history) insert_events_waits_history(thread, wait); @@ -3988,22 +4115,79 @@ static void end_file_wait_v1(PSI_file_locker *locker, thread->m_events_waits_current--; } } +} - /* Release or destroy the file if necessary */ - switch(state->m_operation) +/** + Implementation of the file instrumentation interface. + @sa PSI_v1::start_file_close_wait. +*/ +static void start_file_close_wait_v1(PSI_file_locker *locker, + const char *src_file, + uint src_line) +{ + PFS_thread *thread; + const char *name; + uint len; + PFS_file *pfs_file; + PSI_file_locker_state *state= reinterpret_cast<PSI_file_locker_state*> (locker); + DBUG_ASSERT(state != NULL); + + switch (state->m_operation) { - case PSI_FILE_CLOSE: - case PSI_FILE_STREAM_CLOSE: - case PSI_FILE_STAT: - release_file(file); - break; case PSI_FILE_DELETE: - DBUG_ASSERT(thread != NULL); - destroy_file(thread, file); + thread= reinterpret_cast<PFS_thread*> (state->m_thread); + name= state->m_name; + len= strlen(name); + pfs_file= find_or_create_file(thread, NULL, name, len, false); + state->m_file= reinterpret_cast<PSI_file*> (pfs_file); + break; + case PSI_FILE_STREAM_CLOSE: + case PSI_FILE_CLOSE: break; default: + DBUG_ASSERT(false); break; } + + start_file_wait_v1(locker, 0, src_file, src_line); + + return; +} + +/** + Implementation of the file instrumentation interface. + @sa PSI_v1::end_file_close_wait. +*/ +static void end_file_close_wait_v1(PSI_file_locker *locker, int rc) +{ + PSI_file_locker_state *state= reinterpret_cast<PSI_file_locker_state*> (locker); + DBUG_ASSERT(state != NULL); + + end_file_wait_v1(locker, 0); + + if (rc == 0) + { + PFS_thread *thread= reinterpret_cast<PFS_thread*> (state->m_thread); + PFS_file *file= reinterpret_cast<PFS_file*> (state->m_file); + + /* Release or destroy the file if necessary */ + switch(state->m_operation) + { + case PSI_FILE_CLOSE: + case PSI_FILE_STREAM_CLOSE: + if (file != NULL) + release_file(file); + break; + case PSI_FILE_DELETE: + if (file != NULL) + destroy_file(thread, file); + break; + default: + DBUG_ASSERT(false); + break; + } + } + return; } static void start_stage_v1(PSI_stage_key key, const char *src_file, int src_line) @@ -4165,7 +4349,8 @@ static void end_stage_v1() static PSI_statement_locker* get_thread_statement_locker_v1(PSI_statement_locker_state *state, - PSI_statement_key key) + PSI_statement_key key, + const void *charset) { DBUG_ASSERT(state != NULL); if (! flag_global_instrumentation) @@ -4262,9 +4447,11 @@ get_thread_statement_locker_v1(PSI_statement_locker_state *state, if (flag_statements_digest) { + const CHARSET_INFO *cs= static_cast <const CHARSET_INFO*> (charset); flags|= STATE_FLAG_DIGEST; state->m_digest_state.m_last_id_index= 0; digest_reset(& state->m_digest_state.m_digest_storage); + state->m_digest_state.m_digest_storage.m_charset_number= cs->number; } state->m_discarded= false; @@ -4288,6 +4475,8 @@ get_thread_statement_locker_v1(PSI_statement_locker_state *state, state->m_no_index_used= 0; state->m_no_good_index_used= 0; + state->m_schema_name_length= 0; + return reinterpret_cast<PSI_statement_locker*> (state); } @@ -4352,6 +4541,13 @@ static void start_statement_v1(PSI_statement_locker *locker, state->m_timer_start= timer_start; } + compile_time_assert(PSI_SCHEMA_NAME_LEN == NAME_LEN); + DBUG_ASSERT(db_len <= sizeof(state->m_schema_name)); + + if (db_len > 0) + memcpy(state->m_schema_name, db, db_len); + state->m_schema_name_length= db_len; + if (flags & STATE_FLAG_EVENT) { PFS_events_statements *pfs= reinterpret_cast<PFS_events_statements*> (state->m_statement); @@ -4563,11 +4759,10 @@ static void end_statement_v1(PSI_statement_locker *locker, void *stmt_da) if (flags & STATE_FLAG_DIGEST) { digest_storage= &state->m_digest_state.m_digest_storage; - - /* - Populate PFS_statements_digest_stat with computed digest information. - */ - digest_stat= find_or_create_digest(thread, digest_storage); + /* Populate PFS_statements_digest_stat with computed digest information.*/ + digest_stat= find_or_create_digest(thread, digest_storage, + state->m_schema_name, + state->m_schema_name_length); } if (flags & STATE_FLAG_EVENT) @@ -4633,11 +4828,10 @@ static void end_statement_v1(PSI_statement_locker *locker, void *stmt_da) { /* Set digest stat. */ digest_storage= &state->m_digest_state.m_digest_storage; - - /* - Populate PFS_statements_digest_stat with computed digest information. - */ - digest_stat= find_or_create_digest(thread, digest_storage); + /* Populate statements_digest_stat with computed digest information. */ + digest_stat= find_or_create_digest(thread, digest_storage, + state->m_schema_name, + state->m_schema_name_length); } } @@ -4869,6 +5063,42 @@ static void set_socket_thread_owner_v1(PSI_socket *socket) pfs_socket->m_thread_owner= my_pthread_getspecific_ptr(PFS_thread*, THR_PFS); } + +/** + Implementation of the thread attribute connection interface + @sa PSI_v1::set_thread_connect_attr. +*/ +static int set_thread_connect_attrs_v1(const char *buffer, uint length, + const void *from_cs) +{ + + PFS_thread *thd= my_pthread_getspecific_ptr(PFS_thread*, THR_PFS); + + DBUG_ASSERT(buffer != NULL); + + if (likely(thd != NULL) && session_connect_attrs_size_per_thread > 0) + { + /* 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(); + 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(); + + if (copy_size == length) + return 0; + else + { + session_connect_attrs_lost++; + return 1; + } + } + return 0; +} + + /** Implementation of the instrumentation interface. @sa PSI_v1. @@ -4939,6 +5169,8 @@ PSI_v1 PFS_v1= end_file_open_wait_and_bind_to_descriptor_v1, start_file_wait_v1, end_file_wait_v1, + start_file_close_wait_v1, + end_file_close_wait_v1, start_stage_v1, end_stage_v1, get_thread_statement_locker_v1, @@ -4968,7 +5200,8 @@ PSI_v1 PFS_v1= set_socket_info_v1, set_socket_thread_owner_v1, pfs_digest_start_v1, - pfs_digest_add_token_v1 + pfs_digest_add_token_v1, + set_thread_connect_attrs_v1, }; static void* get_interface(int version) |