summaryrefslogtreecommitdiff
path: root/storage/perfschema/pfs.cc
diff options
context:
space:
mode:
authorSergei Golubchik <sergii@pisem.net>2014-05-07 10:04:30 +0200
committerSergei Golubchik <sergii@pisem.net>2014-05-07 10:04:30 +0200
commit04bce7b569f44f3aca3cb21953d41c2a4a02efe6 (patch)
tree2530ccd90b42afa39b0a60f4454fd5ddb97c95e1 /storage/perfschema/pfs.cc
parent7226287c066228a216217c43c48f3a0a833d9909 (diff)
downloadmariadb-git-04bce7b569f44f3aca3cb21953d41c2a4a02efe6.tar.gz
5.6.17
Diffstat (limited to 'storage/perfschema/pfs.cc')
-rw-r--r--storage/perfschema/pfs.cc179
1 files changed, 111 insertions, 68 deletions
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;
}