diff options
author | Sergei Golubchik <sergii@pisem.net> | 2011-07-02 22:08:51 +0200 |
---|---|---|
committer | Sergei Golubchik <sergii@pisem.net> | 2011-07-02 22:08:51 +0200 |
commit | 9809f05199aeb0b67991fac41bd86f38730768dc (patch) | |
tree | fa2792ff86d0da014b535d743759810612338042 /storage/perfschema | |
parent | 0accbd0364e0333e0b119aa9ce93e34ded9df6cb (diff) | |
parent | 5a0e7394a5ae0c7b6a1ea35b7ea3a8985325987a (diff) | |
download | mariadb-git-9809f05199aeb0b67991fac41bd86f38730768dc.tar.gz |
5.5-merge
Diffstat (limited to 'storage/perfschema')
31 files changed, 300 insertions, 275 deletions
diff --git a/storage/perfschema/Makefile.am b/storage/perfschema/Makefile.am deleted file mode 100644 index 762f5b85790..00000000000 --- a/storage/perfschema/Makefile.am +++ /dev/null @@ -1,76 +0,0 @@ -# Copyright (c) 2008, 2010, 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 -# the Free Software Foundation; version 2 of the License. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA - -#called from the top level Makefile - -SUBDIRS = . unittest - -MYSQLDATAdir = $(localstatedir) -MYSQLSHAREdir = $(pkgdatadir) -MYSQLBASEdir= $(prefix) -MYSQLLIBdir= $(pkglibdir) -pkgplugindir = $(pkglibdir)/plugin -INCLUDES = -I$(top_srcdir)/include -I$(top_builddir)/include \ - -I$(top_srcdir)/regex \ - -I$(top_srcdir)/sql \ - -I$(srcdir) -WRAPLIBS= - -LDADD = - -DEFS = -DMYSQL_SERVER @DEFS@ - - -noinst_HEADERS = ha_perfschema.h pfs_engine_table.h pfs.h pfs_server.h \ - pfs_global.h pfs_instr_class.h pfs_instr.h \ - pfs_column_types.h pfs_column_values.h \ - table_setup_instruments.h table_performance_timers.h \ - table_setup_timers.h \ - table_setup_consumers.h table_events_waits.h \ - pfs_events_waits.h pfs_timer.h table_threads.h \ - table_sync_instances.h \ - table_events_waits_summary.h pfs_stat.h \ - table_ews_global_by_event_name.h table_all_instr.h \ - table_file_instances.h table_file_summary.h \ - pfs_lock.h pfs_atomic.h - -PSE_SOURCES = ha_perfschema.cc pfs_engine_table.cc pfs.cc pfs_server.cc \ - pfs_global.cc pfs_instr_class.cc pfs_instr.cc \ - pfs_column_values.cc \ - table_setup_instruments.cc table_performance_timers.cc \ - table_setup_timers.cc \ - table_setup_consumers.cc table_events_waits.cc \ - pfs_events_waits.cc pfs_timer.cc table_threads.cc \ - table_sync_instances.cc \ - table_events_waits_summary.cc \ - table_ews_global_by_event_name.cc table_all_instr.cc \ - table_file_instances.cc table_file_summary.cc \ - pfs_atomic.cc pfs_check.cc - -EXTRA_LIBRARIES = libperfschema.a -noinst_LIBRARIES = @plugin_perfschema_static_target@ - -libperfschema_a_SOURCES= $(PSE_SOURCES) - -EXTRA_DIST = plug.in CMakeLists.txt - -unittests = unittest - -test: - perl $(top_srcdir)/unittest/unit.pl run $(unittests) - -test-verbose: - HARNESS_VERBOSE=1 perl $(top_srcdir)/unittest/unit.pl run $(unittests) - diff --git a/storage/perfschema/ha_perfschema.cc b/storage/perfschema/ha_perfschema.cc index b6438808869..ec063b782c1 100644 --- a/storage/perfschema/ha_perfschema.cc +++ b/storage/perfschema/ha_perfschema.cc @@ -246,7 +246,6 @@ int ha_perfschema::write_row(uchar *buf) result= m_table_share->m_write_row(table, buf, table->field); else { - my_error(ER_WRONG_PERFSCHEMA_USAGE, MYF(0)); result= HA_ERR_WRONG_COMMAND; } @@ -357,12 +356,16 @@ int ha_perfschema::delete_all_rows(void) result= m_table_share->m_delete_all_rows(); else { - my_error(ER_WRONG_PERFSCHEMA_USAGE, MYF(0)); result= HA_ERR_WRONG_COMMAND; } DBUG_RETURN(result); } +int ha_perfschema::truncate() +{ + return delete_all_rows(); +} + THR_LOCK_DATA **ha_perfschema::store_lock(THD *thd, THR_LOCK_DATA **to, enum thr_lock_type lock_type) @@ -383,7 +386,6 @@ int ha_perfschema::delete_table(const char *name) int ha_perfschema::rename_table(const char * from, const char * to) { DBUG_ENTER("ha_perfschema::rename_table "); - my_error(ER_WRONG_PERFSCHEMA_USAGE, MYF(0)); DBUG_RETURN(HA_ERR_WRONG_COMMAND); } @@ -408,7 +410,37 @@ int ha_perfschema::create(const char *name, TABLE *table_arg, This is not a general purpose engine. Failure to CREATE TABLE is the expected result. */ - my_error(ER_WRONG_PERFSCHEMA_USAGE, MYF(0)); DBUG_RETURN(HA_ERR_WRONG_COMMAND); } +void ha_perfschema::print_error(int error, myf errflag) +{ + switch (error) + { + case HA_ERR_TABLE_NEEDS_UPGRADE: + /* + The error message for ER_TABLE_NEEDS_UPGRADE refers to REPAIR table, + which does not apply to performance schema tables. + */ + my_error(ER_WRONG_NATIVE_TABLE_STRUCTURE, MYF(0), + table_share->db.str, table_share->table_name.str); + break; + case HA_ERR_WRONG_COMMAND: + /* + The performance schema is not a general purpose storage engine, + some operations are not supported, by design. + We do not want to print "Command not supported", + which gives the impression that a command implementation is missing, + and that the failure should be considered a bug. + We print "Invalid performance_schema usage." instead, + to emphasise that the operation attempted is not meant to be legal, + and that the failure returned is indeed the expected result. + */ + my_error(ER_WRONG_PERFSCHEMA_USAGE, MYF(0)); + break; + default: + handler::print_error(error, errflag); + break; + } +} + diff --git a/storage/perfschema/ha_perfschema.h b/storage/perfschema/ha_perfschema.h index 2c7b45fbbf7..c0ee0827dbc 100644 --- a/storage/perfschema/ha_perfschema.h +++ b/storage/perfschema/ha_perfschema.h @@ -100,9 +100,6 @@ public: double scan_time(void) { return 1.0; } - double read_time(ha_rows) - { return 1.0; } - int open(const char *name, int mode, uint test_if_locked); int close(void); @@ -127,6 +124,8 @@ public: int delete_all_rows(void); + int truncate(); + int delete_table(const char *from); int rename_table(const char * from, const char * to); @@ -147,6 +146,8 @@ public: return FALSE; } + virtual void print_error(int error, myf errflags); + private: /** MySQL lock */ THR_LOCK_DATA m_thr_lock; diff --git a/storage/perfschema/pfs_engine_table.cc b/storage/perfschema/pfs_engine_table.cc index 3b1959c98d2..38f6df3003d 100644 --- a/storage/perfschema/pfs_engine_table.cc +++ b/storage/perfschema/pfs_engine_table.cc @@ -232,8 +232,6 @@ int PFS_engine_table::read_row(TABLE *table, */ if (! m_share_ptr->m_checked) { - my_error(ER_WRONG_NATIVE_TABLE_STRUCTURE, MYF(0), - PERFORMANCE_SCHEMA_str.str, m_share_ptr->m_name.str); return HA_ERR_TABLE_NEEDS_UPGRADE; } @@ -279,8 +277,6 @@ int PFS_engine_table::update_row(TABLE *table, */ if (! m_share_ptr->m_checked) { - my_error(ER_WRONG_NATIVE_TABLE_STRUCTURE, MYF(0), - PERFORMANCE_SCHEMA_str.str, m_share_ptr->m_name.str); return HA_ERR_TABLE_NEEDS_UPGRADE; } @@ -351,7 +347,6 @@ int PFS_engine_table::update_row_values(TABLE *, unsigned char *, Field **) { - my_error(ER_WRONG_PERFSCHEMA_USAGE, MYF(0)); return HA_ERR_WRONG_COMMAND; } @@ -524,9 +519,9 @@ bool pfs_show_status(handlerton *hton, THD *thd, /* Note about naming conventions: - Internal buffers exposed as a table in the performance schema are named - after the table, as in 'EVENTS_WAITS_CURRENT' + after the table, as in 'events_waits_current' - Internal buffers not exposed by a table are named with parenthesis, - as in '(PFS_MUTEX_CLASS)'. + as in '(pfs_mutex_class)'. */ if (stat != HA_ENGINE_STATUS) DBUG_RETURN(false); @@ -537,219 +532,219 @@ bool pfs_show_status(handlerton *hton, THD *thd, { switch (i){ case 0: - name= "EVENTS_WAITS_CURRENT.ROW_SIZE"; + name= "events_waits_current.row_size"; size= sizeof(PFS_wait_locker); break; case 1: - name= "EVENTS_WAITS_CURRENT.ROW_COUNT"; + name= "events_waits_current.row_count"; size= LOCKER_STACK_SIZE * thread_max; break; case 2: - name= "EVENTS_WAITS_HISTORY.ROW_SIZE"; + name= "events_waits_history.row_size"; size= sizeof(PFS_events_waits); break; case 3: - name= "EVENTS_WAITS_HISTORY.ROW_COUNT"; + name= "events_waits_history.row_count"; size= events_waits_history_per_thread * thread_max; break; case 4: - name= "EVENTS_WAITS_HISTORY.MEMORY"; + name= "events_waits_history.memory"; size= events_waits_history_per_thread * thread_max * sizeof(PFS_events_waits); total_memory+= size; break; case 5: - name= "EVENTS_WAITS_HISTORY_LONG.ROW_SIZE"; + name= "events_waits_history_long.row_size"; size= sizeof(PFS_events_waits); break; case 6: - name= "EVENTS_WAITS_HISTORY_LONG.ROW_COUNT"; + name= "events_waits_history_long.row_count"; size= events_waits_history_long_size; break; case 7: - name= "EVENTS_WAITS_HISTORY_LONG.MEMORY"; + name= "events_waits_history_long.memory"; size= events_waits_history_long_size * sizeof(PFS_events_waits); total_memory+= size; break; case 8: - name= "(PFS_MUTEX_CLASS).ROW_SIZE"; + name= "(pfs_mutex_class).row_size"; size= sizeof(PFS_mutex_class); break; case 9: - name= "(PFS_MUTEX_CLASS).ROW_COUNT"; + name= "(pfs_mutex_class).row_count"; size= mutex_class_max; break; case 10: - name= "(PFS_MUTEX_CLASS).MEMORY"; + name= "(pfs_mutex_class).memory"; size= mutex_class_max * sizeof(PFS_mutex_class); total_memory+= size; break; case 11: - name= "(PFS_RWLOCK_CLASS).ROW_SIZE"; + name= "(pfs_rwlock_class).row_size"; size= sizeof(PFS_rwlock_class); break; case 12: - name= "(PFS_RWLOCK_CLASS).ROW_COUNT"; + name= "(pfs_rwlock_class).row_count"; size= rwlock_class_max; break; case 13: - name= "(PFS_RWLOCK_CLASS).MEMORY"; + name= "(pfs_rwlock_class).memory"; size= rwlock_class_max * sizeof(PFS_rwlock_class); total_memory+= size; break; case 14: - name= "(PFS_COND_CLASS).ROW_SIZE"; + name= "(pfs_cond_class).row_size"; size= sizeof(PFS_cond_class); break; case 15: - name= "(PFS_COND_CLASS).ROW_COUNT"; + name= "(pfs_cond_class).row_count"; size= cond_class_max; break; case 16: - name= "(PFS_COND_CLASS).MEMORY"; + name= "(pfs_cond_class).memory"; size= cond_class_max * sizeof(PFS_cond_class); total_memory+= size; break; case 17: - name= "(PFS_THREAD_CLASS).ROW_SIZE"; + name= "(pfs_thread_class).row_size"; size= sizeof(PFS_thread_class); break; case 18: - name= "(PFS_THREAD_CLASS).ROW_COUNT"; + name= "(pfs_thread_class).row_count"; size= thread_class_max; break; case 19: - name= "(PFS_THREAD_CLASS).MEMORY"; + name= "(pfs_thread_class).memory"; size= thread_class_max * sizeof(PFS_thread_class); total_memory+= size; break; case 20: - name= "(PFS_FILE_CLASS).ROW_SIZE"; + name= "(pfs_file_class).row_size"; size= sizeof(PFS_file_class); break; case 21: - name= "(PFS_FILE_CLASS).ROW_COUNT"; + name= "(pfs_file_class).row_count"; size= file_class_max; break; case 22: - name= "(PFS_FILE_CLASS).MEMORY"; + name= "(pfs_file_class).memory"; size= file_class_max * sizeof(PFS_file_class); total_memory+= size; break; case 23: - name= "MUTEX_INSTANCES.ROW_SIZE"; + name= "mutex_instances.row_size"; size= sizeof(PFS_mutex); break; case 24: - name= "MUTEX_INSTANCES.ROW_COUNT"; + name= "mutex_instances.row_count"; size= mutex_max; break; case 25: - name= "MUTEX_INSTANCES.MEMORY"; + name= "mutex_instances.memory"; size= mutex_max * sizeof(PFS_mutex); total_memory+= size; break; case 26: - name= "RWLOCK_INSTANCES.ROW_SIZE"; + name= "rwlock_instances.row_size"; size= sizeof(PFS_rwlock); break; case 27: - name= "RWLOCK_INSTANCES.ROW_COUNT"; + name= "rwlock_instances.row_count"; size= rwlock_max; break; case 28: - name= "RWLOCK_INSTANCES.MEMORY"; + name= "rwlock_instances.memory"; size= rwlock_max * sizeof(PFS_rwlock); total_memory+= size; break; case 29: - name= "COND_INSTANCES.ROW_SIZE"; + name= "cond_instances.row_size"; size= sizeof(PFS_cond); break; case 30: - name= "COND_INSTANCES.ROW_COUNT"; + name= "cond_instances.row_count"; size= cond_max; break; case 31: - name= "COND_INSTANCES.MEMORY"; + name= "cond_instances.memory"; size= cond_max * sizeof(PFS_cond); total_memory+= size; break; case 32: - name= "PROCESSLIST.ROW_SIZE"; + name= "threads.row_size"; size= sizeof(PFS_thread); break; case 33: - name= "PROCESSLIST.ROW_COUNT"; + name= "threads.row_count"; size= thread_max; break; case 34: - name= "PROCESSLIST.MEMORY"; + name= "threads.memory"; size= thread_max * sizeof(PFS_thread); total_memory+= size; break; case 35: - name= "FILE_INSTANCES.ROW_SIZE"; + name= "file_instances.row_size"; size= sizeof(PFS_file); break; case 36: - name= "FILE_INSTANCES.ROW_COUNT"; + name= "file_instances.row_count"; size= file_max; break; case 37: - name= "FILE_INSTANCES.MEMORY"; + name= "file_instances.memory"; size= file_max * sizeof(PFS_file); total_memory+= size; break; case 38: - name= "(PFS_FILE_HANDLE).ROW_SIZE"; + name= "(pfs_file_handle).row_size"; size= sizeof(PFS_file*); break; case 39: - name= "(PFS_FILE_HANDLE).ROW_COUNT"; + name= "(pfs_file_handle).row_count"; size= file_handle_max; break; case 40: - name= "(PFS_FILE_HANDLE).MEMORY"; + name= "(pfs_file_handle).memory"; size= file_handle_max * sizeof(PFS_file*); total_memory+= size; break; case 41: - name= "EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME.ROW_SIZE"; + name= "events_waits_summary_by_thread_by_event_name.row_size"; size= sizeof(PFS_single_stat_chain); break; case 42: - name= "EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME.ROW_COUNT"; + name= "events_waits_summary_by_thread_by_event_name.row_count"; size= thread_max * instr_class_per_thread; break; case 43: - name= "EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME.MEMORY"; + name= "events_waits_summary_by_thread_by_event_name.memory"; size= thread_max * instr_class_per_thread * sizeof(PFS_single_stat_chain); total_memory+= size; break; case 44: - name= "(PFS_TABLE_SHARE).ROW_SIZE"; + name= "(pfs_table_share).row_size"; size= sizeof(PFS_table_share); break; case 45: - name= "(PFS_TABLE_SHARE).ROW_COUNT"; + name= "(pfs_table_share).row_count"; size= table_share_max; break; case 46: - name= "(PFS_TABLE_SHARE).MEMORY"; + name= "(pfs_table_share).memory"; size= table_share_max * sizeof(PFS_table_share); total_memory+= size; break; case 47: - name= "(PFS_TABLE).ROW_SIZE"; + name= "(pfs_table).row_size"; size= sizeof(PFS_table); break; case 48: - name= "(PFS_TABLE).ROW_COUNT"; + name= "(pfs_table).row_count"; size= table_max; break; case 49: - name= "(PFS_TABLE).MEMORY"; + name= "(pfs_table).memory"; size= table_max * sizeof(PFS_table); total_memory+= size; break; @@ -758,7 +753,7 @@ bool pfs_show_status(handlerton *hton, THD *thd, for aggregation in total_memory. */ case 50: - name= "PERFORMANCE_SCHEMA.MEMORY"; + name= "performance_schema.memory"; size= total_memory; /* This will fail if something is not advertised here */ DBUG_ASSERT(size == pfs_allocated_memory); diff --git a/storage/perfschema/pfs_global.h b/storage/perfschema/pfs_global.h index 6050612e24c..c0c0490a380 100644 --- a/storage/perfschema/pfs_global.h +++ b/storage/perfschema/pfs_global.h @@ -79,5 +79,21 @@ inline uint randomized_index(const void *ptr, uint max_size) void pfs_print_error(const char *format, ...); +/** + Given an array defined as T ARRAY[MAX], + check that an UNSAFE pointer actually points to an element + within the array. +*/ +#define SANITIZE_ARRAY_BODY(T, ARRAY, MAX, UNSAFE) \ + intptr offset; \ + if ((&ARRAY[0] <= UNSAFE) && \ + (UNSAFE < &ARRAY[MAX])) \ + { \ + offset= ((intptr) UNSAFE - (intptr) ARRAY) % sizeof(T); \ + if (offset == 0) \ + return UNSAFE; \ + } \ + return NULL + #endif diff --git a/storage/perfschema/pfs_instr.cc b/storage/perfschema/pfs_instr.cc index 0c7b25a03de..a09920737c8 100644 --- a/storage/perfschema/pfs_instr.cc +++ b/storage/perfschema/pfs_instr.cc @@ -18,9 +18,9 @@ Performance schema instruments (implementation). */ +#include <my_global.h> #include <string.h> -#include "my_global.h" #include "my_sys.h" #include "pfs.h" #include "pfs_stat.h" @@ -758,9 +758,26 @@ PFS_thread* create_thread(PFS_thread_class *klass, const void *identity, */ PFS_thread *sanitize_thread(PFS_thread *unsafe) { - if ((&thread_array[0] <= unsafe) && - (unsafe < &thread_array[thread_max])) - return unsafe; + SANITIZE_ARRAY_BODY(PFS_thread, thread_array, thread_max, unsafe); +} + +const char *sanitize_file_name(const char *unsafe) +{ + intptr ptr= (intptr) unsafe; + intptr first= (intptr) &file_array[0]; + intptr last= (intptr) &file_array[file_max]; + + /* Check if unsafe points inside file_array[] */ + if (likely((first <= ptr) && (ptr < last))) + { + /* Check if unsafe points to PFS_file::m_filename */ + intptr offset= (ptr - first) % sizeof(PFS_file); + intptr valid_offset= my_offsetof(PFS_file, m_filename[0]); + if (likely(offset == valid_offset)) + { + return unsafe; + } + } return NULL; } diff --git a/storage/perfschema/pfs_instr.h b/storage/perfschema/pfs_instr.h index 791e2cd1f8d..2f6b729628e 100644 --- a/storage/perfschema/pfs_instr.h +++ b/storage/perfschema/pfs_instr.h @@ -227,6 +227,7 @@ struct PFS_thread }; PFS_thread *sanitize_thread(PFS_thread *unsafe); +const char *sanitize_file_name(const char *unsafe); PFS_single_stat_chain* find_per_thread_mutex_class_wait_stat(PFS_thread *thread, diff --git a/storage/perfschema/pfs_instr_class.cc b/storage/perfschema/pfs_instr_class.cc index 48547f73628..d99ca4d513c 100644 --- a/storage/perfschema/pfs_instr_class.cc +++ b/storage/perfschema/pfs_instr_class.cc @@ -543,15 +543,9 @@ PFS_mutex_class *find_mutex_class(PFS_sync_key key) FIND_CLASS_BODY(key, mutex_class_allocated_count, mutex_class_array); } -#define SANITIZE_ARRAY_BODY(ARRAY, MAX, UNSAFE) \ - if ((&ARRAY[0] <= UNSAFE) && \ - (UNSAFE < &ARRAY[MAX])) \ - return UNSAFE; \ - return NULL - PFS_mutex_class *sanitize_mutex_class(PFS_mutex_class *unsafe) { - SANITIZE_ARRAY_BODY(mutex_class_array, mutex_class_max, unsafe); + SANITIZE_ARRAY_BODY(PFS_mutex_class, mutex_class_array, mutex_class_max, unsafe); } /** @@ -566,7 +560,7 @@ PFS_rwlock_class *find_rwlock_class(PFS_sync_key key) PFS_rwlock_class *sanitize_rwlock_class(PFS_rwlock_class *unsafe) { - SANITIZE_ARRAY_BODY(rwlock_class_array, rwlock_class_max, unsafe); + SANITIZE_ARRAY_BODY(PFS_rwlock_class, rwlock_class_array, rwlock_class_max, unsafe); } /** @@ -581,7 +575,7 @@ PFS_cond_class *find_cond_class(PFS_sync_key key) PFS_cond_class *sanitize_cond_class(PFS_cond_class *unsafe) { - SANITIZE_ARRAY_BODY(cond_class_array, cond_class_max, unsafe); + SANITIZE_ARRAY_BODY(PFS_cond_class, cond_class_array, cond_class_max, unsafe); } /** @@ -636,7 +630,7 @@ PFS_thread_class *find_thread_class(PFS_sync_key key) PFS_thread_class *sanitize_thread_class(PFS_thread_class *unsafe) { - SANITIZE_ARRAY_BODY(thread_class_array, thread_class_max, unsafe); + SANITIZE_ARRAY_BODY(PFS_thread_class, thread_class_array, thread_class_max, unsafe); } /** @@ -687,7 +681,7 @@ PFS_file_class *find_file_class(PFS_file_key key) PFS_file_class *sanitize_file_class(PFS_file_class *unsafe) { - SANITIZE_ARRAY_BODY(file_class_array, file_class_max, unsafe); + SANITIZE_ARRAY_BODY(PFS_file_class, file_class_array, file_class_max, unsafe); } /** @@ -820,7 +814,59 @@ search: PFS_table_share *sanitize_table_share(PFS_table_share *unsafe) { - SANITIZE_ARRAY_BODY(table_share_array, table_share_max, unsafe); + SANITIZE_ARRAY_BODY(PFS_table_share, table_share_array, table_share_max, unsafe); +} + +const char *sanitize_table_schema_name(const char *unsafe) +{ + intptr ptr= (intptr) unsafe; + intptr first= (intptr) &table_share_array[0]; + intptr last= (intptr) &table_share_array[table_share_max]; + + PFS_table_share dummy; + + /* Check if unsafe points inside table_share_array[] */ + if (likely((first <= ptr) && (ptr < last))) + { + intptr offset= (ptr - first) % sizeof(PFS_table_share); + intptr from= my_offsetof(PFS_table_share, m_key.m_hash_key); + intptr len= sizeof(dummy.m_key.m_hash_key); + /* Check if unsafe points inside PFS_table_share::m_key::m_hash_key */ + if (likely((from <= offset) && (offset < from + len))) + { + PFS_table_share *base= (PFS_table_share*) (ptr - offset); + /* Check if unsafe really is the schema name */ + if (likely(base->m_schema_name == unsafe)) + return unsafe; + } + } + return NULL; +} + +const char *sanitize_table_object_name(const char *unsafe) +{ + intptr ptr= (intptr) unsafe; + intptr first= (intptr) &table_share_array[0]; + intptr last= (intptr) &table_share_array[table_share_max]; + + PFS_table_share dummy; + + /* Check if unsafe points inside table_share_array[] */ + if (likely((first <= ptr) && (ptr < last))) + { + intptr offset= (ptr - first) % sizeof(PFS_table_share); + intptr from= my_offsetof(PFS_table_share, m_key.m_hash_key); + intptr len= sizeof(dummy.m_key.m_hash_key); + /* Check if unsafe points inside PFS_table_share::m_key::m_hash_key */ + if (likely((from <= offset) && (offset < from + len))) + { + PFS_table_share *base= (PFS_table_share*) (ptr - offset); + /* Check if unsafe really is the table name */ + if (likely(base->m_table_name == unsafe)) + return unsafe; + } + } + return NULL; } static void reset_mutex_class_waits(void) diff --git a/storage/perfschema/pfs_instr_class.h b/storage/perfschema/pfs_instr_class.h index bd6560dbb55..107db628226 100644 --- a/storage/perfschema/pfs_instr_class.h +++ b/storage/perfschema/pfs_instr_class.h @@ -222,6 +222,8 @@ PFS_thread_class *find_thread_class(PSI_thread_key key); PFS_thread_class *sanitize_thread_class(PFS_thread_class *unsafe); PFS_file_class *find_file_class(PSI_file_key key); PFS_file_class *sanitize_file_class(PFS_file_class *unsafe); +const char *sanitize_table_schema_name(const char *unsafe); +const char *sanitize_table_object_name(const char *unsafe); PFS_table_share *find_or_create_table_share(PFS_thread *thread, const char *schema_name, diff --git a/storage/perfschema/pfs_lock.h b/storage/perfschema/pfs_lock.h index 5c74d3944ba..d253cfa4366 100644 --- a/storage/perfschema/pfs_lock.h +++ b/storage/perfschema/pfs_lock.h @@ -135,7 +135,25 @@ struct pfs_lock */ void allocated_to_free(void) { - DBUG_ASSERT(m_state == PFS_LOCK_ALLOCATED); +#ifndef DBUG_OFF + extern volatile bool ready_to_exit; +#endif + + /* + If this record is not in the ALLOCATED state and the caller is trying + to free it, this is a bug: the caller is confused, + and potentially damaging data owned by another thread or object. + The correct assert to use here to guarantee data integrity is simply: + DBUG_ASSERT(m_state == PFS_LOCK_ALLOCATED); + Now, because of Bug#56666 (Race condition between the server main thread + and the kill server thread), this assert actually fails during shutdown, + and the failure is legitimate, on concurrent calls to mysql_*_destroy(), + when destroying the instrumentation of an object ... twice. + During shutdown this has no consequences for the performance schema, + so the assert is relaxed with the "|| ready_to_exit" condition as a work + around until Bug#56666 is fixed. + */ + DBUG_ASSERT((m_state == PFS_LOCK_ALLOCATED) || ready_to_exit); PFS_atomic::store_32(&m_state, PFS_LOCK_FREE); } diff --git a/storage/perfschema/plug.in b/storage/perfschema/plug.in deleted file mode 100644 index 36a1c1e8bda..00000000000 --- a/storage/perfschema/plug.in +++ /dev/null @@ -1,26 +0,0 @@ -dnl -*- ksh -*- - -# Copyright (c) 2008, 2010, 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 -# the Free Software Foundation; version 2 of the License. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA - -dnl This file is part of the configure scripts used by autoconf. - -MYSQL_STORAGE_ENGINE(perfschema, - perfschema, - [Performance Schema], - [Performance Schema], - [default,max,max-no-ndb]) -MYSQL_PLUGIN_DIRECTORY(perfschema, [storage/perfschema]) -MYSQL_PLUGIN_STATIC(perfschema, [libperfschema.a]) diff --git a/storage/perfschema/table_events_waits.cc b/storage/perfschema/table_events_waits.cc index d34f6fbe722..8408cc55975 100644 --- a/storage/perfschema/table_events_waits.cc +++ b/storage/perfschema/table_events_waits.cc @@ -118,7 +118,7 @@ table_events_waits_current::m_field_def= PFS_engine_table_share table_events_waits_current::m_share= { - { C_STRING_WITH_LEN("EVENTS_WAITS_CURRENT") }, + { C_STRING_WITH_LEN("events_waits_current") }, &pfs_truncatable_acl, &table_events_waits_current::create, NULL, /* write_row */ @@ -135,7 +135,7 @@ THR_LOCK table_events_waits_history::m_table_lock; PFS_engine_table_share table_events_waits_history::m_share= { - { C_STRING_WITH_LEN("EVENTS_WAITS_HISTORY") }, + { C_STRING_WITH_LEN("events_waits_history") }, &pfs_truncatable_acl, &table_events_waits_history::create, NULL, /* write_row */ @@ -152,7 +152,7 @@ THR_LOCK table_events_waits_history_long::m_table_lock; PFS_engine_table_share table_events_waits_history_long::m_share= { - { C_STRING_WITH_LEN("EVENTS_WAITS_HISTORY_LONG") }, + { C_STRING_WITH_LEN("events_waits_history_long") }, &pfs_truncatable_acl, &table_events_waits_history_long::create, NULL, /* write_row */ @@ -194,6 +194,9 @@ void table_events_waits_common::make_row(bool thread_own_wait, PFS_instr_class *safe_class; const char *base; const char *safe_source_file; + const char *safe_table_schema_name; + const char *safe_table_object_name; + const char *safe_file_name; m_row_exists= false; safe_thread= sanitize_thread(pfs_thread); @@ -252,15 +255,19 @@ void table_events_waits_common::make_row(bool thread_own_wait, m_row.m_object_type= "TABLE"; m_row.m_object_type_length= 5; m_row.m_object_schema_length= wait->m_schema_name_length; + safe_table_schema_name= sanitize_table_schema_name(wait->m_schema_name); if (unlikely((m_row.m_object_schema_length == 0) || - (m_row.m_object_schema_length > sizeof(m_row.m_object_schema)))) + (m_row.m_object_schema_length > sizeof(m_row.m_object_schema)) || + (safe_table_schema_name == NULL))) return; - memcpy(m_row.m_object_schema, wait->m_schema_name, m_row.m_object_schema_length); + memcpy(m_row.m_object_schema, safe_table_schema_name, m_row.m_object_schema_length); m_row.m_object_name_length= wait->m_object_name_length; + safe_table_object_name= sanitize_table_object_name(wait->m_object_name); if (unlikely((m_row.m_object_name_length == 0) || - (m_row.m_object_name_length > sizeof(m_row.m_object_name)))) + (m_row.m_object_name_length > sizeof(m_row.m_object_name)) || + (safe_table_object_name == NULL))) return; - memcpy(m_row.m_object_name, wait->m_object_name, m_row.m_object_name_length); + memcpy(m_row.m_object_name, safe_table_object_name, m_row.m_object_name_length); safe_class= &global_table_class; break; case WAIT_CLASS_FILE: @@ -268,10 +275,12 @@ void table_events_waits_common::make_row(bool thread_own_wait, m_row.m_object_type_length= 4; m_row.m_object_schema_length= 0; m_row.m_object_name_length= wait->m_object_name_length; + safe_file_name= sanitize_file_name(wait->m_object_name); if (unlikely((m_row.m_object_name_length == 0) || - (m_row.m_object_name_length > sizeof(m_row.m_object_name)))) + (m_row.m_object_name_length > sizeof(m_row.m_object_name)) || + (safe_file_name == NULL))) return; - memcpy(m_row.m_object_name, wait->m_object_name, m_row.m_object_name_length); + memcpy(m_row.m_object_name, safe_file_name, m_row.m_object_name_length); safe_class= sanitize_file_class((PFS_file_class*) wait->m_class); break; case NO_WAIT_CLASS: diff --git a/storage/perfschema/table_events_waits_summary.cc b/storage/perfschema/table_events_waits_summary.cc index 435a3500f06..05f280f8521 100644 --- a/storage/perfschema/table_events_waits_summary.cc +++ b/storage/perfschema/table_events_waits_summary.cc @@ -74,7 +74,7 @@ table_events_waits_summary_by_thread_by_event_name::m_field_def= PFS_engine_table_share table_events_waits_summary_by_thread_by_event_name::m_share= { - { C_STRING_WITH_LEN("EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME") }, + { C_STRING_WITH_LEN("events_waits_summary_by_thread_by_event_name") }, &pfs_truncatable_acl, &table_events_waits_summary_by_thread_by_event_name::create, NULL, /* write_row */ @@ -386,7 +386,7 @@ table_events_waits_summary_by_instance::m_field_def= PFS_engine_table_share table_events_waits_summary_by_instance::m_share= { - { C_STRING_WITH_LEN("EVENTS_WAITS_SUMMARY_BY_INSTANCE") }, + { C_STRING_WITH_LEN("events_waits_summary_by_instance") }, &pfs_truncatable_acl, &table_events_waits_summary_by_instance::create, NULL, /* write_row */ diff --git a/storage/perfschema/table_ews_global_by_event_name.cc b/storage/perfschema/table_ews_global_by_event_name.cc index 35e744ed96b..c983a967c4e 100644 --- a/storage/perfschema/table_ews_global_by_event_name.cc +++ b/storage/perfschema/table_ews_global_by_event_name.cc @@ -69,7 +69,7 @@ table_ews_global_by_event_name::m_field_def= PFS_engine_table_share table_ews_global_by_event_name::m_share= { - { C_STRING_WITH_LEN("EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME") }, + { C_STRING_WITH_LEN("events_waits_summary_global_by_event_name") }, &pfs_truncatable_acl, &table_ews_global_by_event_name::create, NULL, /* write_row */ diff --git a/storage/perfschema/table_file_instances.cc b/storage/perfschema/table_file_instances.cc index f1676421616..9ae732a0e1c 100644 --- a/storage/perfschema/table_file_instances.cc +++ b/storage/perfschema/table_file_instances.cc @@ -54,7 +54,7 @@ table_file_instances::m_field_def= PFS_engine_table_share table_file_instances::m_share= { - { C_STRING_WITH_LEN("FILE_INSTANCES") }, + { C_STRING_WITH_LEN("file_instances") }, &pfs_readonly_acl, &table_file_instances::create, NULL, /* write_row */ diff --git a/storage/perfschema/table_file_summary.cc b/storage/perfschema/table_file_summary.cc index f8b9e66118b..a954db7ef4e 100644 --- a/storage/perfschema/table_file_summary.cc +++ b/storage/perfschema/table_file_summary.cc @@ -64,7 +64,7 @@ table_file_summary_by_event_name::m_field_def= PFS_engine_table_share table_file_summary_by_event_name::m_share= { - { C_STRING_WITH_LEN("FILE_SUMMARY_BY_EVENT_NAME") }, + { C_STRING_WITH_LEN("file_summary_by_event_name") }, &pfs_truncatable_acl, &table_file_summary_by_event_name::create, NULL, /* write_row */ @@ -227,7 +227,7 @@ table_file_summary_by_instance::m_field_def= PFS_engine_table_share table_file_summary_by_instance::m_share= { - { C_STRING_WITH_LEN("FILE_SUMMARY_BY_INSTANCE") }, + { C_STRING_WITH_LEN("file_summary_by_instance") }, &pfs_truncatable_acl, &table_file_summary_by_instance::create, NULL, /* write_row */ diff --git a/storage/perfschema/table_performance_timers.cc b/storage/perfschema/table_performance_timers.cc index f400e37366c..acd379bc57b 100644 --- a/storage/perfschema/table_performance_timers.cc +++ b/storage/perfschema/table_performance_timers.cc @@ -58,7 +58,7 @@ table_performance_timers::m_field_def= PFS_engine_table_share table_performance_timers::m_share= { - { C_STRING_WITH_LEN("PERFORMANCE_TIMERS") }, + { C_STRING_WITH_LEN("performance_timers") }, &pfs_readonly_acl, &table_performance_timers::create, NULL, /* write_row */ diff --git a/storage/perfschema/table_setup_consumers.cc b/storage/perfschema/table_setup_consumers.cc index 3cc6a1441c1..601e0483b14 100644 --- a/storage/perfschema/table_setup_consumers.cc +++ b/storage/perfschema/table_setup_consumers.cc @@ -84,7 +84,7 @@ table_setup_consumers::m_field_def= PFS_engine_table_share table_setup_consumers::m_share= { - { C_STRING_WITH_LEN("SETUP_CONSUMERS") }, + { C_STRING_WITH_LEN("setup_consumers") }, &pfs_updatable_acl, &table_setup_consumers::create, NULL, /* write_row */ @@ -192,7 +192,6 @@ int table_setup_consumers::update_row_values(TABLE *table, switch(f->field_index) { case 0: /* NAME */ - my_error(ER_WRONG_PERFSCHEMA_USAGE, MYF(0)); return HA_ERR_WRONG_COMMAND; case 1: /* ENABLED */ { diff --git a/storage/perfschema/table_setup_instruments.cc b/storage/perfschema/table_setup_instruments.cc index 259ccee3c84..480c0dbc13f 100644 --- a/storage/perfschema/table_setup_instruments.cc +++ b/storage/perfschema/table_setup_instruments.cc @@ -54,7 +54,7 @@ table_setup_instruments::m_field_def= PFS_engine_table_share table_setup_instruments::m_share= { - { C_STRING_WITH_LEN("SETUP_INSTRUMENTS") }, + { C_STRING_WITH_LEN("setup_instruments") }, &pfs_updatable_acl, &table_setup_instruments::create, NULL, /* write_row */ @@ -253,7 +253,6 @@ int table_setup_instruments::update_row_values(TABLE *table, switch(f->field_index) { case 0: /* NAME */ - my_error(ER_WRONG_PERFSCHEMA_USAGE, MYF(0)); return HA_ERR_WRONG_COMMAND; case 1: /* ENABLED */ value= (enum_yes_no) get_field_enum(f); diff --git a/storage/perfschema/table_setup_timers.cc b/storage/perfschema/table_setup_timers.cc index 8ca218913bb..f8b1bfa4fe2 100644 --- a/storage/perfschema/table_setup_timers.cc +++ b/storage/perfschema/table_setup_timers.cc @@ -57,7 +57,7 @@ table_setup_timers::m_field_def= PFS_engine_table_share table_setup_timers::m_share= { - { C_STRING_WITH_LEN("SETUP_TIMERS") }, + { C_STRING_WITH_LEN("setup_timers") }, &pfs_updatable_acl, &table_setup_timers::create, NULL, /* write_row */ @@ -164,7 +164,6 @@ int table_setup_timers::update_row_values(TABLE *table, switch(f->field_index) { case 0: /* NAME */ - my_error(ER_WRONG_PERFSCHEMA_USAGE, MYF(0)); return HA_ERR_WRONG_COMMAND; case 1: /* TIMER_NAME */ value= get_field_enum(f); diff --git a/storage/perfschema/table_sync_instances.cc b/storage/perfschema/table_sync_instances.cc index 82587ce493d..f2bd9fa1a28 100644 --- a/storage/perfschema/table_sync_instances.cc +++ b/storage/perfschema/table_sync_instances.cc @@ -55,7 +55,7 @@ table_mutex_instances::m_field_def= PFS_engine_table_share table_mutex_instances::m_share= { - { C_STRING_WITH_LEN("MUTEX_INSTANCES") }, + { C_STRING_WITH_LEN("mutex_instances") }, &pfs_readonly_acl, &table_mutex_instances::create, NULL, /* write_row */ @@ -223,7 +223,7 @@ table_rwlock_instances::m_field_def= PFS_engine_table_share table_rwlock_instances::m_share= { - { C_STRING_WITH_LEN("RWLOCK_INSTANCES") }, + { C_STRING_WITH_LEN("rwlock_instances") }, &pfs_readonly_acl, &table_rwlock_instances::create, NULL, /* write_row */ @@ -388,7 +388,7 @@ table_cond_instances::m_field_def= PFS_engine_table_share table_cond_instances::m_share= { - { C_STRING_WITH_LEN("COND_INSTANCES") }, + { C_STRING_WITH_LEN("cond_instances") }, &pfs_readonly_acl, &table_cond_instances::create, NULL, /* write_row */ diff --git a/storage/perfschema/table_threads.cc b/storage/perfschema/table_threads.cc index bba7806cab9..541ba860386 100644 --- a/storage/perfschema/table_threads.cc +++ b/storage/perfschema/table_threads.cc @@ -34,13 +34,13 @@ static const TABLE_FIELD_TYPE field_types[]= { NULL, 0} }, { - { C_STRING_WITH_LEN("ID") }, + { C_STRING_WITH_LEN("PROCESSLIST_ID") }, { C_STRING_WITH_LEN("int(11)") }, { NULL, 0} }, { { C_STRING_WITH_LEN("NAME") }, - { C_STRING_WITH_LEN("varchar(64)") }, + { C_STRING_WITH_LEN("varchar(128)") }, { NULL, 0} } }; @@ -52,7 +52,7 @@ table_threads::m_field_def= PFS_engine_table_share table_threads::m_share= { - { C_STRING_WITH_LEN("THREADS") }, + { C_STRING_WITH_LEN("threads") }, &pfs_readonly_acl, &table_threads::create, NULL, /* write_row */ @@ -140,7 +140,7 @@ void table_threads::make_row(PFS_thread *pfs) } int table_threads::read_row_values(TABLE *table, - unsigned char *, + unsigned char *buf, Field **fields, bool read_all) { @@ -150,7 +150,8 @@ int table_threads::read_row_values(TABLE *table, return HA_ERR_RECORD_DELETED; /* Set the null bits */ - DBUG_ASSERT(table->s->null_bytes == 0); + DBUG_ASSERT(table->s->null_bytes == 1); + buf[0]= 0; for (; (f= *fields) ; fields++) { @@ -161,7 +162,7 @@ int table_threads::read_row_values(TABLE *table, case 0: /* THREAD_ID */ set_field_ulong(f, m_row.m_thread_internal_id); break; - case 1: /* ID */ + case 1: /* PROCESSLIST_ID */ set_field_ulong(f, m_row.m_thread_id); break; case 2: /* NAME */ diff --git a/storage/perfschema/table_threads.h b/storage/perfschema/table_threads.h index 9df323f6d82..fb239007069 100644 --- a/storage/perfschema/table_threads.h +++ b/storage/perfschema/table_threads.h @@ -36,7 +36,7 @@ struct row_threads { /** Column THREAD_ID. */ ulong m_thread_internal_id; - /** Column ID. */ + /** Column PROCESSLIST_ID. */ ulong m_thread_id; /** Column NAME. */ const char *m_name; @@ -79,7 +79,7 @@ private: /** Current row. */ row_threads m_row; - /** True is the current row exists. */ + /** True if the current row exists. */ bool m_row_exists; /** Current position. */ PFS_simple_index m_pos; diff --git a/storage/perfschema/unittest/Makefile.am b/storage/perfschema/unittest/Makefile.am deleted file mode 100644 index 7d82753c9e5..00000000000 --- a/storage/perfschema/unittest/Makefile.am +++ /dev/null @@ -1,58 +0,0 @@ -# Copyright (C) 2008-2009 Sun Microsystems, Inc. -# -# 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 -# the Free Software Foundation; version 2 of the License. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# 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 - -INCLUDES = -I$(top_builddir)/include \ - -I$(top_srcdir)/include \ - -I$(top_srcdir)/include/mysql \ - -I$(top_srcdir)/regex \ - -I$(top_srcdir)/unittest/mytap \ - -I$(top_srcdir)/sql \ - -I$(top_srcdir)/storage/perfschema - -DEFS = -DMYSQL_SERVER @DEFS@ - -TEST_CODE = $(top_builddir)/unittest/mytap/libmytap.a - -$(TEST_CODE) : - (cd $(top_builddir)/unittest/mytap; $(MAKE)) - -PROD_CODE = $(top_builddir)/storage/perfschema/libperfschema.a \ - $(top_builddir)/mysys/libmysys.a \ - $(top_builddir)/dbug/libdbug.a \ - $(top_builddir)/strings/libmystrings.a - -noinst_PROGRAMS = pfs_instr_class-t pfs_instr_class-oom-t \ - pfs_instr-t pfs_instr-oom-t pfs_timer-t pfs-t - -pfs_t_SOURCES = pfs-t.cc stub_print_error.h -pfs_t_LDADD = $(TEST_CODE) $(PROD_CODE) - -pfs_instr_class_t_SOURCES = pfs_instr_class-t.cc -pfs_instr_class_t_LDADD = $(TEST_CODE) $(PROD_CODE) - -pfs_instr_class_oom_t_SOURCES = pfs_instr_class-oom-t.cc stub_pfs_global.h -pfs_instr_class_oom_t_LDADD = $(TEST_CODE) $(PROD_CODE) - -pfs_instr_t_SOURCES = pfs_instr-t.cc -pfs_instr_t_LDADD = $(TEST_CODE) $(PROD_CODE) - -pfs_instr_oom_t_SOURCES = pfs_instr-oom-t.cc stub_pfs_global.h -pfs_instr_oom_t_LDADD = $(TEST_CODE) $(PROD_CODE) - -pfs_timer_t_SOURCES = pfs_timer-t.cc -pfs_timer_t_LDADD = $(TEST_CODE) $(PROD_CODE) - -EXTRA_DIST = conf.txt CMakeLists.txt - diff --git a/storage/perfschema/unittest/pfs-t.cc b/storage/perfschema/unittest/pfs-t.cc index c51f358c4d8..46e02306aca 100644 --- a/storage/perfschema/unittest/pfs-t.cc +++ b/storage/perfschema/unittest/pfs-t.cc @@ -25,6 +25,7 @@ #include <memory.h> #include "stub_print_error.h" +#include "stub_server_misc.h" /* test helpers, to simulate the setup */ @@ -1204,6 +1205,8 @@ void test_enabled() void do_all_tests() { + /* Using initialize_performance_schema(), no partial init needed. */ + test_bootstrap(); test_bad_registration(); test_init_disabled(); diff --git a/storage/perfschema/unittest/pfs_instr-oom-t.cc b/storage/perfschema/unittest/pfs_instr-oom-t.cc index 9a3b179aa56..a00afe8b36a 100644 --- a/storage/perfschema/unittest/pfs_instr-oom-t.cc +++ b/storage/perfschema/unittest/pfs_instr-oom-t.cc @@ -21,6 +21,7 @@ #include <tap.h> #include "stub_pfs_global.h" +#include "stub_server_misc.h" void test_oom() { @@ -198,7 +199,11 @@ void test_oom() void do_all_tests() { + PFS_atomic::init(); + test_oom(); + + PFS_atomic::cleanup(); } int main(int, char **) diff --git a/storage/perfschema/unittest/pfs_instr-t.cc b/storage/perfschema/unittest/pfs_instr-t.cc index 7dcc8cec7f8..b13135aa615 100644 --- a/storage/perfschema/unittest/pfs_instr-t.cc +++ b/storage/perfschema/unittest/pfs_instr-t.cc @@ -22,6 +22,8 @@ #include <memory.h> +#include "stub_server_misc.h" + void test_no_instruments() { int rc; @@ -398,10 +400,14 @@ void test_per_thread_wait() void do_all_tests() { + PFS_atomic::init(); + test_no_instruments(); test_no_instances(); test_with_instances(); test_per_thread_wait(); + + PFS_atomic::cleanup(); } int main(int, char **) diff --git a/storage/perfschema/unittest/pfs_instr_class-oom-t.cc b/storage/perfschema/unittest/pfs_instr_class-oom-t.cc index 20fa0f3e6ff..95dccc420d7 100644 --- a/storage/perfschema/unittest/pfs_instr_class-oom-t.cc +++ b/storage/perfschema/unittest/pfs_instr_class-oom-t.cc @@ -20,6 +20,7 @@ #include <tap.h> #include "stub_pfs_global.h" +#include "stub_server_misc.h" void test_oom() { @@ -46,7 +47,11 @@ void test_oom() void do_all_tests() { + PFS_atomic::init(); + test_oom(); + + PFS_atomic::cleanup(); } int main(int, char **) diff --git a/storage/perfschema/unittest/pfs_instr_class-t.cc b/storage/perfschema/unittest/pfs_instr_class-t.cc index c5a199727d5..ac34f082fe8 100644 --- a/storage/perfschema/unittest/pfs_instr_class-t.cc +++ b/storage/perfschema/unittest/pfs_instr_class-t.cc @@ -21,6 +21,8 @@ #include <pfs_global.h> #include <tap.h> +#include "stub_server_misc.h" + void test_no_registration() { int rc; @@ -552,6 +554,8 @@ void test_instruments_reset() void do_all_tests() { + PFS_atomic::init(); + test_no_registration(); test_mutex_registration(); test_rwlock_registration(); @@ -560,6 +564,8 @@ void do_all_tests() test_file_registration(); test_table_registration(); test_instruments_reset(); + + PFS_atomic::cleanup(); } int main(int, char **) diff --git a/storage/perfschema/unittest/pfs_timer-t.cc b/storage/perfschema/unittest/pfs_timer-t.cc index d8663c5ccda..69b554c7b31 100644 --- a/storage/perfschema/unittest/pfs_timer-t.cc +++ b/storage/perfschema/unittest/pfs_timer-t.cc @@ -105,7 +105,11 @@ void test_timers() void do_all_tests() { + PFS_atomic::init(); + test_timers(); + + PFS_atomic::cleanup(); } int main(int, char **) diff --git a/storage/perfschema/unittest/stub_server_misc.h b/storage/perfschema/unittest/stub_server_misc.h new file mode 100644 index 00000000000..17beadbb104 --- /dev/null +++ b/storage/perfschema/unittest/stub_server_misc.h @@ -0,0 +1,21 @@ +/* Copyright (c) 2010, 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 + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + 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 */ + +/* + Minimal code to be able to link a unit test. +*/ + +volatile bool ready_to_exit= false; + |