From: Marc Alff Date: May 7 2010 10:09am Subject: bzr push into mysql-next-mr branch (marc.alff:3140 to 3141) WL#4674 List-Archive: http://lists.mysql.com/commits/107722 Message-Id: <20100507100901.CAC92561698@MarcBook.local> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="Boundary_(ID_Am9jUUmHHwieXkfMiQbxow)" --Boundary_(ID_Am9jUUmHHwieXkfMiQbxow) MIME-version: 1.0 Content-type: text/plain; CHARSET=US-ASCII Content-transfer-encoding: 7BIT Content-disposition: inline 3141 Marc Alff 2010-05-07 WL#4674 PERFORMANCE_SCHEMA SETUP ACTORS Port in progress added: storage/perfschema/pfs_setup_actor.cc storage/perfschema/pfs_setup_actor.h modified: include/mysql/psi/psi.h include/mysql/psi/psi_abi_v1.h.pp libmysqld/lib_sql.cc sql/event_scheduler.cc sql/ha_ndbcluster_binlog.cc sql/log.cc sql/sql_class.cc sql/sql_class.h sql/sql_connect.cc sql/sql_insert.cc sql/sql_parse.cc sql/sql_prepare.cc sql/sql_repl.cc sql/sql_show.cc storage/perfschema/CMakeLists.txt storage/perfschema/Makefile.am storage/perfschema/pfs.cc storage/perfschema/pfs_instr.cc storage/perfschema/pfs_instr.h storage/perfschema/pfs_lock.h storage/perfschema/pfs_server.h storage/perfschema/unittest/stub_pfs_global.h 3140 Marc Alff 2010-05-07 [merge] merge mysql-next-mr --> mysql-next-mr-wl4674 removed: sql/mysql_priv.h.pp strings/dtoa.c added: include/sha2.h mysql-test/include/have_archive_plugin.inc mysql-test/include/have_blackhole_plugin.inc mysql-test/include/have_ssl_crypto_functs.inc mysql-test/r/archive_plugin.result mysql-test/r/blackhole_plugin.result mysql-test/r/func_digest.result mysql-test/r/have_ssl_is_yes_or_disabled_only.require mysql-test/suite/rpl/r/rpl_non_direct_mixed_mixing_engines.result mysql-test/suite/rpl/r/rpl_non_direct_row_mixing_engines.result mysql-test/suite/rpl/r/rpl_non_direct_stm_mixing_engines.result mysql-test/suite/rpl/r/rpl_temp_temporary.result mysql-test/suite/rpl/t/rpl_non_direct_mixed_mixing_engines.test mysql-test/suite/rpl/t/rpl_non_direct_row_mixing_engines.test mysql-test/suite/rpl/t/rpl_non_direct_stm_mixing_engines.test mysql-test/suite/rpl/t/rpl_temp_temporary.test mysql-test/t/archive_plugin-master.opt mysql-test/t/archive_plugin.test mysql-test/t/blackhole_plugin-master.opt mysql-test/t/blackhole_plugin.test mysql-test/t/func_digest.test sql/sha2.cc strings/dtoa.c modified: .bzrignore BUILD/choose_configure.sh Makefile.am client/mysql.cc client/mysqltest.cc cmake/abi_check.cmake cmake/install_macros.cmake cmake/libutils.cmake cmake/mysql_add_executable.cmake cmake/mysql_version.cmake cmake/os/WindowsCache.cmake cmake/plugin.cmake configure.cmake dbug/dbug.c include/Makefile.am include/my_global.h include/mysql/innodb_priv.h include/mysql/plugin_audit.h include/mysql_embed.h include/sslopt-case.h include/sslopt-longopts.h include/sslopt-vars.h include/violite.h libmysqld/CMakeLists.txt libmysqld/Makefile.am libmysqld/examples/Makefile.am libmysqld/lib_sql.cc mysql-test/collections/default.experimental mysql-test/extra/rpl_tests/rpl_binlog_max_cache_size.test mysql-test/extra/rpl_tests/rpl_implicit_commit_binlog.test mysql-test/extra/rpl_tests/rpl_innodb.test mysql-test/extra/rpl_tests/rpl_loaddata.test mysql-test/extra/rpl_tests/rpl_mixing_engines.test mysql-test/include/commit.inc mysql-test/include/ctype_utf8_table.inc mysql-test/r/commit_1innodb.result mysql-test/r/count_distinct.result mysql-test/r/ctype_cp932_binlog_stm.result mysql-test/r/func_encrypt_nossl.result mysql-test/r/func_group.result mysql-test/r/func_misc.result mysql-test/r/grant.result mysql-test/r/innodb_mysql_sync.result mysql-test/r/insert_notembedded.result mysql-test/r/lock_sync.result mysql-test/r/myisam.result mysql-test/r/mysqldump.result mysql-test/r/show_check.result mysql-test/r/sp-lock.result mysql-test/r/sp.result mysql-test/r/sp_sync.result mysql-test/r/trigger_notembedded.result mysql-test/suite/binlog/r/binlog_database.result mysql-test/suite/binlog/r/binlog_innodb_row.result mysql-test/suite/binlog/r/binlog_multi_engine.result mysql-test/suite/binlog/r/binlog_row_binlog.result mysql-test/suite/binlog/r/binlog_row_drop_tmp_tbl.result mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result mysql-test/suite/binlog/r/binlog_stm_binlog.result mysql-test/suite/binlog/r/binlog_stm_mix_innodb_myisam.result mysql-test/suite/binlog/r/binlog_switch_inside_trans.result mysql-test/suite/binlog/t/binlog_switch_inside_trans.test mysql-test/suite/binlog/t/binlog_tmp_table.test mysql-test/suite/ndb/r/ndb_binlog_format.result mysql-test/suite/perfschema/r/dml_cond_instances.result mysql-test/suite/perfschema/r/dml_events_waits_current.result mysql-test/suite/perfschema/r/dml_events_waits_history.result mysql-test/suite/perfschema/r/dml_events_waits_history_long.result mysql-test/suite/perfschema/r/dml_ews_by_event_name.result mysql-test/suite/perfschema/r/dml_ews_by_instance.result mysql-test/suite/perfschema/r/dml_ews_by_thread_by_event_name.result mysql-test/suite/perfschema/r/dml_file_instances.result mysql-test/suite/perfschema/r/dml_file_summary_by_event_name.result mysql-test/suite/perfschema/r/dml_file_summary_by_instance.result mysql-test/suite/perfschema/r/dml_mutex_instances.result mysql-test/suite/perfschema/r/dml_performance_timers.result mysql-test/suite/perfschema/r/dml_processlist.result mysql-test/suite/perfschema/r/dml_rwlock_instances.result mysql-test/suite/perfschema/r/misc.result mysql-test/suite/perfschema/r/pfs_upgrade.result mysql-test/suite/perfschema/r/privilege.result mysql-test/suite/perfschema/r/tampered_perfschema_table1.result mysql-test/suite/perfschema/t/misc.test mysql-test/suite/perfschema/t/tampered_perfschema_table1.test mysql-test/suite/rpl/r/rpl_concurrency_error.result mysql-test/suite/rpl/r/rpl_mixed_binlog_max_cache_size.result mysql-test/suite/rpl/r/rpl_mixed_implicit_commit_binlog.result mysql-test/suite/rpl/r/rpl_mixed_mixing_engines.result mysql-test/suite/rpl/r/rpl_mixed_row_innodb.result mysql-test/suite/rpl/r/rpl_row_drop.result mysql-test/suite/rpl/r/rpl_row_implicit_commit_binlog.result mysql-test/suite/rpl/r/rpl_row_mixing_engines.result mysql-test/suite/rpl/r/rpl_sp.result mysql-test/suite/rpl/r/rpl_stm_binlog_max_cache_size.result mysql-test/suite/rpl/r/rpl_stm_implicit_commit_binlog.result mysql-test/suite/rpl/r/rpl_stm_innodb.result mysql-test/suite/rpl/r/rpl_stm_mixing_engines.result mysql-test/suite/rpl/r/rpl_stm_stop_middle_group.result mysql-test/suite/rpl/t/rpl000013.test mysql-test/suite/rpl/t/rpl_misc_functions.test mysql-test/suite/rpl/t/rpl_semi_sync.test mysql-test/suite/rpl/t/rpl_sp.test mysql-test/suite/rpl/t/rpl_ssl.test mysql-test/suite/rpl/t/rpl_ssl1.test mysql-test/suite/rpl/t/rpl_temp_table.test mysql-test/suite/rpl/t/rpl_temporary.test mysql-test/suite/rpl_ndb/r/rpl_ndb_mixed_engines_transactions.result mysql-test/suite/rpl_ndb/r/rpl_ndb_row_implicit_commit_binlog.result mysql-test/suite/rpl_ndb/r/rpl_truncate_7ndb.result mysql-test/suite/rpl_ndb/t/rpl_ndb_mixed_engines_transactions.test mysql-test/suite/rpl_ndb/t/rpl_truncate_7ndb.test mysql-test/suite/sys_vars/r/large_files_support_basic.result mysql-test/t/count_distinct.test mysql-test/t/create_select_tmp.test mysql-test/t/ctype_cp932_binlog_stm.test mysql-test/t/disabled.def mysql-test/t/events_1.test mysql-test/t/func_des_encrypt.test mysql-test/t/func_encrypt.test mysql-test/t/func_group.test mysql-test/t/func_misc.test mysql-test/t/innodb_mysql_sync.test mysql-test/t/lock_sync.test mysql-test/t/myisam.test mysql-test/t/mysqlbinlog.test mysql-test/t/openssl_1.test mysql-test/t/show_check.test mysql-test/t/sp-destruct.test mysql-test/t/sp-lock.test mysql-test/t/sp.test mysql-test/t/sp_sync.test mysql-test/t/ssl-big.test mysql-test/t/ssl.test mysql-test/t/ssl_8k_key.test mysql-test/t/ssl_compress.test mysql-test/t/ssl_connect.test mysys/typelib.c plugin/audit_null/audit_null.c scripts/CMakeLists.txt scripts/make_win_bin_dist scripts/mysql_system_tables.sql scripts/mysql_system_tables_fix.sql sql-common/client.c sql/CMakeLists.txt sql/Makefile.am sql/event_db_repository.cc sql/event_scheduler.cc sql/handler.cc sql/item.cc sql/item.h sql/item_create.cc sql/item_strfunc.cc sql/item_strfunc.h sql/item_sum.cc sql/item_sum.h sql/log.cc sql/log.h sql/log_event.cc sql/log_event_old.cc sql/mdl.h sql/mysqld.cc sql/share/errmsg-utf8.txt sql/sp.cc sql/sp_head.cc sql/sql_acl.cc sql/sql_audit.cc sql/sql_base.cc sql/sql_class.cc sql/sql_class.h sql/sql_connect.cc sql/sql_lex.cc sql/sql_lex.h sql/sql_parse.cc sql/sql_priv.h sql/sql_select.cc sql/sql_show.cc sql/sql_string.cc sql/sql_string.h sql/sql_table.cc sql/sql_update.cc sql/sql_yacc.yy sql/sys_vars.cc sql/table.cc storage/archive/Makefile.am storage/archive/azlib.h storage/blackhole/Makefile.am storage/example/Makefile.am storage/innobase/handler/ha_innodb.cc storage/innobase/handler/i_s.cc storage/innobase/trx/trx0i_s.c storage/myisam/ha_myisam.h storage/perfschema/CMakeLists.txt storage/perfschema/Makefile.am storage/perfschema/ha_perfschema.cc storage/perfschema/ha_perfschema.h storage/perfschema/pfs.cc storage/perfschema/pfs.h storage/perfschema/pfs_atomic.cc storage/perfschema/pfs_atomic.h storage/perfschema/pfs_check.cc storage/perfschema/pfs_column_types.h storage/perfschema/pfs_column_values.cc storage/perfschema/pfs_column_values.h storage/perfschema/pfs_engine_table.cc storage/perfschema/pfs_engine_table.h storage/perfschema/pfs_events_waits.cc storage/perfschema/pfs_events_waits.h storage/perfschema/pfs_global.cc storage/perfschema/pfs_global.h storage/perfschema/pfs_instr.cc storage/perfschema/pfs_instr.h storage/perfschema/pfs_instr_class.cc storage/perfschema/pfs_instr_class.h storage/perfschema/pfs_lock.h storage/perfschema/pfs_server.cc storage/perfschema/pfs_server.h storage/perfschema/pfs_stat.h storage/perfschema/pfs_timer.cc storage/perfschema/pfs_timer.h storage/perfschema/plug.in storage/perfschema/table_all_instr.cc storage/perfschema/table_all_instr.h storage/perfschema/table_events_waits.cc storage/perfschema/table_events_waits.h storage/perfschema/table_events_waits_summary.cc storage/perfschema/table_events_waits_summary.h storage/perfschema/table_file_instances.cc storage/perfschema/table_file_instances.h storage/perfschema/table_file_summary.cc storage/perfschema/table_file_summary.h storage/perfschema/table_performance_timers.cc storage/perfschema/table_performance_timers.h storage/perfschema/table_processlist.cc storage/perfschema/table_processlist.h storage/perfschema/table_setup_consumers.cc storage/perfschema/table_setup_consumers.h storage/perfschema/table_setup_instruments.cc storage/perfschema/table_setup_instruments.h storage/perfschema/table_setup_objects.cc storage/perfschema/table_setup_objects.h storage/perfschema/table_setup_timers.cc storage/perfschema/table_setup_timers.h storage/perfschema/table_sync_instances.cc storage/perfschema/table_sync_instances.h storage/perfschema/unittest/pfs-t.cc storage/perfschema/unittest/pfs_instr-oom-t.cc storage/perfschema/unittest/pfs_instr-t.cc storage/perfschema/unittest/pfs_instr_class-oom-t.cc storage/perfschema/unittest/pfs_instr_class-t.cc support-files/mysql.spec.sh === modified file 'include/mysql/psi/psi.h' --- a/include/mysql/psi/psi.h 2010-01-26 23:42:54 +0000 +++ b/include/mysql/psi/psi.h 2010-05-07 10:08:23 +0000 @@ -600,6 +600,20 @@ typedef void (*set_thread_id_v1_t)(struc */ typedef struct PSI_thread* (*get_thread_v1_t)(void); +typedef void (*set_thread_user_v1_t)(const char *user, int user_len); + +typedef void (*set_thread_host_v1_t)(const char *host, int host_len); + +typedef void (*set_thread_db_v1_t)(const char* db, int db_len); + +typedef void (*set_thread_command_v1_t)(int command); + +typedef void (*set_thread_start_time_v1_t)(time_t start_time); + +typedef void (*set_thread_state_v1_t)(const char* state); + +typedef void (*set_thread_info_v1_t)(const char* info, int info_len); + /** Attach a thread instrumentation to the running thread. In case of thread pools, this method should be called when @@ -889,6 +903,20 @@ struct PSI_v1 set_thread_id_v1_t set_thread_id; /** @sa get_thread_v1_t. */ get_thread_v1_t get_thread; + /** @sa set_thread_user_v1_t. */ + set_thread_user_v1_t set_thread_user; + /** @sa set_thread_host_v1_t. */ + set_thread_host_v1_t set_thread_host; + /** @sa set_thread_db_v1_t. */ + set_thread_db_v1_t set_thread_db; + /** @sa set_thread_command_v1_t. */ + set_thread_command_v1_t set_thread_command; + /** @sa set_thread_start_time_v1_t. */ + set_thread_start_time_v1_t set_thread_start_time; + /** @sa set_thread_state_v1_t. */ + set_thread_state_v1_t set_thread_state; + /** @sa set_thread_info_v1_t. */ + set_thread_info_v1_t set_thread_info; /** @sa set_thread_v1_t. */ set_thread_v1_t set_thread; /** @sa delete_current_thread_v1_t. */ === modified file 'include/mysql/psi/psi_abi_v1.h.pp' --- a/include/mysql/psi/psi_abi_v1.h.pp 2010-01-26 23:42:54 +0000 +++ b/include/mysql/psi/psi_abi_v1.h.pp 2010-05-07 10:08:23 +0000 @@ -125,6 +125,13 @@ typedef struct PSI_thread* (*new_thread_ typedef void (*set_thread_id_v1_t)(struct PSI_thread *thread, unsigned long id); typedef struct PSI_thread* (*get_thread_v1_t)(void); +typedef void (*set_thread_user_v1_t)(const char *user, int user_len); +typedef void (*set_thread_host_v1_t)(const char *host, int host_len); +typedef void (*set_thread_db_v1_t)(const char* db, int db_len); +typedef void (*set_thread_command_v1_t)(int command); +typedef void (*set_thread_start_time_v1_t)(time_t start_time); +typedef void (*set_thread_state_v1_t)(const char* state); +typedef void (*set_thread_info_v1_t)(const char* info, int info_len); typedef void (*set_thread_v1_t)(struct PSI_thread *thread); typedef void (*delete_current_thread_v1_t)(void); typedef void (*delete_thread_v1_t)(struct PSI_thread *thread); @@ -203,6 +210,13 @@ struct PSI_v1 new_thread_v1_t new_thread; set_thread_id_v1_t set_thread_id; get_thread_v1_t get_thread; + set_thread_user_v1_t set_thread_user; + set_thread_host_v1_t set_thread_host; + set_thread_db_v1_t set_thread_db; + set_thread_command_v1_t set_thread_command; + set_thread_start_time_v1_t set_thread_start_time; + set_thread_state_v1_t set_thread_state; + set_thread_info_v1_t set_thread_info; set_thread_v1_t set_thread; delete_current_thread_v1_t delete_current_thread; delete_thread_v1_t delete_thread; === modified file 'libmysqld/lib_sql.cc' --- a/libmysqld/lib_sql.cc 2010-04-13 15:04:45 +0000 +++ b/libmysqld/lib_sql.cc 2010-05-07 10:08:23 +0000 @@ -633,7 +633,7 @@ void *create_embedded_thd(int client_fla if (thd->variables.max_join_size == HA_POS_ERROR) thd->variables.option_bits |= OPTION_BIG_SELECTS; thd->proc_info=0; // Remove 'login' - thd->command=COM_SLEEP; + thd->set_command(COM_SLEEP); thd->version=refresh_version; thd->set_time(); thd->init_for_queries(); === modified file 'sql/event_scheduler.cc' --- a/sql/event_scheduler.cc 2010-04-20 08:51:50 +0000 +++ b/sql/event_scheduler.cc 2010-05-07 10:08:23 +0000 @@ -398,7 +398,7 @@ Event_scheduler::start() } pre_init_event_thread(new_thd); new_thd->system_thread= SYSTEM_THREAD_EVENT_SCHEDULER; - new_thd->command= COM_DAEMON; + new_thd->set_command(COM_DAEMON); /* We should run the event scheduler thread under the super-user privileges. === modified file 'sql/ha_ndbcluster_binlog.cc' --- a/sql/ha_ndbcluster_binlog.cc 2010-03-31 14:05:33 +0000 +++ b/sql/ha_ndbcluster_binlog.cc 2010-05-07 10:08:23 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2000-2003 MySQL AB, 2008-2009 Sun Microsystems, Inc +/* Copyright (c) 2000, 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 @@ -3674,7 +3674,7 @@ pthread_handler_t ndb_binlog_thread_func } thd->init_for_queries(); - thd->command= COM_DAEMON; + thd->set_command(COM_DAEMON); thd->system_thread= SYSTEM_THREAD_NDBCLUSTER_BINLOG; thd->version= refresh_version; thd->main_security_ctx.host_or_ip= ""; === modified file 'sql/log.cc' --- a/sql/log.cc 2010-04-20 11:58:28 +0000 +++ b/sql/log.cc 2010-05-07 10:08:23 +0000 @@ -1,4 +1,4 @@ -/* Copyright 2000-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc. +/* Copyright (c) 2000, 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 @@ -1133,8 +1133,8 @@ bool LOGGER::slow_log_print(THD *thd, co if (!query) { is_command= TRUE; - query= command_name[thd->command].str; - query_length= command_name[thd->command].length; + query= command_name[thd->get_command()].str; + query_length= command_name[thd->get_command()].length; } for (current_handler= slow_log_handler_list; *current_handler ;) === modified file 'sql/sql_class.cc' --- a/sql/sql_class.cc 2010-04-26 09:06:35 +0000 +++ b/sql/sql_class.cc 2010-05-07 10:08:23 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2000-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc. +/* Copyright (c) 2000, 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 @@ -276,6 +276,10 @@ const char *set_thd_proc_info(THD *thd, thd->profiling.status_change(info, calling_function, calling_file, calling_line); #endif thd->proc_info= info; +#ifdef HAVE_PSI_INTERFACE + if (PSI_server) + PSI_server->set_thread_state(info); +#endif return old_info; } @@ -556,7 +560,7 @@ THD::THD() where= THD::DEFAULT_WHERE; server_id = ::server_id; slave_net = 0; - command=COM_CONNECT; + set_command(COM_CONNECT); *scramble= '\0'; /* Call to init() below requires fully initialized Open_tables_state. */ @@ -3295,6 +3299,16 @@ void THD::set_statement(Statement *stmt) } +void THD::set_command(enum enum_server_command command) +{ + m_command= command; +#ifdef HAVE_PSI_INTERFACE + if (PSI_server) + PSI_server->set_thread_command(m_command); +#endif +} + + /** Assign a new value to thd->query. */ void THD::set_query(char *query_arg, uint32 query_length_arg) @@ -3302,6 +3316,11 @@ void THD::set_query(char *query_arg, uin mysql_mutex_lock(&LOCK_thd_data); set_query_inner(query_arg, query_length_arg); mysql_mutex_unlock(&LOCK_thd_data); + +#ifdef HAVE_PSI_INTERFACE + if (PSI_server) + PSI_server->set_thread_info(query_arg, query_length_arg); +#endif } /** Assign a new value to thd->query and thd->query_id. */ === modified file 'sql/sql_class.h' --- a/sql/sql_class.h 2010-04-26 09:06:35 +0000 +++ b/sql/sql_class.h 2010-05-07 10:08:23 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2000-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc. +/* Copyright (c) 2000, 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 @@ -1648,11 +1648,15 @@ public: uint dbug_sentry; // watch out for memory corruption #endif struct st_my_thread_var *mysys_var; - /* - Type of current query: COM_STMT_PREPARE, COM_QUERY, etc. Set from - first byte of the packet in do_command() + +private: + /** + Type of current query: COM_STMT_PREPARE, COM_QUERY, etc. + Set from first byte of the packet in do_command() */ - enum enum_server_command command; + enum enum_server_command m_command; + +public: uint32 server_id; uint32 file_id; // for LOAD DATA INFILE /* remote (peer) port */ @@ -2296,12 +2300,28 @@ public: } else start_utime= utime_after_lock= my_micro_time_and_time(&start_time); + +#ifdef HAVE_PSI_INTERFACE + if (PSI_server) + PSI_server->set_thread_start_time(start_time); +#endif } - inline void set_current_time() { start_time= my_time(MY_WME); } - inline void set_time(time_t t) + inline void set_current_time() + { + start_time= my_time(MY_WME); +#ifdef HAVE_PSI_INTERFACE + if (PSI_server) + PSI_server->set_thread_start_time(start_time); +#endif + } + inline void set_time(time_t t) { start_time= user_time= t; start_utime= utime_after_lock= my_micro_time(); +#ifdef HAVE_PSI_INTERFACE + if (PSI_server) + PSI_server->set_thread_start_time(start_time); +#endif } void set_time_after_lock() { utime_after_lock= my_micro_time(); } ulonglong current_utime() { return my_micro_time(); } @@ -2569,6 +2589,7 @@ public: */ bool set_db(const char *new_db, size_t new_db_len) { + bool result; /* Do not reallocate memory if current chunk is big enough. */ if (db && new_db && db_length >= new_db_len) memcpy(db, new_db, new_db_len+1); @@ -2581,7 +2602,12 @@ public: db= NULL; } db_length= db ? new_db_len : 0; - return new_db && !db; + result= new_db && !db; +#ifdef HAVE_PSI_INTERFACE + if (result && PSI_server) + PSI_server->set_thread_db(new_db, new_db_len); +#endif + return result; } /** @@ -2599,6 +2625,10 @@ public: { db= new_db; db_length= new_db_len; +#ifdef HAVE_PSI_INTERFACE + if (PSI_server) + PSI_server->set_thread_db(new_db, new_db_len); +#endif } /* Copy the current database to the argument. Use the current arena to @@ -2733,6 +2763,11 @@ public: /** Overloaded to guard query/query_length fields */ virtual void set_statement(Statement *stmt); + void set_command(enum enum_server_command command); + + inline enum enum_server_command get_command() const + { return m_command; } + /** Assign a new value to thd->query and thd->query_id. Protected with LOCK_thd_data mutex. === modified file 'sql/sql_connect.cc' --- a/sql/sql_connect.cc 2010-04-13 15:04:45 +0000 +++ b/sql/sql_connect.cc 2010-05-07 10:08:23 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2007 MySQL AB, 2008-2009 Sun Microsystems, Inc +/* Copyright (c) 2007, 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 @@ -15,7 +15,7 @@ /* - Functions to autenticate and handle reqests for a connection + Functions to authenticate and handle requests for a connection */ #include "my_global.h" @@ -496,6 +496,15 @@ check_user(THD *thd, enum enum_server_co } my_ok(thd); thd->password= test(passwd_len); // remember for error messages +#ifdef HAVE_PSI_INTERFACE + if (PSI_server) + { + PSI_server->set_thread_host(thd->main_security_ctx.host_or_ip, + strlen(thd->main_security_ctx.host_or_ip)); + PSI_server->set_thread_user(thd->main_security_ctx.user, + strlen(thd->main_security_ctx.user)); + } +#endif /* Ready to handle queries */ DBUG_RETURN(0); } @@ -1078,7 +1087,7 @@ static void prepare_new_connection_state */ thd->version= refresh_version; thd->proc_info= 0; - thd->command= COM_SLEEP; + thd->set_command(COM_SLEEP); thd->set_time(); thd->init_for_queries(); === modified file 'sql/sql_insert.cc' --- a/sql/sql_insert.cc 2010-04-07 12:02:19 +0000 +++ b/sql/sql_insert.cc 2010-05-07 10:08:23 +0000 @@ -1816,7 +1816,7 @@ public: thd.security_ctx->host=(char*) my_localhost; thd.current_tablenr=0; thd.version=refresh_version; - thd.command=COM_DELAYED_INSERT; + thd.set_command(COM_DELAYED_INSERT); thd.lex->current_select= 0; // for my_message_sql thd.lex->sql_command= SQLCOM_INSERT; // For innodb::store_lock() /* === modified file 'sql/sql_parse.cc' --- a/sql/sql_parse.cc 2010-04-26 09:06:35 +0000 +++ b/sql/sql_parse.cc 2010-05-07 10:08:23 +0000 @@ -882,7 +882,7 @@ bool dispatch_command(enum enum_server_c thd->security_ctx->priv_user, (char *) thd->security_ctx->host_or_ip); - thd->command=command; + thd->set_command(command); /* Commands which always take a long time are logged into the slow log only if opt_log_slow_admin_statements is set. @@ -1457,7 +1457,7 @@ bool dispatch_command(enum enum_server_c thd_proc_info(thd, "cleaning up"); thd->set_query(NULL, 0); - thd->command=COM_SLEEP; + thd->set_command(COM_SLEEP); dec_thread_running(); thd_proc_info(thd, 0); thd->packet.shrink(thd->variables.net_buffer_length); // Reclaim some memory @@ -6880,7 +6880,7 @@ uint kill_one_thread(THD *thd, ulong id, I_List_iterator it(threads); while ((tmp=it++)) { - if (tmp->command == COM_DAEMON) + if (tmp->get_command() == COM_DAEMON) continue; if (tmp->thread_id == id) { === modified file 'sql/sql_prepare.cc' --- a/sql/sql_prepare.cc 2010-04-07 11:58:40 +0000 +++ b/sql/sql_prepare.cc 2010-05-07 10:08:23 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 1995-2002 MySQL AB, 2008-2009 Sun Microsystems, Inc +/* Copyright (c) 1995, 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 @@ -2700,7 +2700,7 @@ void mysqld_stmt_reset(THD *thd, char *p stmt->state= Query_arena::PREPARED; - general_log_print(thd, thd->command, NullS); + general_log_print(thd, thd->get_command(), NullS); my_ok(thd); @@ -2733,7 +2733,7 @@ void mysqld_stmt_close(THD *thd, char *p */ DBUG_ASSERT(! stmt->is_in_use()); stmt->deallocate(); - general_log_print(thd, thd->command, NullS); + general_log_print(thd, thd->get_command(), NullS); DBUG_VOID_RETURN; } @@ -2837,7 +2837,7 @@ void mysql_stmt_get_longdata(THD *thd, c sprintf(stmt->last_error, ER(ER_OUTOFMEMORY), 0); } - general_log_print(thd, thd->command, NullS); + general_log_print(thd, thd->get_command(), NullS); DBUG_VOID_RETURN; } === modified file 'sql/sql_repl.cc' --- a/sql/sql_repl.cc 2010-04-01 19:34:09 +0000 +++ b/sql/sql_repl.cc 2010-05-07 10:08:23 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2000-2006 MySQL AB & Sasha, 2008-2009 Sun Microsystems, Inc +/* Copyright (c) 2000, 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 @@ -1308,7 +1308,7 @@ void kill_zombie_dump_threads(uint32 sla while ((tmp=it++)) { - if (tmp->command == COM_BINLOG_DUMP && + if (tmp->get_command() == COM_BINLOG_DUMP && tmp->server_id == slave_server_id) { mysql_mutex_lock(&tmp->LOCK_thd_data); // Lock from delete === modified file 'sql/sql_show.cc' --- a/sql/sql_show.cc 2010-04-21 07:35:37 +0000 +++ b/sql/sql_show.cc 2010-05-07 10:08:23 +0000 @@ -1714,7 +1714,7 @@ static const char *thread_state_info(THD { if (tmp->net.reading_or_writing == 2) return "Writing to net"; - else if (tmp->command == COM_SLEEP) + else if (tmp->get_command() == COM_SLEEP) return ""; else return "Reading from net"; @@ -1788,7 +1788,7 @@ void mysqld_list_processes(THD *thd,cons tmp_sctx->host ? tmp_sctx->host : ""); if ((thd_info->db=tmp->db)) // Safe test thd_info->db=thd->strdup(thd_info->db); - thd_info->command=(int) tmp->command; + thd_info->command=(int) tmp->get_command(); if ((mysys_var= tmp->mysys_var)) mysql_mutex_lock(&mysys_var->mutex); thd_info->proc_info= (char*) (tmp->killed == THD::KILL_CONNECTION? "Killed" : 0); @@ -1898,8 +1898,8 @@ int fill_schema_processlist(THD* thd, TA if ((val= (char *) (tmp->killed == THD::KILL_CONNECTION? "Killed" : 0))) table->field[4]->store(val, strlen(val), cs); else - table->field[4]->store(command_name[tmp->command].str, - command_name[tmp->command].length, cs); + table->field[4]->store(command_name[tmp->get_command()].str, + command_name[tmp->get_command()].length, cs); /* MYSQL_TIME */ table->field[5]->store((longlong)(tmp->start_time ? now - tmp->start_time : 0), FALSE); === modified file 'storage/perfschema/CMakeLists.txt' --- a/storage/perfschema/CMakeLists.txt 2010-04-19 12:26:29 +0000 +++ b/storage/perfschema/CMakeLists.txt 2010-05-07 10:08:23 +0000 @@ -33,6 +33,7 @@ SET(PERFSCHEMA_SOURCES ha_perfschema.h pfs_lock.h pfs_atomic.h pfs_server.h + pfs_setup_actor.h pfs_stat.h pfs_engine_table.h pfs_timer.h @@ -56,6 +57,7 @@ SET(PERFSCHEMA_SOURCES ha_perfschema.h pfs_instr.cc pfs_instr_class.cc pfs_server.cc + pfs_setup_actor.cc pfs_engine_table.cc pfs_timer.cc table_all_instr.cc === modified file 'storage/perfschema/Makefile.am' --- a/storage/perfschema/Makefile.am 2010-04-19 12:26:29 +0000 +++ b/storage/perfschema/Makefile.am 2010-05-07 10:08:23 +0000 @@ -44,7 +44,8 @@ noinst_HEADERS = ha_perfschema.h pfs_eng table_events_waits_summary.h pfs_stat.h \ table_all_instr.h \ table_file_instances.h table_file_summary.h \ - table_setup_objects.h pfs_lock.h pfs_atomic.h + table_setup_objects.h pfs_lock.h pfs_atomic.h \ + pfs_setup_actor.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 \ @@ -57,7 +58,8 @@ PSE_SOURCES = ha_perfschema.cc pfs_engin table_events_waits_summary.cc \ table_all_instr.cc \ table_file_instances.cc table_file_summary.cc \ - table_setup_objects.cc pfs_atomic.cc pfs_check.cc + table_setup_objects.cc pfs_atomic.cc pfs_check.cc \ + pfs_setup_actor.cc EXTRA_LIBRARIES = libperfschema.a noinst_LIBRARIES = @plugin_perfschema_static_target@ === modified file 'storage/perfschema/pfs.cc' --- a/storage/perfschema/pfs.cc 2010-04-19 12:26:29 +0000 +++ b/storage/perfschema/pfs.cc 2010-05-07 10:08:23 +0000 @@ -26,6 +26,7 @@ #include "pfs_column_values.h" #include "pfs_timer.h" #include "pfs_events_waits.h" +#include "pfs_setup_actor.h" /* Pending WL#4895 PERFORMANCE_SCHEMA Instrumenting Table IO */ #undef HAVE_TABLE_WAIT @@ -1065,6 +1066,134 @@ get_thread_v1(void) return reinterpret_cast (pfs); } +static void set_thread_user_v1(const char *user, int user_len) +{ + PFS_thread *pfs= my_pthread_getspecific_ptr(PFS_thread*, THR_PFS); + + DBUG_ASSERT((user != NULL) || (user_len == 0)); + DBUG_ASSERT(user_len >= 0); + DBUG_ASSERT((uint) user_len <= sizeof(pfs->m_username)); + + if (unlikely(pfs == NULL)) + return; + + pfs->m_lock.allocated_to_dirty(); + if (user_len > 0) + memcpy(pfs->m_username, user, user_len); + pfs->m_username_length= user_len; + + bool enabled= false; + + if ((pfs->m_username_length > 0) && (pfs->m_hostname_length > 0)) + { + /* + TODO: performance improvement. + Once performance_schema.USERS is exposed, + we can use PFS_user::m_enabled instead of looking up + SETUP_ACTORS every time. + */ + lookup_setup_actor(pfs, + pfs->m_username, pfs->m_username_length, + pfs->m_hostname, pfs->m_hostname_length, + &enabled); + } + + pfs->m_enabled= enabled; + + pfs->m_lock.dirty_to_allocated(); +} + +static void set_thread_host_v1(const char *host, int host_len) +{ + PFS_thread *pfs= my_pthread_getspecific_ptr(PFS_thread*, THR_PFS); + + DBUG_ASSERT((host != NULL) || (host_len == 0)); + DBUG_ASSERT(host_len >= 0); + DBUG_ASSERT((uint) host_len <= sizeof(pfs->m_hostname)); + + if (likely(pfs != NULL)) + { + pfs->m_lock.allocated_to_dirty(); + if (host_len > 0) + memcpy(pfs->m_hostname, host, host_len); + pfs->m_hostname_length= host_len; + pfs->m_lock.dirty_to_allocated(); + } +} + +static void set_thread_db_v1(const char* db, int db_len) +{ + PFS_thread *pfs= my_pthread_getspecific_ptr(PFS_thread*, THR_PFS); + + DBUG_ASSERT((db != NULL) || (db_len == 0)); + DBUG_ASSERT(db_len >= 0); + DBUG_ASSERT((uint) db_len <= sizeof(pfs->m_dbname)); + + if (likely(pfs != NULL)) + { + pfs->m_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(); + } +} + +static void set_thread_command_v1(int command) +{ + PFS_thread *pfs= my_pthread_getspecific_ptr(PFS_thread*, THR_PFS); + + DBUG_ASSERT(command >= 0); + DBUG_ASSERT(command <= (int) COM_END); + + if (likely(pfs != NULL)) + { + pfs->m_lock.allocated_to_dirty(); + pfs->m_command= command; + pfs->m_lock.dirty_to_allocated(); + } +} + +static void set_thread_start_time_v1(time_t start_time) +{ + PFS_thread *pfs= my_pthread_getspecific_ptr(PFS_thread*, THR_PFS); + + if (likely(pfs != NULL)) + { + pfs->m_lock.allocated_to_dirty(); + pfs->m_start_time= start_time; + pfs->m_lock.dirty_to_allocated(); + } +} + +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_lock.allocated_to_dirty(); + pfs->m_processlist_state_ptr= state; + pfs->m_processlist_state_length= state_len; + pfs->m_lock.dirty_to_allocated(); + } +} + +static void set_thread_info_v1(const char* info, int info_len) +{ + PFS_thread *pfs= my_pthread_getspecific_ptr(PFS_thread*, THR_PFS); + + if (likely(pfs != NULL)) + { + pfs->m_lock.allocated_to_dirty(); + pfs->m_processlist_info_ptr= info; + pfs->m_processlist_info_length= info_len; + pfs->m_lock.dirty_to_allocated(); + } +} + static void set_thread_v1(PSI_thread* thread) { PFS_thread *pfs= reinterpret_cast (thread); @@ -2012,6 +2141,13 @@ PSI_v1 PFS_v1= new_thread_v1, set_thread_id_v1, get_thread_v1, + set_thread_user_v1, + set_thread_host_v1, + set_thread_db_v1, + set_thread_command_v1, + set_thread_start_time_v1, + set_thread_state_v1, + set_thread_info_v1, set_thread_v1, delete_current_thread_v1, delete_thread_v1, === modified file 'storage/perfschema/pfs_instr.cc' --- a/storage/perfschema/pfs_instr.cc 2010-04-13 09:49:50 +0000 +++ b/storage/perfschema/pfs_instr.cc 2010-05-07 10:08:23 +0000 @@ -23,6 +23,7 @@ #include "my_global.h" #include "sql_priv.h" #include "my_sys.h" +#include "pfs.h" #include "pfs_stat.h" #include "pfs_instr.h" #include "pfs_global.h" @@ -687,6 +688,12 @@ void destroy_cond(PFS_cond *pfs) pfs->m_lock.allocated_to_free(); } +PFS_thread* PFS_thread::get_current_thread() +{ + PFS_thread *pfs= my_pthread_getspecific_ptr(PFS_thread*, THR_PFS); + return pfs; +} + /** Create instrumentation for a thread instance. @param klass the thread class @@ -730,6 +737,16 @@ PFS_thread* create_thread(PFS_thread_cla reset_single_stat_link(stat); pfs->m_filename_hash_pins= NULL; pfs->m_table_share_hash_pins= NULL; + pfs->m_setup_actor_hash_pins= NULL; + + pfs->m_username_length= 0; + pfs->m_hostname_length= 0; + pfs->m_dbname_length= 0; + pfs->m_command= 0; /* FIXME: revise this */ + pfs->m_start_time= 0; + pfs->m_processlist_state_length= 0; + pfs->m_processlist_info_length= 0; + pfs->m_lock.dirty_to_allocated(); return pfs; } === modified file 'storage/perfschema/pfs_instr.h' --- a/storage/perfschema/pfs_instr.h 2010-04-19 12:26:29 +0000 +++ b/storage/perfschema/pfs_instr.h 2010-05-07 10:08:23 +0000 @@ -181,12 +181,16 @@ private: /** Instrumented thread implementation. @see PSI_thread. */ struct PFS_thread { + static PFS_thread* get_current_thread(void); + /** Internal lock. */ pfs_lock m_lock; /** Pins for filename_hash. */ LF_PINS *m_filename_hash_pins; /** Pins for table_share_hash. */ LF_PINS *m_table_share_hash_pins; + /** Pins for setup_actor_hash. */ + LF_PINS *m_setup_actor_hash_pins; /** Event ID counter */ ulonglong m_event_id; /** Thread instrumentation flag. */ @@ -225,6 +229,19 @@ struct PFS_thread PERFORMANCE_SCHEMA.EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME. */ PFS_single_stat_chain *m_instr_class_wait_stats; + + char m_username[USERNAME_LENGTH]; + uint m_username_length; + char m_hostname[HOSTNAME_LENGTH]; + uint m_hostname_length; + char m_dbname[NAME_LEN]; + uint m_dbname_length; + int m_command; + time_t m_start_time; + const char *m_processlist_state_ptr; + uint m_processlist_state_length; + const char *m_processlist_info_ptr; + uint m_processlist_info_length; }; PFS_thread *sanitize_thread(PFS_thread *unsafe); === modified file 'storage/perfschema/pfs_lock.h' --- a/storage/perfschema/pfs_lock.h 2010-04-19 12:26:29 +0000 +++ b/storage/perfschema/pfs_lock.h 2010-05-07 10:08:23 +0000 @@ -108,6 +108,17 @@ struct pfs_lock } /** + Execute an allocated to dirty transition. + This transition should be executed by the writer that owns the record, + before the record is modified. + */ + void allocated_to_dirty(void) + { + DBUG_ASSERT(m_state == PFS_LOCK_ALLOCATED); + PFS_atomic::store_32(&m_state, PFS_LOCK_DIRTY); + } + + /** Execute a dirty to allocated transition. This transition should be executed by the writer that owns the record, after the record is in a state ready to be read. === modified file 'storage/perfschema/pfs_server.h' --- a/storage/perfschema/pfs_server.h 2010-04-19 12:26:29 +0000 +++ b/storage/perfschema/pfs_server.h 2010-05-07 10:08:23 +0000 @@ -66,6 +66,9 @@ #ifndef PFS_WAITS_HISTORY_LONG_SIZE #define PFS_WAITS_HISTORY_LONG_SIZE 10000 #endif +#ifndef PFS_MAX_SETUP_ACTOR + #define PFS_MAX_SETUP_ACTOR 100 +#endif struct PFS_global_param { @@ -85,6 +88,7 @@ struct PFS_global_param ulong m_file_handle_sizing; ulong m_events_waits_history_sizing; ulong m_events_waits_history_long_sizing; + ulong m_setup_actor_sizing; }; extern PFS_global_param pfs_param; === added file 'storage/perfschema/pfs_setup_actor.cc' --- a/storage/perfschema/pfs_setup_actor.cc 1970-01-01 00:00:00 +0000 +++ b/storage/perfschema/pfs_setup_actor.cc 2010-05-07 10:08:23 +0000 @@ -0,0 +1,325 @@ +/* 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 */ + +/** + @file storage/perfschema/pfs_setup_actor.cc + Performance schema setup actor (implementation). +*/ + +#include "my_global.h" +#include "my_sys.h" +#include "my_base.h" +#include "pfs.h" +#include "pfs_stat.h" +#include "pfs_instr.h" +#include "pfs_setup_actor.h" +#include "pfs_global.h" + +/** + @addtogroup Performance_schema_buffers + @{ +*/ + +ulong setup_actor_max; + +PFS_setup_actor *setup_actor_array= NULL; + +static LF_HASH setup_actor_hash; +static bool setup_actor_hash_inited= false; + +/** + Initialize the setup actor buffers. + @param param sizing parameters + @return 0 on success +*/ +int init_setup_actor(const PFS_global_param *param) +{ + setup_actor_max= param->m_setup_actor_sizing; + + setup_actor_array= NULL; + + if (setup_actor_max > 0) + { + setup_actor_array= PFS_MALLOC_ARRAY(setup_actor_max, PFS_setup_actor, + MYF(MY_ZEROFILL)); + if (unlikely(setup_actor_array == NULL)) + return 1; + } + + return 0; +} + +/** Cleanup all the setup actor buffers. */ +void cleanup_setup_actor(void) +{ + pfs_free(setup_actor_array); + setup_actor_array= NULL; + setup_actor_max= 0; +} + +static uchar *setup_actor_hash_get_key(const uchar *entry, size_t *length, + my_bool) +{ + const PFS_setup_actor * const *typed_entry; + const PFS_setup_actor *setup_actor; + const void *result; + typed_entry= reinterpret_cast (entry); + DBUG_ASSERT(typed_entry != NULL); + setup_actor= *typed_entry; + DBUG_ASSERT(setup_actor != NULL); + *length= setup_actor->m_key.m_key_length; + result= setup_actor->m_key.m_hash_key; + return const_cast (reinterpret_cast (result)); +} + +/** + Initialize the setup actor hash. + @return 0 on success +*/ +int init_setup_actor_hash(void) +{ + if (! setup_actor_hash_inited) + { + lf_hash_init(&setup_actor_hash, sizeof(PFS_setup_actor*), LF_HASH_UNIQUE, + 0, 0, setup_actor_hash_get_key, &my_charset_bin); + setup_actor_hash_inited= true; + } + return 0; +} + +/** Cleanup the setup actor hash. */ +void cleanup_setup_actor_hash(void) +{ + if (setup_actor_hash_inited) + { + lf_hash_destroy(&setup_actor_hash); + setup_actor_hash_inited= false; + } +} + +static LF_PINS* get_setup_actor_hash_pins(PFS_thread *thread) +{ + if (! setup_actor_hash_inited) + return NULL; + if (unlikely(thread->m_setup_actor_hash_pins == NULL)) + thread->m_setup_actor_hash_pins= lf_hash_get_pins(&setup_actor_hash); + return thread->m_setup_actor_hash_pins; +} + +static void set_setup_actor_key(PFS_setup_actor_key *key, + const char *user, uint user_length, + const char *host, uint host_length, + const char *role, uint role_length) +{ + DBUG_ASSERT(user_length <= USERNAME_LENGTH); + DBUG_ASSERT(host_length <= HOSTNAME_LENGTH); + + char *ptr= &key->m_hash_key[0]; + memcpy(ptr, user, user_length); + ptr+= user_length; + ptr[0]= 0; + ptr++; + memcpy(ptr, host, host_length); + ptr+= host_length; + ptr[0]= 0; + ptr++; + memcpy(ptr, role, role_length); + ptr+= role_length; + ptr[0]= 0; + ptr++; + key->m_key_length= ptr - &key->m_hash_key[0]; +} + +int insert_setup_actor(const String *user, const String *host, const String *role) +{ + if (setup_actor_max == 0) + return HA_ERR_RECORD_FILE_FULL; + + PFS_thread *thread= PFS_thread::get_current_thread(); + if (unlikely(thread == NULL)) + return HA_ERR_OUT_OF_MEM; + + LF_PINS *pins= get_setup_actor_hash_pins(thread); + if (unlikely(pins == NULL)) + return HA_ERR_OUT_OF_MEM; + + /* user is not constant, just using it for noise on insert */ + uint i= randomized_index(user, setup_actor_max); + + /* + Pass 1: [random, setup_actor_max - 1] + Pass 2: [0, setup_actor_max - 1] + */ + int pass; + for (pass= 1; pass <= 2; i=0, pass++) + { + PFS_setup_actor *pfs= setup_actor_array + i; + PFS_setup_actor *pfs_last= setup_actor_array + setup_actor_max; + for ( ; pfs < pfs_last; pfs++) + { + if (pfs->m_lock.is_free()) + { + if (pfs->m_lock.free_to_dirty()) + { + set_setup_actor_key(&pfs->m_key, + user->ptr(), user->length(), + host->ptr(), host->length(), + role->ptr(), role->length()); + pfs->m_username= &pfs->m_key.m_hash_key[0]; + pfs->m_username_length= user->length(); + pfs->m_hostname= pfs->m_username + pfs->m_username_length + 1; + pfs->m_hostname_length= host->length(); + pfs->m_rolename= pfs->m_hostname + pfs->m_hostname_length + 1; + pfs->m_rolename_length= role->length(); + + int res; + res= lf_hash_insert(&setup_actor_hash, pins, &pfs); + if (likely(res == 0)) + { + pfs->m_lock.dirty_to_allocated(); + return 0; + } + + pfs->m_lock.dirty_to_free(); + if (res > 0) + return HA_ERR_FOUND_DUPP_KEY; + return HA_ERR_OUT_OF_MEM; + } + } + } + } + + return HA_ERR_RECORD_FILE_FULL; +} + +int delete_setup_actor(const String *user, const String *host, const String *role) +{ + PFS_thread *thread= PFS_thread::get_current_thread(); + if (unlikely(thread == NULL)) + return HA_ERR_OUT_OF_MEM; + + LF_PINS* pins= get_setup_actor_hash_pins(thread); + if (unlikely(pins == NULL)) + return HA_ERR_OUT_OF_MEM; + + PFS_setup_actor_key key; + set_setup_actor_key(&key, + user->ptr(), user->length(), + host->ptr(), host->length(), + role->ptr(), role->length()); + + PFS_setup_actor **entry; + entry= reinterpret_cast + (lf_hash_search(&setup_actor_hash, pins, key.m_hash_key, key.m_key_length)); + + if (entry && (entry != MY_ERRPTR)) + { + PFS_setup_actor *pfs= *entry; + lf_hash_delete(&setup_actor_hash, pins, key.m_hash_key, key.m_key_length); + pfs->m_lock.allocated_to_free(); + } + + return 0; +} + +int reset_setup_actor() +{ + PFS_thread *thread= PFS_thread::get_current_thread(); + if (unlikely(thread == NULL)) + return HA_ERR_OUT_OF_MEM; + + LF_PINS* pins= get_setup_actor_hash_pins(thread); + if (unlikely(pins == NULL)) + return HA_ERR_OUT_OF_MEM; + + PFS_setup_actor *pfs= setup_actor_array; + PFS_setup_actor *pfs_last= setup_actor_array + setup_actor_max; + + for ( ; pfs < pfs_last; pfs++) + { + if (pfs->m_lock.is_populated()) + { + lf_hash_delete(&setup_actor_hash, pins, + pfs->m_key.m_hash_key, pfs->m_key.m_key_length); + pfs->m_lock.allocated_to_free(); + } + } + + return 0; +} + +long setup_actor_count() +{ + return setup_actor_hash.count; +} + +/* + - '%' should be replaced by NULL in table SETUP_ACTOR + - add an ENABLED column to include/exclude patterns, more flexible + - the principle is similar to SETUP_OBJECTS +*/ +void lookup_setup_actor(PFS_thread *thread, + const char *user, uint user_length, + const char *host, uint host_length, + bool *enabled) +{ +#ifdef PORTME + PFS_setup_actor_key key; + PFS_setup_actor **entry; + int i; + + LF_PINS* pins= get_setup_actor_hash_pins(thread); + if (unlikely(pins == NULL)) + { + *enabled= false; + return; + } + + for (i= 1; i<=4; i++) + { + /* + WL#988 Roles is not implemented, so we do not have a role name. + Looking up "%" in SETUP_ACTORS.ROLE. + */ + switch(i) + { + case 1: + set_setup_actor_key(&key, user, user_length, host, host_length, "%", 1); + break; + case 2: + set_setup_actor_key(&key, user, user_length, "%", 1, "%", 1); + break; + case 3: + set_setup_actor_key(&key, "%", 1, host, host_length, "%", 1); + break; + case 4: + set_setup_actor_key(&key, "%", 1, "%", 1, "%", 1); + break; + } + entry= reinterpret_cast + (lf_hash_search(&setup_actor_hash, pins, key.m_hash_key, key.m_key_length)); + + if (entry && (entry != MY_ERRPTR)) + { + *enabled= true; + return; + } + } +#endif + *enabled= false; + return; +} + +/** @} */ === added file 'storage/perfschema/pfs_setup_actor.h' --- a/storage/perfschema/pfs_setup_actor.h 1970-01-01 00:00:00 +0000 +++ b/storage/perfschema/pfs_setup_actor.h 2010-05-07 10:08:23 +0000 @@ -0,0 +1,87 @@ +/* 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 */ + +#ifndef PFS_SETUP_ACTOR_H +#define PFS_SETUP_ACTOR_H + +/** + @file storage/perfschema/pfs_setup_actor.h + Performance schema setup actors (declarations). +*/ + +#include "sql_string.h" +#include "pfs_lock.h" +#include "lf.h" + +struct PFS_global_param; + +/* WL#988 Roles Not implemented yet */ +#define ROLENAME_LENGTH 64 + +/** + @addtogroup Performance_schema_buffers + @{ +*/ + +struct PFS_setup_actor_key +{ + /** + Hash search key. + This has to be a string for LF_HASH, + the format is "<0x00><0x00><0x00>" + */ + char m_hash_key[USERNAME_LENGTH + 1 + HOSTNAME_LENGTH + 1 + ROLENAME_LENGTH + 1]; + uint m_key_length; +}; + +struct PFS_setup_actor +{ + /** Internal lock. */ + pfs_lock m_lock; + PFS_setup_actor_key m_key; + const char *m_username; + uint m_username_length; + const char *m_hostname; + uint m_hostname_length; + const char *m_rolename; + uint m_rolename_length; +}; + +int init_setup_actor(const PFS_global_param *param); +void cleanup_setup_actor(void); +int init_setup_actor_hash(void); +void cleanup_setup_actor_hash(void); + +int insert_setup_actor(const String *user, const String *host, const String *role); +int delete_setup_actor(const String *user, const String *host, const String *role); +int reset_setup_actor(void); +long setup_actor_count(void); + +void lookup_setup_actor(PFS_thread *thread, + const char *user, uint user_length, + const char *host, uint host_length, + bool *enabled); + +/* For iterators and show status. */ + +extern ulong setup_actor_max; + +/* Exposing the data directly, for iterators. */ + +extern PFS_setup_actor *setup_actor_array; + +/** @} */ +#endif + === modified file 'storage/perfschema/unittest/stub_pfs_global.h' --- a/storage/perfschema/unittest/stub_pfs_global.h 2010-01-12 01:47:27 +0000 +++ b/storage/perfschema/unittest/stub_pfs_global.h 2010-05-07 10:08:23 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2008-2009 Sun Microsystems, Inc +/* 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 @@ -39,3 +39,7 @@ void pfs_free(void *) { } +void pfs_print_error(const char *format, ...) +{ +} + --Boundary_(ID_Am9jUUmHHwieXkfMiQbxow) MIME-version: 1.0 Content-type: text/bzr-bundle; CHARSET=US-ASCII; name="bzr/marc.alff@stripped" Content-transfer-encoding: 7BIT Content-disposition: inline; filename="bzr/marc.alff@stripped" # Bazaar merge directive format 2 (Bazaar 0.90) # revision_id: marc.alff@stripped # target_branch: file:///Users/malff/BZR_TREE/mysql-next-mr-wl4674/ # testament_sha1: 35e342eb796c6a2a6028e71533f5e6637037049f # timestamp: 2010-05-07 04:09:01 -0600 # source_branch: file:///Users/malff/BZR_TREE/mysql-next-mr/ # base_revision_id: marc.alff@stripped\ # ecfs9tv1al0uotdx # # Begin bundle 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 --Boundary_(ID_Am9jUUmHHwieXkfMiQbxow)--