summaryrefslogtreecommitdiff
path: root/storage
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
parent7226287c066228a216217c43c48f3a0a833d9909 (diff)
downloadmariadb-git-04bce7b569f44f3aca3cb21953d41c2a4a02efe6.tar.gz
5.6.17
Diffstat (limited to 'storage')
-rw-r--r--storage/perfschema/cursor_by_account.cc2
-rw-r--r--storage/perfschema/cursor_by_account.h2
-rw-r--r--storage/perfschema/cursor_by_host.cc2
-rw-r--r--storage/perfschema/cursor_by_host.h2
-rw-r--r--storage/perfschema/cursor_by_thread.cc2
-rw-r--r--storage/perfschema/cursor_by_thread.h2
-rw-r--r--storage/perfschema/cursor_by_user.cc2
-rw-r--r--storage/perfschema/cursor_by_user.h2
-rw-r--r--storage/perfschema/ha_perfschema.cc18
-rw-r--r--storage/perfschema/ha_perfschema.h37
-rw-r--r--storage/perfschema/pfs.cc179
-rw-r--r--storage/perfschema/pfs_account.cc91
-rw-r--r--storage/perfschema/pfs_account.h14
-rw-r--r--storage/perfschema/pfs_check.cc5
-rw-r--r--storage/perfschema/pfs_defaults.cc2
-rw-r--r--storage/perfschema/pfs_digest.cc111
-rw-r--r--storage/perfschema/pfs_digest.h8
-rw-r--r--storage/perfschema/pfs_engine_table.cc8
-rw-r--r--storage/perfschema/pfs_events_stages.cc20
-rw-r--r--storage/perfschema/pfs_events_statements.cc20
-rw-r--r--storage/perfschema/pfs_events_waits.cc20
-rw-r--r--storage/perfschema/pfs_global.cc4
-rw-r--r--storage/perfschema/pfs_global.h4
-rw-r--r--storage/perfschema/pfs_host.cc12
-rw-r--r--storage/perfschema/pfs_host.h5
-rw-r--r--storage/perfschema/pfs_instr.cc237
-rw-r--r--storage/perfschema/pfs_instr.h109
-rw-r--r--storage/perfschema/pfs_instr_class.cc8
-rw-r--r--storage/perfschema/pfs_instr_class.h17
-rw-r--r--storage/perfschema/pfs_server.h4
-rw-r--r--storage/perfschema/pfs_setup_object.cc4
-rw-r--r--storage/perfschema/pfs_stat.h7
-rw-r--r--storage/perfschema/pfs_user.cc4
-rw-r--r--storage/perfschema/pfs_user.h4
-rw-r--r--storage/perfschema/table_esgs_by_account_by_event_name.cc4
-rw-r--r--storage/perfschema/table_esgs_by_account_by_event_name.h4
-rw-r--r--storage/perfschema/table_esgs_by_host_by_event_name.cc4
-rw-r--r--storage/perfschema/table_esgs_by_host_by_event_name.h4
-rw-r--r--storage/perfschema/table_esgs_by_user_by_event_name.cc4
-rw-r--r--storage/perfschema/table_esgs_by_user_by_event_name.h4
-rw-r--r--storage/perfschema/table_esms_by_account_by_event_name.cc7
-rw-r--r--storage/perfschema/table_esms_by_account_by_event_name.h4
-rw-r--r--storage/perfschema/table_esms_by_digest.cc4
-rw-r--r--storage/perfschema/table_esms_by_digest.h4
-rw-r--r--storage/perfschema/table_esms_by_host_by_event_name.cc7
-rw-r--r--storage/perfschema/table_esms_by_host_by_event_name.h4
-rw-r--r--storage/perfschema/table_esms_by_thread_by_event_name.cc5
-rw-r--r--storage/perfschema/table_esms_by_user_by_event_name.cc7
-rw-r--r--storage/perfschema/table_esms_by_user_by_event_name.h4
-rw-r--r--storage/perfschema/table_esms_global_by_event_name.cc7
-rw-r--r--storage/perfschema/table_events_statements.cc93
-rw-r--r--storage/perfschema/table_events_statements.h13
-rw-r--r--storage/perfschema/table_ews_by_account_by_event_name.cc4
-rw-r--r--storage/perfschema/table_ews_by_account_by_event_name.h4
-rw-r--r--storage/perfschema/table_ews_by_host_by_event_name.cc4
-rw-r--r--storage/perfschema/table_ews_by_host_by_event_name.h4
-rw-r--r--storage/perfschema/table_ews_by_user_by_event_name.cc4
-rw-r--r--storage/perfschema/table_ews_by_user_by_event_name.h4
-rw-r--r--storage/perfschema/table_helper.cc23
-rw-r--r--storage/perfschema/table_helper.h8
-rw-r--r--storage/perfschema/table_host_cache.cc2
-rw-r--r--storage/perfschema/table_host_cache.h2
-rw-r--r--storage/perfschema/table_os_global_by_type.cc4
-rw-r--r--storage/perfschema/table_os_global_by_type.h2
-rw-r--r--storage/perfschema/table_session_connect.cc70
-rw-r--r--storage/perfschema/table_session_connect.h9
-rw-r--r--storage/perfschema/table_setup_actors.cc2
-rw-r--r--storage/perfschema/table_threads.cc85
-rw-r--r--storage/perfschema/table_tiws_by_table.cc4
-rw-r--r--storage/perfschema/table_tiws_by_table.h4
-rw-r--r--storage/perfschema/table_tlws_by_table.cc4
-rw-r--r--storage/perfschema/table_tlws_by_table.h4
-rw-r--r--storage/perfschema/unittest/CMakeLists.txt6
-rw-r--r--storage/perfschema/unittest/pfs_account-oom-t.cc2
-rw-r--r--storage/perfschema/unittest/pfs_host-oom-t.cc2
-rw-r--r--storage/perfschema/unittest/stub_pfs_defaults.h2
-rw-r--r--storage/perfschema/unittest/stub_server_misc.h4
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.