diff options
author | Michael Widenius <monty@askmonty.org> | 2013-01-23 16:16:14 +0100 |
---|---|---|
committer | Michael Widenius <monty@askmonty.org> | 2013-01-23 16:16:14 +0100 |
commit | a260b155542179bec75a6bbe1e430bea57b70ad6 (patch) | |
tree | 761fdd82f49c9fc557398218a11d089961263ead | |
parent | 09665bfd0e83efbc6c67f14852800fb4a0fe1e13 (diff) | |
download | mariadb-git-a260b155542179bec75a6bbe1e430bea57b70ad6.tar.gz |
MDEV-4011 Added per thread memory counting and usage
Base code and idea from a patch from by plinux at Taobao.
The idea is that we mark all memory that are thread specific with MY_THREAD_SPECIFIC.
Memory counting is done per thread in the my_malloc_size_cb_func callback function from my_malloc().
There are plenty of new asserts to ensure that for a debug server the counting is correct.
Information_schema.processlist gets two new columns: MEMORY_USED and EXAMINED_ROWS.
- The later is there mainly to show how query is progressing.
The following changes in interfaces was needed to get this to work:
- init_alloc_root() amd init_sql_alloc() has extra option so that one can mark memory with MY_THREAD_SPECIFIC
- One now have to use alloc_root_set_min_malloc() to set min memory to be allocated by alloc_root()
- my_init_dynamic_array() has extra option so that one can mark memory with MY_THREAD_SPECIFIC
- my_net_init() has extra option so that one can mark memory with MY_THREAD_SPECIFIC
- Added flag for hash_init() so that one can mark hash table to be thread specific.
- Added flags to init_tree() so that one can mark tree to be thread specific.
- Removed with_delete option to init_tree(). Now one should instead use MY_TREE_WITH_DELETE_FLAG.
- Added flag to Warning_info::Warning_info() if the structure should be fully initialized.
- String elements can now be marked as thread specific.
- Internal HEAP tables are now marking it's memory as MY_THREAD_SPECIFIC.
- Changed type of myf from int to ulong, as this is always a set of bit flags.
Other things:
- Removed calls to net_end() and thd->cleanup() as these are now done in ~THD()
- We now also show EXAMINED_ROWS in SHOW PROCESSLIST
- Added new variable 'memory_used'
- Fixed bug where kill_threads_for_user() was using the wrong mem_root to allocate memory.
- Removed calls to the obsoleted function init_dynamic_array()
- Use set_current_thd() instead of my_pthread_setspecific_ptr(THR_THD,...)
client/completion_hash.cc:
Updated call to init_alloc_root()
client/mysql.cc:
Updated call to init_alloc_root()
client/mysqlbinlog.cc:
init_dynamic_array() -> my_init_dynamic_array()
Updated call to init_alloc_root()
client/mysqlcheck.c:
Updated call to my_init_dynamic_array()
client/mysqldump.c:
Updated call to init_alloc_root()
client/mysqltest.cc:
Updated call to init_alloc_root()
Updated call to my_init_dynamic_array()
Fixed compiler warnings
extra/comp_err.c:
Updated call to my_init_dynamic_array()
extra/resolve_stack_dump.c:
Updated call to my_init_dynamic_array()
include/hash.h:
Added HASH_THREAD_SPECIFIC
include/heap.h:
Added flag is internal temporary table.
include/my_dir.h:
Safety fix: Ensure that MY_DONT_SORT and MY_WANT_STAT don't interfer with other mysys flags
include/my_global.h:
Changed type of myf from int to ulong, as this is always a set of bit flags.
include/my_sys.h:
Added MY_THREAD_SPECIFIC and MY_THREAD_MOVE
Added malloc_flags to DYNAMIC_ARRAY
Added extra mysys flag argument to my_init_dynamic_array()
Removed deprecated functions init_dynamic_array() and my_init_dynamic_array.._ci
Updated paramaters for init_alloc_root()
include/my_tree.h:
Added my_flags to allow one to use MY_THREAD_SPECIFIC with hash tables.
Removed with_delete. One should now instead use MY_TREE_WITH_DELETE_FLAG
Updated parameters to init_tree()
include/myisamchk.h:
Added malloc_flags to allow one to use MY_THREAD_SPECIFIC for checks.
include/mysql.h:
Added MYSQL_THREAD_SPECIFIC_MALLOC
Used 'unused1' to mark memory as thread specific.
include/mysql.h.pp:
Updated file
include/mysql_com.h:
Used 'unused1' to mark memory as thread specific.
Updated parameters for my_net_init()
libmysql/libmysql.c:
Updated call to init_alloc_root() to mark memory thread specific.
libmysqld/emb_qcache.cc:
Updated call to init_alloc_root()
libmysqld/lib_sql.cc:
Updated call to init_alloc_root()
mysql-test/r/create.result:
Updated results
mysql-test/r/user_var.result:
Updated results
mysql-test/suite/funcs_1/datadict/processlist_priv.inc:
Update to handle new format of SHOW PROCESSLIST
mysql-test/suite/funcs_1/datadict/processlist_val.inc:
Update to handle new format of SHOW PROCESSLIST
mysql-test/suite/funcs_1/r/is_columns_is.result:
Update to handle new format of SHOW PROCESSLIST
mysql-test/suite/funcs_1/r/processlist_priv_no_prot.result:
Updated results
mysql-test/suite/funcs_1/r/processlist_val_no_prot.result:
Updated results
mysql-test/t/show_explain.test:
Fixed usage of debug variable so that one can run test with --debug
mysql-test/t/user_var.test:
Added test of memory_usage variable.
mysys/array.c:
Added extra my_flags option to init_dynamic_array() and init_dynamic_array2() so that one can mark memory with MY_THREAD_SPECIFIC
All allocated memory is marked with the given my_flags.
Removed obsolete function init_dynamic_array()
mysys/default.c:
Updated call to init_alloc_root()
Updated call to my_init_dynamic_array()
mysys/hash.c:
Updated call to my_init_dynamic_array_ci().
Allocated memory is marked with MY_THREAD_SPECIFIC if HASH_THREAD_SPECIFIC is used.
mysys/ma_dyncol.c:
init_dynamic_array() -> my_init_dynamic_array()
Added #if to get rid of compiler warnings
mysys/mf_tempdir.c:
Updated call to my_init_dynamic_array()
mysys/my_alloc.c:
Added extra parameter to init_alloc_root() so that one can mark memory with MY_THREAD_SPECIFIC
Extend MEM_ROOT with a flag if memory is thread specific.
This is stored in block_size, to keep the size of the MEM_ROOT object identical as before.
Allocated memory is marked with MY_THREAD_SPECIFIC if used with init_alloc_root()
mysys/my_chmod.c:
Updated DBUG_PRINT because of change of myf type
mysys/my_chsize.c:
Updated DBUG_PRINT because of change of myf type
mysys/my_copy.c:
Updated DBUG_PRINT because of change of myf type
mysys/my_create.c:
Updated DBUG_PRINT because of change of myf type
mysys/my_delete.c:
Updated DBUG_PRINT because of change of myf type
mysys/my_error.c:
Updated DBUG_PRINT because of change of myf type
mysys/my_fopen.c:
Updated DBUG_PRINT because of change of myf type
mysys/my_fstream.c:
Updated DBUG_PRINT because of change of myf type
mysys/my_getwd.c:
Updated DBUG_PRINT because of change of myf type
mysys/my_lib.c:
Updated call to init_alloc_root()
Updated call to my_init_dynamic_array()
Updated DBUG_PRINT because of change of myf type
mysys/my_lock.c:
Updated DBUG_PRINT because of change of myf type
mysys/my_malloc.c:
Store at start of each allocated memory block the size of the block and if the block is thread specific.
Call malloc_size_cb_func, if set, with the memory allocated/freed.
Updated DBUG_PRINT because of change of myf type
mysys/my_open.c:
Updated DBUG_PRINT because of change of myf type
mysys/my_pread.c:
Updated DBUG_PRINT because of change of myf type
mysys/my_read.c:
Updated DBUG_PRINT because of change of myf type
mysys/my_redel.c:
Updated DBUG_PRINT because of change of myf type
mysys/my_rename.c:
Updated DBUG_PRINT because of change of myf type
mysys/my_seek.c:
Updated DBUG_PRINT because of change of myf type
mysys/my_sync.c:
Updated DBUG_PRINT because of change of myf type
mysys/my_thr_init.c:
Ensure that one can call my_thread_dbug_id() even if thread is not properly initialized.
mysys/my_write.c:
Updated DBUG_PRINT because of change of myf type
mysys/mysys_priv.h:
Updated parameters to sf_malloc and sf_realloc()
mysys/safemalloc.c:
Added checking that for memory marked with MY_THREAD_SPECIFIC that it's the same thread that is allocation and freeing the memory.
Added sf_malloc_dbug_id() to allow MariaDB to specify which THD is handling the memory.
Added my_flags arguments to sf_malloc() and sf_realloc() to be able to mark memory with MY_THREAD_SPECIFIC.
Added sf_report_leaked_memory() to get list of memory not freed by a thread.
mysys/tree.c:
Added flags to init_tree() so that one can mark tree to be thread specific.
Removed with_delete option to init_tree(). Now one should instead use MY_TREE_WITH_DELETE_FLAG.
Updated call to init_alloc_root()
All allocated memory is marked with the given malloc flags
mysys/waiting_threads.c:
Updated call to my_init_dynamic_array()
sql-common/client.c:
Updated call to init_alloc_root() and my_net_init() to mark memory thread specific.
Updated call to my_init_dynamic_array().
Added MYSQL_THREAD_SPECIFIC_MALLOC so that client can mark memory as MY_THREAD_SPECIFIC.
sql-common/client_plugin.c:
Updated call to init_alloc_root()
sql/debug_sync.cc:
Added MY_THREAD_SPECIFIC to allocated memory.
sql/event_scheduler.cc:
Removed calls to net_end() as this is now done in ~THD()
Call set_current_thd() to ensure that memory is assigned to right thread.
sql/events.cc:
my_pthread_setspecific_ptr(THR_THD,...) -> set_current_thd()
sql/filesort.cc:
Added MY_THREAD_SPECIFIC to allocated memory.
sql/filesort_utils.cc:
Added MY_THREAD_SPECIFIC to allocated memory.
sql/ha_ndbcluster.cc:
Updated call to init_alloc_root()
Updated call to my_net_init()
Removed calls to net_end() and thd->cleanup() as these are now done in ~THD()
sql/ha_ndbcluster_binlog.cc:
Updated call to my_net_init()
Updated call to init_sql_alloc()
Removed calls to net_end() and thd->cleanup() as these are now done in ~THD()
sql/ha_partition.cc:
Updated call to init_alloc_root()
sql/handler.cc:
Added MY_THREAD_SPECIFIC to allocated memory.
Added missing call to my_dir_end()
sql/item_func.cc:
Added MY_THREAD_SPECIFIC to allocated memory.
sql/item_subselect.cc:
Added MY_THREAD_SPECIFIC to allocated memory.
sql/item_sum.cc:
Added MY_THREAD_SPECIFIC to allocated memory.
sql/log.cc:
More DBUG
Updated call to init_alloc_root()
sql/mdl.cc:
Added MY_THREAD_SPECIFIC to allocated memory.
sql/mysqld.cc:
Added total_memory_used
Updated call to init_alloc_root()
Move mysql_cond_broadcast() before my_thread_end()
Added mariadb_dbug_id() to count memory per THD instead of per thread.
Added my_malloc_size_cb_func() callback function for my_malloc() to count memory.
Move initialization of mysqld_server_started and mysqld_server_initialized earlier.
Updated call to my_init_dynamic_array().
Updated call to my_net_init().
Call my_pthread_setspecific_ptr(THR_THD,...) to ensure that memory is assigned to right thread.
Added status variable 'memory_used'.
Updated call to init_alloc_root()
my_pthread_setspecific_ptr(THR_THD,...) -> set_current_thd()
sql/mysqld.h:
Added set_current_thd()
sql/net_serv.cc:
Added new parameter to my_net_init() so that one can mark memory with MY_THREAD_SPECIFIC.
Store in net->thread_specific_malloc if memory is thread specific.
Mark memory to be thread specific if requested.
sql/opt_range.cc:
Updated call to my_init_dynamic_array()
Updated call to init_sql_alloc()
Added MY_THREAD_SPECIFIC to allocated memory.
sql/opt_subselect.cc:
Updated call to init_sql_alloc() to mark memory thread specific.
sql/protocol.cc:
Fixed compiler warning
sql/records.cc:
Added MY_THREAD_SPECIFIC to allocated memory.
sql/rpl_filter.cc:
Updated call to my_init_dynamic_array()
sql/rpl_handler.cc:
Updated call to my_init_dynamic_array2()
sql/rpl_handler.h:
Updated call to init_sql_alloc()
sql/rpl_mi.cc:
Updated call to my_init_dynamic_array()
sql/rpl_tblmap.cc:
Updated call to init_alloc_root()
sql/rpl_utility.cc:
Updated call to my_init_dynamic_array()
sql/slave.cc:
Initialize things properly before calling functions that allocate memory.
Removed calls to net_end() as this is now done in ~THD()
sql/sp_head.cc:
Updated call to init_sql_alloc()
Updated call to my_init_dynamic_array()
Added parameter to warning_info() that it should be fully initialized.
sql/sp_pcontext.cc:
Updated call to my_init_dynamic_array()
sql/sql_acl.cc:
Updated call to init_sql_alloc()
Updated call to my_init_dynamic_array()
my_pthread_setspecific_ptr(THR_THD,...) -> set_current_thd()
sql/sql_admin.cc:
Added parameter to warning_info() that it should be fully initialized.
sql/sql_analyse.h:
Updated call to init_tree() to mark memory thread specific.
sql/sql_array.h:
Updated call to my_init_dynamic_array() to mark memory thread specific.
sql/sql_audit.cc:
Updated call to my_init_dynamic_array()
sql/sql_base.cc:
Updated call to init_sql_alloc()
my_pthread_setspecific_ptr(THR_THD,...) -> set_current_thd()
sql/sql_cache.cc:
Updated comment
sql/sql_class.cc:
Added parameter to warning_info() that not initialize it until THD is fully created.
Updated call to init_sql_alloc()
Mark THD::user_vars has to be thread specific.
Updated call to my_init_dynamic_array()
Ensure that memory allocated by THD is assigned to the THD.
More DBUG
Always acll net_end() in ~THD()
Assert that all memory signed to this THD is really deleted at ~THD.
Fixed set_status_var_init() to not reset memory_used.
my_pthread_setspecific_ptr(THR_THD,...) -> set_current_thd()
sql/sql_class.h:
Added MY_THREAD_SPECIFIC to allocated memory.
Added malloc_size to THD to record allocated memory per THD.
sql/sql_delete.cc:
Added MY_THREAD_SPECIFIC to allocated memory.
sql/sql_error.cc:
Added 'initialize' parameter to Warning_info() to say if should allocate memory for it's structures.
This is used by THD::THD() to not allocate memory until THD is ready.
Added Warning_info::free_memory()
sql/sql_error.h:
Updated Warning_info() class.
sql/sql_handler.cc:
Updated call to init_alloc_root() to mark memory thread specific.
sql/sql_insert.cc:
More DBUG
sql/sql_join_cache.cc:
Added MY_THREAD_SPECIFIC to allocated memory.
sql/sql_lex.cc:
Updated call to my_init_dynamic_array()
sql/sql_lex.h:
Updated call to my_init_dynamic_array()
sql/sql_load.cc:
Added MY_THREAD_SPECIFIC to allocated memory.
sql/sql_parse.cc:
Removed calls to net_end() and thd->cleanup() as these are now done in ~THD()
Ensure that examined_row_count() is reset before query.
Fixed bug where kill_threads_for_user() was using the wrong mem_root to allocate memory.
my_pthread_setspecific_ptr(THR_THD,...) -> set_current_thd()
Don't restore thd->status_var.memory_used when restoring thd->status_var
sql/sql_plugin.cc:
Updated call to init_alloc_root()
Updated call to my_init_dynamic_array()
Don't allocate THD on the stack, as this causes problems with valgrind when doing thd memory counting.
my_pthread_setspecific_ptr(THR_THD,...) -> set_current_thd()
sql/sql_prepare.cc:
Added parameter to warning_info() that it should be fully initialized.
Updated call to init_sql_alloc() to mark memory thread specific.
sql/sql_reload.cc:
my_pthread_setspecific_ptr(THR_THD,...) -> set_current_thd()
sql/sql_select.cc:
Updated call to my_init_dynamic_array() and init_sql_alloc() to mark memory thread specific.
Added MY_THREAD_SPECIFIC to allocated memory.
More DBUG
sql/sql_servers.cc:
Updated call to init_sql_alloc() to mark memory some memory thread specific.
my_pthread_setspecific_ptr(THR_THD,...) -> set_current_thd()
sql/sql_show.cc:
Updated call to my_init_dynamic_array()
Mark my_dir() memory thread specific.
Use my_pthread_setspecific_ptr(THR_THD,...) to mark that allocated memory should be allocated to calling thread.
More DBUG.
Added malloc_size and examined_row_count to SHOW PROCESSLIST.
Added MY_THREAD_SPECIFIC to allocated memory.
Updated call to init_sql_alloc()
Added parameter to warning_info() that it should be fully initialized.
sql/sql_statistics.cc:
Fixed compiler warning
sql/sql_string.cc:
String elements can now be marked as thread specific.
sql/sql_string.h:
String elements can now be marked as thread specific.
sql/sql_table.cc:
Updated call to init_sql_alloc() and my_malloc() to mark memory thread specific
my_pthread_setspecific_ptr(THR_THD,...) -> set_current_thd()
Fixed compiler warning
sql/sql_test.cc:
Updated call to my_init_dynamic_array() to mark memory thread specific.
sql/sql_trigger.cc:
Updated call to init_sql_alloc()
sql/sql_udf.cc:
Updated call to init_sql_alloc()
my_pthread_setspecific_ptr(THR_THD,...) -> set_current_thd()
sql/sql_update.cc:
Added MY_THREAD_SPECIFIC to allocated memory.
sql/table.cc:
Updated call to init_sql_alloc().
Mark memory used by temporary tables, that are not for slave threads, as MY_THREAD_SPECIFIC
Updated call to init_sql_alloc()
sql/thr_malloc.cc:
Added my_flags argument to init_sql_alloc() to be able to mark memory as MY_THREAD_SPECIFIC.
sql/thr_malloc.h:
Updated prototype for init_sql_alloc()
sql/tztime.cc:
Updated call to init_sql_alloc()
Updated call to init_alloc_root() to mark memory thread specific.
my_pthread_setspecific_ptr(THR_THD,...) -> set_current_thd()
sql/uniques.cc:
Updated calls to init_tree(), my_init_dynamic_array() and my_malloc() to mark memory thread specific.
sql/unireg.cc:
Added MY_THREAD_SPECIFIC to allocated memory.
storage/csv/ha_tina.cc:
Updated call to init_alloc_root()
storage/federated/ha_federated.cc:
Updated call to init_alloc_root()
Updated call to my_init_dynamic_array()
Ensure that memory allocated by fedarated is registered for the system, not for the thread.
storage/federatedx/federatedx_io_mysql.cc:
Updated call to my_init_dynamic_array()
storage/federatedx/ha_federatedx.cc:
Updated call to init_alloc_root()
Updated call to my_init_dynamic_array()
storage/heap/ha_heap.cc:
Added MY_THREAD_SPECIFIC to allocated memory.
storage/heap/heapdef.h:
Added parameter to hp_get_new_block() to be able to do thread specific memory tagging.
storage/heap/hp_block.c:
Added parameter to hp_get_new_block() to be able to do thread specific memory tagging.
storage/heap/hp_create.c:
- Internal HEAP tables are now marking it's memory as MY_THREAD_SPECIFIC.
- Use MY_TREE_WITH_DELETE instead of removed option 'with_delete'.
storage/heap/hp_open.c:
Internal HEAP tables are now marking it's memory as MY_THREAD_SPECIFIC.
storage/heap/hp_write.c:
Added new parameter to hp_get_new_block()
storage/maria/ma_bitmap.c:
Updated call to my_init_dynamic_array()
storage/maria/ma_blockrec.c:
Updated call to my_init_dynamic_array()
storage/maria/ma_check.c:
Updated call to init_alloc_root()
storage/maria/ma_ft_boolean_search.c:
Updated calls to init_tree() and init_alloc_root()
storage/maria/ma_ft_nlq_search.c:
Updated call to init_tree()
storage/maria/ma_ft_parser.c:
Updated call to init_tree()
Updated call to init_alloc_root()
storage/maria/ma_loghandler.c:
Updated call to my_init_dynamic_array()
storage/maria/ma_open.c:
Updated call to my_init_dynamic_array()
storage/maria/ma_sort.c:
Updated call to my_init_dynamic_array()
storage/maria/ma_write.c:
Updated calls to my_init_dynamic_array() and init_tree()
storage/maria/maria_pack.c:
Updated call to init_tree()
storage/maria/unittest/sequence_storage.c:
Updated call to my_init_dynamic_array()
storage/myisam/ft_boolean_search.c:
Updated call to init_tree()
Updated call to init_alloc_root()
storage/myisam/ft_nlq_search.c:
Updated call to init_tree()
storage/myisam/ft_parser.c:
Updated call to init_tree()
Updated call to init_alloc_root()
storage/myisam/ft_stopwords.c:
Updated call to init_tree()
storage/myisam/mi_check.c:
Updated call to init_alloc_root()
storage/myisam/mi_write.c:
Updated call to my_init_dynamic_array()
Updated call to init_tree()
storage/myisam/myisamlog.c:
Updated call to init_tree()
storage/myisam/myisampack.c:
Updated call to init_tree()
storage/myisam/sort.c:
Updated call to my_init_dynamic_array()
storage/myisammrg/ha_myisammrg.cc:
Updated call to init_sql_alloc()
storage/perfschema/pfs_check.cc:
Rest current_thd
storage/perfschema/pfs_instr.cc:
Removed DBUG_ENTER/DBUG_VOID_RETURN as at this point my_thread_var is not allocated anymore, which can cause problems.
support-files/compiler_warnings.supp:
Disable compiler warning from offsetof macro.
173 files changed, 1330 insertions, 772 deletions
diff --git a/client/completion_hash.cc b/client/completion_hash.cc index 9ffb2082c06..1a8bc4d5035 100644 --- a/client/completion_hash.cc +++ b/client/completion_hash.cc @@ -49,7 +49,7 @@ int completion_hash_init(HashTable *ht, uint nSize) ht->initialized = 0; return FAILURE; } - init_alloc_root(&ht->mem_root, 8192, 0); + init_alloc_root(&ht->mem_root, 8192, 0, 0); ht->pHashFunction = hashpjw; ht->nTableSize = nSize; ht->initialized = 1; diff --git a/client/mysql.cc b/client/mysql.cc index 67878b36227..c4cfcc4f1ff 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -1157,7 +1157,7 @@ int main(int argc,char *argv[]) } glob_buffer.realloc(512); completion_hash_init(&ht, 128); - init_alloc_root(&hash_mem_root, 16384, 0); + init_alloc_root(&hash_mem_root, 16384, 0, 0); bzero((char*) &mysql, sizeof(mysql)); if (sql_connect(current_host,current_db,current_user,opt_password, opt_silent)) diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc index 8f6baea4b9f..95e2066cf41 100644 --- a/client/mysqlbinlog.cc +++ b/client/mysqlbinlog.cc @@ -278,8 +278,8 @@ public: int init() { - return init_dynamic_array(&file_names, sizeof(File_name_record), - 100, 100); + return my_init_dynamic_array(&file_names, sizeof(File_name_record), + 100, 100, 0); } void init_by_dir_name(const char *dir) @@ -2393,7 +2393,7 @@ int main(int argc, char** argv) my_init_time(); // for time functions - init_alloc_root(&s_mem_root, 16384, 0); + init_alloc_root(&s_mem_root, 16384, 0, 0); if (load_defaults("my", load_groups, &argc, &argv)) exit(1); diff --git a/client/mysqlcheck.c b/client/mysqlcheck.c index 4218f2da62c..eb2bed9d13f 100644 --- a/client/mysqlcheck.c +++ b/client/mysqlcheck.c @@ -994,8 +994,10 @@ int main(int argc, char **argv) } if (opt_auto_repair && - (my_init_dynamic_array(&tables4repair, sizeof(char)*(NAME_LEN*2+2),16,64) || - my_init_dynamic_array(&tables4rebuild, sizeof(char)*(NAME_LEN*2+2),16,64))) + (my_init_dynamic_array(&tables4repair, sizeof(char)*(NAME_LEN*2+2),16, + 64, 0) || + my_init_dynamic_array(&tables4rebuild, sizeof(char)*(NAME_LEN*2+2),16, + 64, 0))) goto end; if (opt_alldbs) diff --git a/client/mysqldump.c b/client/mysqldump.c index e054cc57839..583524a43d8 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -4583,7 +4583,7 @@ static int dump_selected_tables(char *db, char **table_names, int tables) if (init_dumping(db, init_dumping_tables)) DBUG_RETURN(1); - init_alloc_root(&root, 8192, 0); + init_alloc_root(&root, 8192, 0, 0); if (!(dump_tables= pos= (char**) alloc_root(&root, tables * sizeof(char *)))) die(EX_EOM, "alloc_root failure."); diff --git a/client/mysqltest.cc b/client/mysqltest.cc index d61a48fe964..a60c8da93bf 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -5174,7 +5174,7 @@ typedef struct static st_error global_error_names[] = { - { "<No error>", -1U, "" }, + { "<No error>", ~0U, "" }, #include <mysqld_ername.h> { 0, 0, 0 } }; @@ -7286,7 +7286,7 @@ void init_win_path_patterns() DBUG_ENTER("init_win_path_patterns"); - my_init_dynamic_array(&patterns, sizeof(const char*), 16, 16); + my_init_dynamic_array(&patterns, sizeof(const char*), 16, 16, MYF(0)); /* Loop through all paths in the array */ for (i= 0; i < num_paths; i++) @@ -8899,7 +8899,7 @@ int main(int argc, char **argv) cur_block->ok= TRUE; /* Outer block should always be executed */ cur_block->cmd= cmd_none; - my_init_dynamic_array(&q_lines, sizeof(struct st_command*), 1024, 1024); + my_init_dynamic_array(&q_lines, sizeof(struct st_command*), 1024, 1024, 0); if (my_hash_init2(&var_hash, 64, charset_info, 128, 0, 0, get_var_key, var_free, MYF(0))) @@ -8929,7 +8929,7 @@ int main(int argc, char **argv) #endif init_dynamic_string(&ds_res, "", 2048, 2048); - init_alloc_root(&require_file_root, 1024, 1024); + init_alloc_root(&require_file_root, 1024, 1024, 0); parse_args(argc, argv); @@ -9873,7 +9873,7 @@ struct st_replace_regex* init_replace_regex(char* expr) /* my_malloc() will die on fail with MY_FAE */ res=(struct st_replace_regex*)my_malloc( sizeof(*res)+expr_len ,MYF(MY_FAE+MY_WME)); - my_init_dynamic_array(&res->regex_arr,sizeof(struct st_regex),128,128); + my_init_dynamic_array(&res->regex_arr,sizeof(struct st_regex), 128, 128, 0); buf= (char*)res + sizeof(*res); expr_end= expr + expr_len; @@ -10928,7 +10928,7 @@ void dynstr_append_sorted(DYNAMIC_STRING* ds, DYNAMIC_STRING *ds_input, if (!*start) DBUG_VOID_RETURN; /* No input */ - my_init_dynamic_array(&lines, sizeof(const char*), 32, 32); + my_init_dynamic_array(&lines, sizeof(const char*), 32, 32, 0); if (keep_header) { diff --git a/extra/comp_err.c b/extra/comp_err.c index bde7d705c75..7476578204a 100644 --- a/extra/comp_err.c +++ b/extra/comp_err.c @@ -894,7 +894,7 @@ static struct errors *generate_empty_message(uint d_code) if (!(new_error= (struct errors *) my_malloc(sizeof(*new_error), MYF(MY_WME)))) return(0); - if (my_init_dynamic_array(&new_error->msg, sizeof(struct message), 0, 1)) + if (my_init_dynamic_array(&new_error->msg, sizeof(struct message), 0, 1, 0)) return(0); /* OOM: Fatal error */ new_error->er_name= NULL; @@ -928,7 +928,7 @@ static struct errors *parse_error_string(char *str, int er_count) MYF(MY_WME)))) DBUG_RETURN(0); - if (my_init_dynamic_array(&new_error->msg, sizeof(struct message), 0, 0)) + if (my_init_dynamic_array(&new_error->msg, sizeof(struct message), 0, 0, 0)) DBUG_RETURN(0); /* OOM: Fatal error */ /* getting the error name */ diff --git a/extra/replace.c b/extra/replace.c index 8aef9f9a0a0..c2dcc9f50b5 100644 --- a/extra/replace.c +++ b/extra/replace.c @@ -265,7 +265,7 @@ static int insert_pointer_name(reg1 POINTER_ARRAY *pa,char * name) if (!(pa->str= (uchar*) my_malloc((uint) (PS_MALLOC-MALLOC_OVERHEAD), MYF(MY_WME)))) { - my_free(pa->typelib.type_names); + my_free((char*) pa->typelib.type_names); DBUG_RETURN (-1); } pa->max_count=(PC_MALLOC-MALLOC_OVERHEAD)/(sizeof(uchar*)+ @@ -327,7 +327,7 @@ static void free_pointer_array(reg1 POINTER_ARRAY *pa) if (pa->typelib.count) { pa->typelib.count=0; - my_free(pa->typelib.type_names); + my_free((char*) pa->typelib.type_names); pa->typelib.type_names=0; my_free(pa->str); } diff --git a/extra/resolve_stack_dump.c b/extra/resolve_stack_dump.c index dd77e1785d0..c7f33d2723b 100644 --- a/extra/resolve_stack_dump.c +++ b/extra/resolve_stack_dump.c @@ -223,7 +223,7 @@ static void init_sym_table() { char buf[512]; if (my_init_dynamic_array(&sym_table, sizeof(SYM_ENTRY), INIT_SYM_TABLE, - INC_SYM_TABLE)) + INC_SYM_TABLE, 0)) die("Failed in my_init_dynamic_array() -- looks like out of memory problem"); while (fgets(buf, sizeof(buf), fp_sym)) diff --git a/include/hash.h b/include/hash.h index 98bcf911db2..2ecfe0891d7 100644 --- a/include/hash.h +++ b/include/hash.h @@ -39,6 +39,7 @@ extern "C" { /* flags for hash_init */ #define HASH_UNIQUE 1 /* hash_insert fails on duplicate key */ +#define HASH_THREAD_SPECIFIC 2 /* Mark allocated memory THREAD_SPECIFIC */ typedef uint my_hash_value_type; typedef uchar *(*my_hash_get_key)(const uchar *,size_t*,my_bool); diff --git a/include/heap.h b/include/heap.h index 10b165d89c6..149f9ed5f56 100644 --- a/include/heap.h +++ b/include/heap.h @@ -153,6 +153,7 @@ typedef struct st_heap_share THR_LOCK lock; mysql_mutex_t intern_lock; /* Locking for use with _locking */ my_bool delete_on_close; + my_bool internal; /* Internal temporary table */ LIST open_list; uint auto_key; uint auto_key_type; /* real type of the auto key segment */ diff --git a/include/my_dir.h b/include/my_dir.h index 1ee002cc380..6a941b37d79 100644 --- a/include/my_dir.h +++ b/include/my_dir.h @@ -45,8 +45,9 @@ extern "C" { #define MY_S_ISREG(m) (((m) & MY_S_IFMT) == MY_S_IFREG) #define MY_S_ISFIFO(m) (((m) & MY_S_IFMT) == MY_S_IFIFO) -#define MY_DONT_SORT 512 /* my_lib; Don't sort files */ -#define MY_WANT_STAT 1024 /* my_lib; stat files */ +/* Ensure these dosn't clash with anything in my_sys.h */ +#define MY_DONT_SORT 8192 /* my_lib; Don't sort files */ +#define MY_WANT_STAT 16384 /* my_lib; stat files */ /* typedefs for my_dir & my_stat */ diff --git a/include/my_global.h b/include/my_global.h index 09a3a0a6efd..a99823b94d8 100644 --- a/include/my_global.h +++ b/include/my_global.h @@ -1003,7 +1003,7 @@ typedef struct st_mysql_lex_string LEX_STRING; #define SOCKET_EMFILE EMFILE #endif -typedef int myf; /* Type of MyFlags in my_funcs */ +typedef ulong myf; /* Type of MyFlags in my_funcs */ typedef char my_bool; /* Small bool */ /* Macros for converting *constants* to the right type */ diff --git a/include/my_sys.h b/include/my_sys.h index 2b0ae41a9b0..8f19293deb0 100644 --- a/include/my_sys.h +++ b/include/my_sys.h @@ -86,6 +86,10 @@ typedef struct my_aio_result { #define MY_SYNC 4096 /* my_copy(): sync dst file */ #define MY_SYNC_DIR 32768 /* my_create/delete/rename: sync directory */ #define MY_SYNC_FILESIZE 65536 /* my_sync(): safe sync when file is extended */ +#define MY_THREAD_SPECIFIC 0x10000 /* my_malloc(): thread specific */ +#define MY_THREAD_MOVE 0x20000 /* realloc(); Memory can move */ +/* Tree that should delete things automaticly */ +#define MY_TREE_WITH_DELETE 0x40000 #define MY_CHECK_ERROR 1 /* Params to my_end; Check open-close */ #define MY_GIVE_INFO 2 /* Give time info about process*/ @@ -148,6 +152,18 @@ typedef struct my_aio_result { /* Extra length needed for filename if one calls my_create_backup_name */ #define MY_BACKUP_NAME_EXTRA_LENGTH 17 +/* If we have our own safemalloc (for debugging) */ +#if defined(SAFEMALLOC) +void sf_report_leaked_memory(my_thread_id id); +extern my_thread_id (*sf_malloc_dbug_id)(void); +#define SAFEMALLOC_REPORT_MEMORY(X) sf_report_leaked_memory(X) +#else +#define SAFEMALLOC_REPORT_MEMORY(X) do {} while(0) +#endif + +typedef void (*MALLOC_SIZE_CB) (long long size, myf my_flags); +extern void set_malloc_size_cb(MALLOC_SIZE_CB func); + /* defines when allocating data */ extern void *my_malloc(size_t Size,myf MyFlags); extern void *my_multi_malloc(myf MyFlags, ...); @@ -323,6 +339,7 @@ typedef struct st_dynamic_array uint elements,max_element; uint alloc_increment; uint size_of_element; + myf malloc_flags; } DYNAMIC_ARRAY; typedef struct st_my_tmpdir @@ -768,16 +785,11 @@ extern my_bool real_open_cached_file(IO_CACHE *cache); extern void close_cached_file(IO_CACHE *cache); File create_temp_file(char *to, const char *dir, const char *pfx, int mode, myf MyFlags); -#define my_init_dynamic_array(A,B,C,D) init_dynamic_array2(A,B,NULL,C,D) -#define my_init_dynamic_array_ci(A,B,C,D) init_dynamic_array2(A,B,NULL,C,D) -#define my_init_dynamic_array2(A,B,C,D,E) init_dynamic_array2(A,B,C,D,E) -#define my_init_dynamic_array2_ci(A,B,C,D,E) init_dynamic_array2(A,B,C,D,E) +#define my_init_dynamic_array(A,B,C,D,E) init_dynamic_array2(A,B,NULL,C,D,E) +#define my_init_dynamic_array2(A,B,C,D,E,F) init_dynamic_array2(A,B,C,D,E,F) extern my_bool init_dynamic_array2(DYNAMIC_ARRAY *array, uint element_size, void *init_buffer, uint init_alloc, - uint alloc_increment); -/* init_dynamic_array() function is deprecated */ -extern my_bool init_dynamic_array(DYNAMIC_ARRAY *array, uint element_size, - uint init_alloc, uint alloc_increment); + uint alloc_increment, myf my_flags); extern my_bool insert_dynamic(DYNAMIC_ARRAY *array, const uchar * element); extern uchar *alloc_dynamic(DYNAMIC_ARRAY *array); extern uchar *pop_dynamic(DYNAMIC_ARRAY*); @@ -829,7 +841,7 @@ extern void my_free_lock(void *ptr); #define ALLOC_ROOT_MIN_BLOCK_SIZE (MALLOC_OVERHEAD + sizeof(USED_MEM) + 8) #define clear_alloc_root(A) do { (A)->free= (A)->used= (A)->pre_alloc= 0; (A)->min_malloc=0;} while(0) extern void init_alloc_root(MEM_ROOT *mem_root, size_t block_size, - size_t pre_alloc_size); + size_t pre_alloc_size, myf my_flags); extern void *alloc_root(MEM_ROOT *mem_root, size_t Size); extern void *multi_alloc_root(MEM_ROOT *mem_root, ...); extern void free_root(MEM_ROOT *root, myf MyFLAGS); diff --git a/include/my_tree.h b/include/my_tree.h index 3dd92712af2..f8be55f84b2 100644 --- a/include/my_tree.h +++ b/include/my_tree.h @@ -68,13 +68,15 @@ typedef struct st_tree { MEM_ROOT mem_root; my_bool with_delete; tree_element_free free; + myf my_flags; uint flag; } TREE; /* Functions on whole tree */ void init_tree(TREE *tree, size_t default_alloc_size, size_t memory_limit, - int size, qsort_cmp2 compare, my_bool with_delete, - tree_element_free free_element, void *custom_arg); + int size, qsort_cmp2 compare, + tree_element_free free_element, void *custom_arg, + myf my_flags); void delete_tree(TREE*); void reset_tree(TREE*); diff --git a/include/myisamchk.h b/include/myisamchk.h index 789e95572b3..7e7b685a88a 100644 --- a/include/myisamchk.h +++ b/include/myisamchk.h @@ -164,6 +164,7 @@ typedef struct st_handler_check_param mysql_mutex_t print_msg_mutex; my_bool need_print_msg_lock; + myf malloc_flags; } HA_CHECK; diff --git a/include/mysql.h b/include/mysql.h index fa62026b44a..1268280395e 100644 --- a/include/mysql.h +++ b/include/mysql.h @@ -167,7 +167,7 @@ enum mysql_option MYSQL_OPT_GUESS_CONNECTION, MYSQL_SET_CLIENT_IP, MYSQL_SECURE_AUTH, MYSQL_REPORT_DATA_TRUNCATION, MYSQL_OPT_RECONNECT, MYSQL_OPT_SSL_VERIFY_SERVER_CERT, MYSQL_PLUGIN_DIR, MYSQL_DEFAULT_AUTH, - MYSQL_PROGRESS_CALLBACK, + MYSQL_PROGRESS_CALLBACK, MYSQL_THREAD_SPECIFIC_MALLOC, /* MariaDB options */ MYSQL_OPT_NONBLOCK=6000 }; @@ -194,7 +194,7 @@ struct st_mysql_options { unsigned long max_allowed_packet; my_bool use_ssl; /* if to use SSL or not */ my_bool compress,named_pipe; - my_bool unused1; + my_bool thread_specific_malloc; my_bool unused2; my_bool unused3; my_bool unused4; diff --git a/include/mysql.h.pp b/include/mysql.h.pp index 48ce79046ff..84510a69edb 100644 --- a/include/mysql.h.pp +++ b/include/mysql.h.pp @@ -28,7 +28,7 @@ typedef struct st_net { unsigned char reading_or_writing; char save_char; char net_skip_rest_factor; - my_bool unused1; + my_bool thread_specific_malloc; my_bool compress; my_bool unused3; unsigned char *unused; @@ -80,7 +80,7 @@ enum enum_mysql_set_option MYSQL_OPTION_MULTI_STATEMENTS_ON, MYSQL_OPTION_MULTI_STATEMENTS_OFF }; -my_bool my_net_init(NET *net, Vio* vio); +my_bool my_net_init(NET *net, Vio* vio, unsigned int my_flags); void my_net_local_init(NET *net); void net_end(NET *net); void net_clear(NET *net, my_bool clear_buffer); @@ -262,7 +262,7 @@ enum mysql_option MYSQL_OPT_GUESS_CONNECTION, MYSQL_SET_CLIENT_IP, MYSQL_SECURE_AUTH, MYSQL_REPORT_DATA_TRUNCATION, MYSQL_OPT_RECONNECT, MYSQL_OPT_SSL_VERIFY_SERVER_CERT, MYSQL_PLUGIN_DIR, MYSQL_DEFAULT_AUTH, - MYSQL_PROGRESS_CALLBACK, + MYSQL_PROGRESS_CALLBACK, MYSQL_THREAD_SPECIFIC_MALLOC, MYSQL_OPT_NONBLOCK=6000 }; struct st_mysql_options_extention; @@ -282,7 +282,7 @@ struct st_mysql_options { unsigned long max_allowed_packet; my_bool use_ssl; my_bool compress,named_pipe; - my_bool unused1; + my_bool thread_specific_malloc; my_bool unused2; my_bool unused3; my_bool unused4; diff --git a/include/mysql_com.h b/include/mysql_com.h index 46a55e42e50..dbcc7125302 100644 --- a/include/mysql_com.h +++ b/include/mysql_com.h @@ -330,7 +330,7 @@ typedef struct st_net { unsigned char reading_or_writing; char save_char; char net_skip_rest_factor; - my_bool unused1; /* Please remove with the next incompatible ABI change */ + my_bool thread_specific_malloc; my_bool compress; my_bool unused3; /* Please remove with the next incompatible ABI change. */ /* @@ -465,10 +465,10 @@ enum enum_mysql_set_option extern "C" { #endif -my_bool my_net_init(NET *net, Vio* vio); +my_bool my_net_init(NET *net, Vio* vio, unsigned int my_flags); void my_net_local_init(NET *net); void net_end(NET *net); - void net_clear(NET *net, my_bool clear_buffer); +void net_clear(NET *net, my_bool clear_buffer); my_bool net_realloc(NET *net, size_t length); my_bool net_flush(NET *net); my_bool my_net_write(NET *net,const unsigned char *packet, size_t len); diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c index f90cc96a90f..5ca4e1085ee 100644 --- a/libmysql/libmysql.c +++ b/libmysql/libmysql.c @@ -1520,8 +1520,8 @@ mysql_stmt_init(MYSQL *mysql) DBUG_RETURN(NULL); } - init_alloc_root(&stmt->mem_root, 2048, 2048); - init_alloc_root(&stmt->result.alloc, 4096, 4096); + init_alloc_root(&stmt->mem_root, 2048, 2048, MY_THREAD_SPECIFIC); + init_alloc_root(&stmt->result.alloc, 4096, 4096, MY_THREAD_SPECIFIC); stmt->result.alloc.min_malloc= sizeof(MYSQL_ROWS); mysql->stmts= list_add(mysql->stmts, &stmt->list); stmt->list.data= stmt; @@ -1532,7 +1532,8 @@ mysql_stmt_init(MYSQL *mysql) strmov(stmt->sqlstate, not_error_sqlstate); /* The rest of statement members was bzeroed inside malloc */ - init_alloc_root(&stmt->extension->fields_mem_root, 2048, 0); + init_alloc_root(&stmt->extension->fields_mem_root, 2048, 0, + MYF(MY_THREAD_SPECIFIC)); DBUG_RETURN(stmt); } diff --git a/libmysqld/emb_qcache.cc b/libmysqld/emb_qcache.cc index d263e5d5fe8..7f73c6c4aeb 100644 --- a/libmysqld/emb_qcache.cc +++ b/libmysqld/emb_qcache.cc @@ -415,7 +415,7 @@ int emb_load_querycache_result(THD *thd, Querycache_stream *src) if (!data) goto err; - init_alloc_root(&data->alloc, 8192,0); + init_alloc_root(&data->alloc, 8192,0,0); f_alloc= &data->alloc; data->fields= src->load_int(); diff --git a/libmysqld/lib_sql.cc b/libmysqld/lib_sql.cc index 955cc3c0dd1..8ffeaebb17b 100644 --- a/libmysqld/lib_sql.cc +++ b/libmysqld/lib_sql.cc @@ -634,7 +634,7 @@ void init_embedded_mysql(MYSQL *mysql, int client_flag) mysql->server_version= server_version; mysql->client_flag= client_flag; //mysql->server_capabilities= client_flag; - init_alloc_root(&mysql->field_alloc, 8192, 0); + init_alloc_root(&mysql->field_alloc, 8192, 0, 0); } /** @@ -906,8 +906,9 @@ int Protocol::begin_dataset() if (!data) return 1; alloc= &data->alloc; - init_alloc_root(alloc,8192,0); /* Assume rowlength < 8192 */ - alloc->min_malloc=sizeof(MYSQL_ROWS); + /* Assume rowlength < 8192 */ + init_alloc_root(alloc, 8192, 0, MYF(MY_THREAD_SPECIFIC)); + alloc->min_malloc= sizeof(MYSQL_ROWS); return 0; } diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 768016d94aa..067d10e13ff 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -3591,9 +3591,10 @@ sub mysql_install_db { verbose => $opt_verbose, ) != 0) { + my $data= mtr_grab_file($path_bootstrap_log); mtr_error("Error executing mysqld --bootstrap\n" . "Could not install system database from $bootstrap_sql_file\n" . - "see $path_bootstrap_log for errors"); + "The $path_bootstrap_log file contains:\n$data\n"); } } diff --git a/mysql-test/r/create.result b/mysql-test/r/create.result index 86050a3c792..7c556354d2e 100644 --- a/mysql-test/r/create.result +++ b/mysql-test/r/create.result @@ -1762,7 +1762,9 @@ t1 CREATE TABLE `t1` ( `TIME_MS` decimal(22,3) NOT NULL DEFAULT '0.000', `STAGE` tinyint(2) NOT NULL DEFAULT '0', `MAX_STAGE` tinyint(2) NOT NULL DEFAULT '0', - `PROGRESS` decimal(7,3) NOT NULL DEFAULT '0.000' + `PROGRESS` decimal(7,3) NOT NULL DEFAULT '0.000', + `MEMORY_USED` int(7) NOT NULL DEFAULT '0', + `EXAMINED_ROWS` int(7) NOT NULL DEFAULT '0' ) DEFAULT CHARSET=utf8 drop table t1; create temporary table t1 like information_schema.processlist; @@ -1780,7 +1782,9 @@ t1 CREATE TEMPORARY TABLE `t1` ( `TIME_MS` decimal(22,3) NOT NULL DEFAULT '0.000', `STAGE` tinyint(2) NOT NULL DEFAULT '0', `MAX_STAGE` tinyint(2) NOT NULL DEFAULT '0', - `PROGRESS` decimal(7,3) NOT NULL DEFAULT '0.000' + `PROGRESS` decimal(7,3) NOT NULL DEFAULT '0.000', + `MEMORY_USED` int(7) NOT NULL DEFAULT '0', + `EXAMINED_ROWS` int(7) NOT NULL DEFAULT '0' ) DEFAULT CHARSET=utf8 drop table t1; create table t1 like information_schema.character_sets; diff --git a/mysql-test/r/show_explain.result b/mysql-test/r/show_explain.result index 176f82ad9e3..da132a102e2 100644 --- a/mysql-test/r/show_explain.result +++ b/mysql-test/r/show_explain.result @@ -1,5 +1,6 @@ drop table if exists t0, t1, t2, t3, t4; drop view if exists v1; +SET @old_debug= @@session.debug; set debug_sync='RESET'; create table t0 (a int); insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); @@ -12,12 +13,13 @@ show explain for 2000000000; ERROR HY000: Unknown thread id: 2000000000 show explain for (select max(a) from t0); ERROR HY000: You may only use constant expressions in this statement +SET @old_debug= @@session.debug; show explain for $thr2; ERROR HY000: Target is not running an EXPLAINable command show explain for $thr1; ERROR HY000: Target is not running an EXPLAINable command set @show_explain_probe_select_id=1; -set debug_dbug='d,show_explain_probe_join_exec_start'; +set debug_dbug='+d,show_explain_probe_join_exec_start'; select count(*) from t1 where a < 100000; show explain for $thr2; id select_type table type possible_keys key key_len ref rows Extra @@ -46,9 +48,10 @@ Note 1003 explain select max(c) from t1 where a < 10 id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 range a a 5 NULL 10 Using index condition; Rowid-ordered scan set optimizer_switch= @show_expl_tmp; +set debug_dbug=@old_debug; # UNION, first branch set @show_explain_probe_select_id=1; -set debug_dbug='d,show_explain_probe_join_exec_start'; +set debug_dbug='+d,show_explain_probe_join_exec_start'; explain select a from t0 A union select a+1 from t0 B; show explain for $thr2; id select_type table type possible_keys key key_len ref rows Extra @@ -61,9 +64,10 @@ id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY A ALL NULL NULL NULL NULL 10 2 UNION B ALL NULL NULL NULL NULL 10 NULL UNION RESULT <union1,2> ALL NULL NULL NULL NULL NULL +set debug_dbug=@old_debug; # UNION, second branch set @show_explain_probe_select_id=1; -set debug_dbug='d,show_explain_probe_join_exec_start'; +set debug_dbug='+d,show_explain_probe_join_exec_start'; explain select a from t0 A union select a+1 from t0 B; show explain for $thr2; id select_type table type possible_keys key key_len ref rows Extra @@ -76,9 +80,10 @@ id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY A ALL NULL NULL NULL NULL 10 2 UNION B ALL NULL NULL NULL NULL 10 NULL UNION RESULT <union1,2> ALL NULL NULL NULL NULL NULL +set debug_dbug=@old_debug; # Uncorrelated subquery, select set @show_explain_probe_select_id=1; -set debug_dbug='d,show_explain_probe_join_exec_start'; +set debug_dbug='+d,show_explain_probe_join_exec_start'; select a, (select max(a) from t0 B) from t0 A where a<1; show explain for $thr2; id select_type table type possible_keys key key_len ref rows Extra @@ -88,9 +93,10 @@ Warnings: Note 1003 select a, (select max(a) from t0 B) from t0 A where a<1 a (select max(a) from t0 B) 0 9 +set debug_dbug=@old_debug; # Uncorrelated subquery, explain set @show_explain_probe_select_id=1; -set debug_dbug='d,show_explain_probe_join_exec_start'; +set debug_dbug='+d,show_explain_probe_join_exec_start'; explain select a, (select max(a) from t0 B) from t0 A where a<1; show explain for $thr2; id select_type table type possible_keys key key_len ref rows Extra @@ -101,9 +107,10 @@ Note 1003 explain select a, (select max(a) from t0 B) from t0 A where a<1 id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY A ALL NULL NULL NULL NULL 10 Using where 2 SUBQUERY B ALL NULL NULL NULL NULL 10 +set debug_dbug=@old_debug; # correlated subquery, select set @show_explain_probe_select_id=1; -set debug_dbug='d,show_explain_probe_join_exec_start'; +set debug_dbug='+d,show_explain_probe_join_exec_start'; select a, (select max(a) from t0 b where b.a+a.a<10) from t0 a where a<1; show explain for $thr2; id select_type table type possible_keys key key_len ref rows Extra @@ -113,9 +120,10 @@ Warnings: Note 1003 select a, (select max(a) from t0 b where b.a+a.a<10) from t0 a where a<1 a (select max(a) from t0 b where b.a+a.a<10) 0 9 +set debug_dbug=@old_debug; # correlated subquery, explain set @show_explain_probe_select_id=1; -set debug_dbug='d,show_explain_probe_join_exec_start'; +set debug_dbug='+d,show_explain_probe_join_exec_start'; select a, (select max(a) from t0 b where b.a+a.a<10) from t0 a where a<1; show explain for $thr2; id select_type table type possible_keys key key_len ref rows Extra @@ -125,9 +133,10 @@ Warnings: Note 1003 select a, (select max(a) from t0 b where b.a+a.a<10) from t0 a where a<1 a (select max(a) from t0 b where b.a+a.a<10) 0 9 +set debug_dbug=@old_debug; # correlated subquery, select, while inside the subquery set @show_explain_probe_select_id=2; -set debug_dbug='d,show_explain_probe_join_exec_start'; +set debug_dbug='+d,show_explain_probe_join_exec_start'; select a, (select max(a) from t0 b where b.a+a.a<10) from t0 a where a<1; show explain for $thr2; id select_type table type possible_keys key key_len ref rows Extra @@ -137,9 +146,10 @@ Warnings: Note 1003 select a, (select max(a) from t0 b where b.a+a.a<10) from t0 a where a<1 a (select max(a) from t0 b where b.a+a.a<10) 0 9 +set debug_dbug=@old_debug; # correlated subquery, explain, while inside the subquery set @show_explain_probe_select_id=2; -set debug_dbug='d,show_explain_probe_join_exec_start'; +set debug_dbug='+d,show_explain_probe_join_exec_start'; select a, (select max(a) from t0 b where b.a+a.a<10) from t0 a where a<1; show explain for $thr2; id select_type table type possible_keys key key_len ref rows Extra @@ -149,52 +159,57 @@ Warnings: Note 1003 select a, (select max(a) from t0 b where b.a+a.a<10) from t0 a where a<1 a (select max(a) from t0 b where b.a+a.a<10) 0 9 +set debug_dbug=@old_debug; # correlated subquery, explain, while inside the subquery set @show_explain_probe_select_id=1; -set debug_dbug='d,show_explain_probe_join_exec_end'; +set debug_dbug='+d,show_explain_probe_join_exec_end'; select a, (select max(a) from t0 b where b.a+a.a<10) from t0 a where a<1; show explain for $thr2; ERROR HY000: Target is not running an EXPLAINable command a (select max(a) from t0 b where b.a+a.a<10) 0 9 +set debug_dbug=@old_debug; # Try to do SHOW EXPLAIN for a query that runs a SET command: # I've found experimentally that select_id==2 here... # set @show_explain_probe_select_id=2; -set debug_dbug='d,show_explain_probe_join_exec_start'; +set debug_dbug='+d,show_explain_probe_join_exec_start'; set @foo= (select max(a) from t0 where sin(a) >0); show explain for $thr2; ERROR HY000: Target is not running an EXPLAINable command +set debug_dbug=@old_debug; # # Attempt SHOW EXPLAIN for an UPDATE # create table t2 as select a as a, a as dummy from t0 limit 2; set @show_explain_probe_select_id=2; -set debug_dbug='d,show_explain_probe_join_exec_start'; +set debug_dbug='+d,show_explain_probe_join_exec_start'; update t2 set dummy=0 where (select max(a) from t0 where t2.a + t0.a <3) >3 ; show explain for $thr2; ERROR HY000: Target is not running an EXPLAINable command show explain for $thr2; ERROR HY000: Target is not running an EXPLAINable command drop table t2; +set debug_dbug=@old_debug; # # Attempt SHOW EXPLAIN for a DELETE # create table t2 as select a as a, a as dummy from t0 limit 2; set @show_explain_probe_select_id=2; -set debug_dbug='d,show_explain_probe_join_exec_start'; +set debug_dbug='+d,show_explain_probe_join_exec_start'; delete from t2 where (select max(a) from t0 where t2.a + t0.a <3) >3 ; show explain for $thr2; ERROR HY000: Target is not running an EXPLAINable command show explain for $thr2; ERROR HY000: Target is not running an EXPLAINable command drop table t2; +set debug_dbug=@old_debug; # # Multiple SHOW EXPLAIN calls for one select # create table t2 as select a as a, a as dummy from t0 limit 3; set @show_explain_probe_select_id=2; -set debug_dbug='d,show_explain_probe_join_exec_start'; +set debug_dbug='+d,show_explain_probe_join_exec_start'; select t2.a, ((select max(a) from t0 where t2.a + t0.a <3) >3) as SUBQ from t2; show explain for $thr2; id select_type table type possible_keys key key_len ref rows Extra @@ -219,13 +234,14 @@ a SUBQ 1 0 2 0 drop table t2; +set debug_dbug=@old_debug; # # SHOW EXPLAIN for SELECT ... ORDER BY with "Using filesort" # explain select * from t0 order by a; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t0 ALL NULL NULL NULL NULL 10 Using filesort -set debug_dbug='d,show_explain_probe_join_exec_start'; +set debug_dbug='+d,show_explain_probe_join_exec_start'; set @show_explain_probe_select_id=1; select * from t0 order by a; show explain for $thr2; @@ -244,13 +260,14 @@ a 7 8 9 +set debug_dbug=@old_debug; # # SHOW EXPLAIN for SELECT ... with "Using temporary" # explain select distinct a from t0; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t0 ALL NULL NULL NULL NULL 10 Using temporary -set debug_dbug='d,show_explain_probe_join_exec_start'; +set debug_dbug='+d,show_explain_probe_join_exec_start'; set @show_explain_probe_select_id=1; select distinct a from t0; show explain for $thr2; @@ -269,13 +286,14 @@ a 7 8 9 +set debug_dbug=@old_debug; # # SHOW EXPLAIN for SELECT ... with "Using temporary; Using filesort" # explain select distinct a from t0; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t0 ALL NULL NULL NULL NULL 10 Using temporary -set debug_dbug='d,show_explain_probe_join_exec_start'; +set debug_dbug='+d,show_explain_probe_join_exec_start'; set @show_explain_probe_select_id=1; select distinct a from t0; show explain for $thr2; @@ -294,7 +312,7 @@ a 7 8 9 -set debug_dbug=''; +set debug_dbug=@old_debug; # # MDEV-238: SHOW EXPLAIN: Server crashes in JOIN::print_explain with FROM subquery and GROUP BY # @@ -304,7 +322,7 @@ explain SELECT alias.a FROM t2, ( SELECT * FROM t2 ) AS alias GROUP BY alias.a; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 ALL NULL NULL NULL NULL 5 Using temporary; Using filesort 1 SIMPLE t2 ALL NULL NULL NULL NULL 5 Using join buffer (flat, BNL join) -set debug_dbug='d,show_explain_in_find_all_keys'; +set debug_dbug='+d,show_explain_in_find_all_keys'; SELECT alias.a FROM t2, ( SELECT * FROM t2 ) AS alias GROUP BY alias.a; # FIXED by "conservative assumptions about when QEP is available" fix: # NOTE: current code will not show "Using join buffer": @@ -314,7 +332,7 @@ a 1 2 4 -set debug_dbug=''; +set debug_dbug=@old_debug; DROP TABLE t2; # # MDEV-239: Assertion `field_types == 0 ... ' failed in Protocol_text::store(double, uint32, String*) with @@ -329,7 +347,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra Warnings: Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` join `test`.`t2` group by `test`.`t2`.`a` set @show_explain_probe_select_id=1; -set debug_dbug='d,show_explain_probe_join_exec_end'; +set debug_dbug='+d,show_explain_probe_join_exec_end'; EXPLAIN EXTENDED SELECT alias.a FROM t2, ( SELECT * FROM t2 ) AS alias GROUP BY alias.a ; show explain for $thr2; id select_type table type possible_keys key key_len ref rows Extra @@ -342,7 +360,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t2 ALL NULL NULL NULL NULL 5 100.00 Using join buffer (flat, BNL join) Warnings: Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` join `test`.`t2` group by `test`.`t2`.`a` -set debug_dbug=''; +set debug_dbug=@old_debug; DROP TABLE t2; # # MDEV-240: SHOW EXPLAIN: Assertion `this->optimized == 2' failed in @@ -359,7 +377,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t2 ALL NULL NULL NULL NULL 6 2 DERIVED t3 system NULL NULL NULL NULL 1 set @show_explain_probe_select_id=2; -set debug_dbug='d,show_explain_probe_join_exec_end'; +set debug_dbug='+d,show_explain_probe_join_exec_end'; SELECT * FROM v1, t2; show explain for $thr2; ERROR HY000: Target is not running an EXPLAINable command @@ -370,14 +388,14 @@ a b 8 7 8 8 8 9 -set debug_dbug=''; +set debug_dbug=@old_debug; DROP VIEW v1; DROP TABLE t2, t3; # # MDEV-267: SHOW EXPLAIN: Server crashes in JOIN::print_explain on most of queries # set @show_explain_probe_select_id=1; -set debug_dbug='d,show_explain_probe_join_exec_end'; +set debug_dbug='+d,show_explain_probe_join_exec_end'; select sleep(1); show explain for $thr2; id select_type table type possible_keys key key_len ref rows Extra @@ -386,29 +404,29 @@ Warnings: Note 1003 select sleep(1) sleep(1) 0 -set debug_dbug=''; +set debug_dbug=@old_debug; # # Same as above, but try another reason for JOIN to be degenerate # set @show_explain_probe_select_id=1; -set debug_dbug='d,show_explain_probe_join_exec_end'; +set debug_dbug='+d,show_explain_probe_join_exec_end'; select * from t0 where 1>10; show explain for $thr2; ERROR HY000: Target is not running an EXPLAINable command a -set debug_dbug=''; +set debug_dbug=@old_debug; # # Same as above, but try another reason for JOIN to be degenerate (2) # create table t3(a int primary key); insert into t3 select a from t0; set @show_explain_probe_select_id=1; -set debug_dbug='d,show_explain_probe_join_exec_end'; +set debug_dbug='+d,show_explain_probe_join_exec_end'; select * from t0,t3 where t3.a=112233; show explain for $thr2; ERROR HY000: Target is not running an EXPLAINable command a a -set debug_dbug=''; +set debug_dbug=@old_debug; drop table t3; # # MDEV-270: SHOW EXPLAIN: server crashes in JOIN::print_explain on a query with @@ -427,7 +445,7 @@ id select_type table type possible_keys key key_len ref rows Extra 2 SUBQUERY t2 const PRIMARY PRIMARY 4 const 1 Using where 3 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away set @show_explain_probe_select_id=2; -set debug_dbug='d,show_explain_probe_do_select'; +set debug_dbug='+d,show_explain_probe_do_select'; SELECT * FROM t2 WHERE a = (SELECT MAX(a) FROM t2 WHERE pk= (SELECT MAX(pk) FROM t2 WHERE pk = 3) @@ -447,7 +465,7 @@ pk a 6 7 7 7 9 7 -set debug_dbug=''; +set debug_dbug=@old_debug; drop table t2; # # MDEV-273: SHOW EXPLAIN: server crashes in JOIN::print_explain on a query with impossible WHERE @@ -479,7 +497,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t3 ALL NULL NULL NULL NULL 87 Using join buffer (flat, BNL join) 2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables set @show_explain_probe_select_id=1; -set debug_dbug='d,show_explain_probe_do_select'; +set debug_dbug='+d,show_explain_probe_do_select'; SELECT count(*) FROM t2, t3 WHERE a1 < ALL ( SELECT a1 FROM t2 @@ -498,7 +516,7 @@ WHERE a1 IN ( SELECT a1 FROM t2, t4 ) ) count(*) 1740 -set debug_dbug=''; +set debug_dbug=@old_debug; drop table t2, t3, t4; # # MDEV-275: SHOW EXPLAIN: server crashes in JOIN::print_explain with IN subquery and aggregate function @@ -508,12 +526,12 @@ INSERT INTO t2 VALUES (1,5),(2,4),(3,6),(4,9),(5,2),(6,8),(7,4),(8,8),(9,0),(10,43), (11,23),(12,3),(13,45),(14,16),(15,2),(16,33),(17,2),(18,5),(19,9),(20,2); set @show_explain_probe_select_id=1; -set debug_dbug='d,show_explain_probe_join_exec_end'; +set debug_dbug='+d,show_explain_probe_join_exec_end'; SELECT * FROM t2 WHERE (5, 78) IN (SELECT `a1`, MAX(`a1`) FROM t2 GROUP BY `a1`); show explain for $thr2; ERROR HY000: Target is not running an EXPLAINable command pk a1 -set debug_dbug=''; +set debug_dbug=@old_debug; DROP TABLE t2; DROP TABLE t1; # @@ -522,7 +540,7 @@ DROP TABLE t1; CREATE TABLE t1(a INT, KEY(a)); INSERT INTO t1 VALUES (3),(1),(5),(1); set @show_explain_probe_select_id=1; -set debug_dbug='d,show_explain_probe_join_exec_start'; +set debug_dbug='+d,show_explain_probe_join_exec_start'; SELECT 'test' FROM t1 WHERE a=1; show explain for $thr2; id select_type table type possible_keys key key_len ref rows Extra @@ -532,7 +550,7 @@ Note 1003 SELECT 'test' FROM t1 WHERE a=1 test test test -set debug_dbug=''; +set debug_dbug=@old_debug; DROP TABLE t1; # # MDEV-299: SHOW EXPLAIN: Plan produced by SHOW EXPLAIN changes back and forth during query execution @@ -550,7 +568,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE A ALL NULL NULL NULL NULL 100 Using where 1 SIMPLE B ALL key1 NULL NULL NULL 100 Range checked for each record (index map: 0x1) set @show_explain_probe_select_id=1; -set debug_dbug='d,show_explain_probe_test_if_quick_select'; +set debug_dbug='+d,show_explain_probe_test_if_quick_select'; select count(*) from t1 A, t1 B where B.key1 < A.col2 and A.col1=3 AND B.col2 + 1 < 100; show explain for $thr2; id select_type table type possible_keys key key_len ref rows Extra @@ -578,7 +596,7 @@ Warnings: Note 1003 select count(*) from t1 A, t1 B where B.key1 < A.col2 and A.col1=3 AND B.col2 + 1 < 100 count(*) 212 -set debug_dbug=''; +set debug_dbug=@old_debug; drop table t1; # # MDEV-297: SHOW EXPLAIN: Server gets stuck until timeout occurs while @@ -587,7 +605,7 @@ drop table t1; CREATE TABLE t1(a INT, b INT, c INT, KEY(a), KEY(b), KEY(c)); INSERT INTO t1 (a) VALUES (3),(1),(5),(1); set @show_explain_probe_select_id=1; -set debug_dbug='d,show_explain_probe_join_exec_start'; +set debug_dbug='+d,show_explain_probe_join_exec_start'; SHOW INDEX FROM t1; show explain for $thr2; id select_type table type possible_keys key key_len ref rows Extra @@ -598,7 +616,7 @@ Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_par t1 1 a 1 a A NULL NULL NULL YES BTREE t1 1 b 1 b A NULL NULL NULL YES BTREE t1 1 c 1 c A NULL NULL NULL YES BTREE -set debug_dbug=''; +set debug_dbug=@old_debug; DROP TABLE t1; # # MDEV-324: SHOW EXPLAIN: Plan produced by SHOW EXPLAIN for a query with TEMPTABLE view @@ -611,7 +629,7 @@ EXPLAIN SELECT a + 1 FROM v1; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2 2 DERIVED t1 ALL NULL NULL NULL NULL 2 -set debug_dbug='d,show_explain_probe_join_tab_preread'; +set debug_dbug='+d,show_explain_probe_join_tab_preread'; set @show_explain_probe_select_id=1; SELECT a + 1 FROM v1; show explain for $thr2; @@ -623,7 +641,7 @@ Note 1003 SELECT a + 1 FROM v1 a + 1 2 3 -set debug_dbug=''; +set debug_dbug=@old_debug; DROP VIEW v1; DROP TABLE t1; # @@ -639,7 +657,7 @@ id select_type table type possible_keys key key_len ref rows Extra 2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL No tables used 3 DEPENDENT UNION NULL NULL NULL NULL NULL NULL NULL No tables used NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL -set debug_dbug='d,show_explain_probe_union_read'; +set debug_dbug='+d,show_explain_probe_union_read'; SELECT a FROM t1 WHERE a IN ( SELECT 1+SLEEP(0.01) UNION SELECT 2 ); show explain for $thr2; id select_type table type possible_keys key key_len ref rows Extra @@ -658,7 +676,7 @@ NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL Warnings: Note 1003 SELECT a FROM t1 WHERE a IN ( SELECT 1+SLEEP(0.01) UNION SELECT 2 ) a -set debug_dbug=''; +set debug_dbug=@old_debug; DROP TABLE t1; # # MDEV-327: SHOW EXPLAIN: Different select_type in plans produced by SHOW EXPLAIN @@ -681,7 +699,7 @@ id select_type table type possible_keys key key_len ref rows Extra 3 SUBQUERY t1 ALL NULL NULL NULL NULL 20 3 SUBQUERY t2 ALL NULL NULL NULL NULL 20 Using where set @show_explain_probe_select_id=1; -set debug_dbug='d,show_explain_probe_join_exec_start'; +set debug_dbug='+d,show_explain_probe_join_exec_start'; SELECT * FROM t1, ( SELECT * FROM t2 ) AS alias WHERE a < ALL ( SELECT b FROM t1, t2 WHERE a = b ); show explain for $thr2; @@ -694,7 +712,7 @@ Warnings: Note 1003 SELECT * FROM t1, ( SELECT * FROM t2 ) AS alias WHERE a < ALL ( SELECT b FROM t1, t2 WHERE a = b ) a b -set debug_dbug=''; +set debug_dbug=@old_debug; DROP TABLE t1, t2; # # Test that SHOW EXPLAIN will print 'Distinct'. @@ -716,7 +734,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 index PRIMARY PRIMARY 4 NULL 4 Using index; Using temporary 1 SIMPLE t3 ref a a 5 test.t1.a 7 Using index; Distinct set @show_explain_probe_select_id=1; -set debug_dbug='d,show_explain_probe_join_exec_start'; +set debug_dbug='+d,show_explain_probe_join_exec_start'; select distinct t1.a from t1,t3 where t1.a=t3.a; show explain for $thr2; id select_type table type possible_keys key key_len ref rows Extra @@ -727,7 +745,7 @@ Note 1003 select distinct t1.a from t1,t3 where t1.a=t3.a a 1 2 -set debug_dbug=''; +set debug_dbug=@old_debug; drop table t1,t3,t4; # # ---------- SHOW EXPLAIN and permissions ----------------- @@ -738,7 +756,7 @@ grant super on *.* to test2@localhost; # First, make sure that user 'test2' cannot do SHOW EXPLAIN on us # set @show_explain_probe_select_id=1; -set debug_dbug='d,show_explain_probe_join_exec_start'; +set debug_dbug='+d,show_explain_probe_join_exec_start'; select * from t0 where a < 3; show explain for $thr2; ERROR 42000: Access denied; you need (at least one of) the PROCESS privilege(s) for this operation @@ -751,12 +769,12 @@ a 0 1 2 -set debug_dbug=''; +set debug_dbug=@old_debug; # # Check that user test2 can do SHOW EXPLAIN on its own queries # set @show_explain_probe_select_id=1; -set debug_dbug='d,show_explain_probe_join_exec_start'; +set debug_dbug='+d,show_explain_probe_join_exec_start'; select * from t0 where a < 3; show explain for $thr_con2; id select_type table type possible_keys key key_len ref rows Extra @@ -771,8 +789,9 @@ a # Now, grant test2 a PROCESSLIST permission, and see that he's able to observe us # grant process on *.* to test2@localhost; +set debug_dbug=@old_debug; set @show_explain_probe_select_id=1; -set debug_dbug='d,show_explain_probe_join_exec_start'; +set debug_dbug='+d,show_explain_probe_join_exec_start'; select * from t0 where a < 3; show explain for $thr2; id select_type table type possible_keys key key_len ref rows Extra @@ -783,7 +802,7 @@ a 0 1 2 -set debug_dbug=''; +set debug_dbug=@old_debug; revoke all privileges on test.* from test2@localhost; drop user test2@localhost; # @@ -848,7 +867,7 @@ ORDER BY b; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 index_merge a,b a,b 5,5 NULL 8 Using sort_union(a,b); Using where; Using filesort set @show_explain_probe_select_id=1; -set debug_dbug='d,show_explain_probe_join_exec_start'; +set debug_dbug='+d,show_explain_probe_join_exec_start'; SELECT a+SLEEP(0.01) FROM t1 WHERE a IN ( 255, 0 ) OR b BETWEEN 6 AND 129 ORDER BY b; @@ -867,8 +886,9 @@ a+SLEEP(0.01) 0 0 0 +set debug_dbug=@old_debug; set @show_explain_probe_select_id=1; -set debug_dbug='d,show_explain_probe_do_select'; +set debug_dbug='+d,show_explain_probe_do_select'; SELECT a+SLEEP(0.01) FROM t1 WHERE a IN ( 255, 0 ) OR b BETWEEN 6 AND 129 ORDER BY b; @@ -887,7 +907,7 @@ a+SLEEP(0.01) 0 0 0 -set debug_dbug=''; +set debug_dbug=@old_debug; drop table t1; # # MDEV-298: SHOW EXPLAIN: Plan returned by SHOW EXPLAIN only contains @@ -901,7 +921,7 @@ EXPLAIN SELECT a FROM t1 GROUP BY a; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 4112 Using temporary; Using filesort set @show_explain_probe_select_id=1; -set debug_dbug='d,show_explain_probe_join_exec_start'; +set debug_dbug='+d,show_explain_probe_join_exec_start'; SELECT a FROM t1 GROUP BY a; show explain for $thr2; id select_type table type possible_keys key key_len ref rows Extra @@ -925,7 +945,7 @@ a 14 15 16 -set debug_dbug=''; +set debug_dbug=@old_debug; drop table t1; # # MDEV-408: SHOW EXPLAIN: Some values are chopped off in SHOW EXPLAIN output @@ -939,7 +959,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where 2 DEPENDENT SUBQUERY t2 index_subquery PRIMARY,c c 5 func 1 Using index; Using where set @show_explain_probe_select_id=1; -set debug_dbug='d,show_explain_probe_join_exec_start'; +set debug_dbug='+d,show_explain_probe_join_exec_start'; SELECT SUM(a + SLEEP(0.1)) FROM t1 WHERE a IN ( SELECT c FROM t2 WHERE d < b ) OR b < 's'; show explain for $thr2; id select_type table type possible_keys key key_len ref rows Extra @@ -949,7 +969,7 @@ Warnings: Note 1003 SELECT SUM(a + SLEEP(0.1)) FROM t1 WHERE a IN ( SELECT c FROM t2 WHERE d < b ) OR b < 's' SUM(a + SLEEP(0.1)) 7862 -set debug_dbug=''; +set debug_dbug=@old_debug; drop table t1, t2; # # MDEV-412: SHOW EXPLAIN: Server crashes in JOIN::print_explain on a query with inner join and ORDER BY the same column twice @@ -987,7 +1007,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 index b b 6 NULL 107 Using where; Using index 1 SIMPLE t3 ref PRIMARY PRIMARY 5 test.t1.b 1 Using index set @show_explain_probe_select_id=1; -set debug_dbug='d,show_explain_probe_do_select'; +set debug_dbug='+d,show_explain_probe_do_select'; SELECT b AS field1, b AS field2 FROM t1, t2, t3 WHERE d = b ORDER BY field1, field2; show explain for $thr2; id select_type table type possible_keys key key_len ref rows Extra @@ -997,7 +1017,7 @@ id select_type table type possible_keys key key_len ref rows Extra Warnings: Note 1003 SELECT b AS field1, b AS field2 FROM t1, t2, t3 WHERE d = b ORDER BY field1, field2 field1 field2 -set debug_dbug=''; +set debug_dbug=@old_debug; DROP TABLE t1,t2,t3; # # MDEV-423: SHOW EXPLAIN: 'Using where' for a subquery is shown in EXPLAIN, but not in SHOW EXPLAIN output @@ -1018,7 +1038,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t2 ALL NULL NULL NULL NULL 20 3 SUBQUERY t3 ALL NULL NULL NULL NULL 20 Using where set @show_explain_probe_select_id=1; -set debug_dbug='d,show_explain_probe_join_exec_start'; +set debug_dbug='+d,show_explain_probe_join_exec_start'; SELECT max(a+b+c) FROM t1 AS alias1, ( SELECT * FROM t2 ) AS alias WHERE EXISTS ( SELECT * FROM t3 WHERE b = c ) OR a <= 10; show explain for $thr2; @@ -1031,7 +1051,7 @@ Note 1003 SELECT max(a+b+c) FROM t1 AS alias1, ( SELECT * FROM t2 ) AS alias WHERE EXISTS ( SELECT * FROM t3 WHERE b = c ) OR a <= 10 max(a+b+c) 279 -set debug_dbug=''; +set debug_dbug=@old_debug; DROP TABLE t1,t2,t3; # # MDEV-416: Server crashes in SQL_SELECT::cleanup on EXPLAIN with SUM ( DISTINCT ) in a non-correlated subquery (5.5-show-explain tree) @@ -1057,7 +1077,7 @@ select hex('ãû'); hex('ãû') E3FB set @show_explain_probe_select_id=1; -set debug_dbug='d,show_explain_probe_join_exec_start'; +set debug_dbug='+d,show_explain_probe_join_exec_start'; select * from t0 where length('ãû') = a; set names utf8; show explain for $thr2; @@ -1068,7 +1088,7 @@ Note 1003 select * from t0 where length('гы') = a set names default; a 2 -set debug_dbug=''; +set debug_dbug=@old_debug; set names default; # # MDEV-462: SHOW EXPLAIN: Assertion `table_list->table' fails in find_field_in_table_ref if FOR contains a non-numeric value diff --git a/mysql-test/r/user_var.result b/mysql-test/r/user_var.result index 9c4fd02fcdd..6cbbe934bde 100644 --- a/mysql-test/r/user_var.result +++ b/mysql-test/r/user_var.result @@ -530,4 +530,9 @@ SELECT @a; @a 1 DROP TABLE t1; +# +# Check that used memory extends if we set a variable +# +set @var= repeat('a',20000); +1 End of 5.5 tests diff --git a/mysql-test/suite/funcs_1/datadict/processlist_priv.inc b/mysql-test/suite/funcs_1/datadict/processlist_priv.inc index b863b98d98a..474171d175d 100644 --- a/mysql-test/suite/funcs_1/datadict/processlist_priv.inc +++ b/mysql-test/suite/funcs_1/datadict/processlist_priv.inc @@ -66,7 +66,7 @@ let $table= processlist; # # columns of the information_schema table e.g. to use in a select. -let $columns= ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO, TIME_MS, STAGE, MAX_STAGE, PROGRESS; +let $columns= ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO, TIME_MS, STAGE, MAX_STAGE, PROGRESS, MEMORY_USED, EXAMINED_ROWS; # # Where clause for an update. let $update_where= WHERE id=1 ; @@ -159,9 +159,9 @@ WHERE DB = 'information_schema' AND COMMAND = 'Sleep' AND USER = 'ddicttestuser1 eval SHOW CREATE TABLE $table; --replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS eval SHOW $table; ---replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS +--replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS 13 MEMORY 14 ROWS eval SELECT * FROM $table $select_where ORDER BY id; ---replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS +--replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS 13 MEMORY 14 ROWS eval SELECT $columns FROM $table $select_where ORDER BY id; --source suite/funcs_1/datadict/datadict_priv.inc --real_sleep 0.3 @@ -179,9 +179,9 @@ connection con100; eval SHOW CREATE TABLE $table; --replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS eval SHOW $table; ---replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS +--replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS 13 MEMORY 14 ROWS eval SELECT * FROM $table $select_where ORDER BY id; ---replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS +--replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS 13 MEMORY 14 ROWS eval SELECT $columns FROM $table $select_where ORDER BY id; --source suite/funcs_1/datadict/datadict_priv.inc --real_sleep 0.3 @@ -205,7 +205,7 @@ connection con100; SHOW GRANTS; --replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS SHOW processlist; ---replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS +--replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS 13 MEMORY 14 ROWS SELECT * FROM information_schema.processlist; --real_sleep 0.3 @@ -217,7 +217,7 @@ connect (con101,localhost,ddicttestuser1,ddictpass,information_schema); SHOW GRANTS; --replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS SHOW processlist; ---replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS +--replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS 13 MEMORY 14 ROWS SELECT * FROM information_schema.processlist; --real_sleep 0.3 @@ -239,7 +239,7 @@ connect (anonymous1,localhost,"''",,information_schema); SHOW GRANTS; --replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS SHOW processlist; ---replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS +--replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS 13 MEMORY 14 ROWS SELECT * FROM information_schema.processlist; --real_sleep 0.3 @@ -261,7 +261,7 @@ connect (con102,localhost,ddicttestuser1,ddictpass,information_schema); SHOW GRANTS; --replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS SHOW processlist; ---replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS +--replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS 13 MEMORY 14 ROWS SELECT * FROM information_schema.processlist; --real_sleep 0.3 @@ -287,7 +287,7 @@ if ($fixed_bug_30395) --replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS SHOW processlist; } ---replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS +--replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS 13 MEMORY 14 ROWS SELECT * FROM information_schema.processlist; --real_sleep 0.3 @@ -308,7 +308,7 @@ connect (con103,localhost,ddicttestuser1,ddictpass,information_schema); SHOW GRANTS FOR 'ddicttestuser1'@'localhost'; --replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS SHOW processlist; ---replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS +--replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS 13 MEMORY 14 ROWS SELECT * FROM information_schema.processlist; --real_sleep 0.3 @@ -330,7 +330,7 @@ connect (con104,localhost,ddicttestuser1,ddictpass,information_schema); SHOW GRANTS FOR 'ddicttestuser1'@'localhost'; --replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS SHOW processlist; ---replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS +--replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS 13 MEMORY 14 ROWS SELECT * FROM information_schema.processlist; --real_sleep 0.3 @@ -377,7 +377,7 @@ connect (con200,localhost,ddicttestuser2,ddictpass,information_schema); SHOW GRANTS FOR 'ddicttestuser2'@'localhost'; --replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS SHOW processlist; ---replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS +--replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS 13 MEMORY 14 ROWS SELECT * FROM information_schema.processlist; --real_sleep 0.3 @@ -398,7 +398,7 @@ connect (con201,localhost,ddicttestuser2,ddictpass,information_schema); SHOW GRANTS; --replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS SHOW processlist; ---replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS +--replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS 13 MEMORY 14 ROWS SELECT * FROM information_schema.processlist; --real_sleep 0.3 @@ -421,7 +421,7 @@ SHOW GRANTS FOR 'ddicttestuser1'@'localhost'; GRANT PROCESS ON *.* TO 'ddicttestuser2'@'localhost'; --replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS SHOW processlist; ---replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS +--replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS 13 MEMORY 14 ROWS SELECT * FROM information_schema.processlist; --real_sleep 0.3 @@ -445,7 +445,7 @@ connect (con108,localhost,ddicttestuser1,ddictpass,information_schema); SHOW GRANTS FOR 'ddicttestuser1'@'localhost'; --replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS SHOW processlist; ---replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS +--replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS 13 MEMORY 14 ROWS SELECT * FROM information_schema.processlist; --real_sleep 0.3 diff --git a/mysql-test/suite/funcs_1/datadict/processlist_val.inc b/mysql-test/suite/funcs_1/datadict/processlist_val.inc index bb6c13a6f4b..d0d2e606152 100644 --- a/mysql-test/suite/funcs_1/datadict/processlist_val.inc +++ b/mysql-test/suite/funcs_1/datadict/processlist_val.inc @@ -93,9 +93,9 @@ echo # - INFO must contain the corresponding SHOW/SELECT PROCESSLIST # # 1. Just dump what we get ---replace_column 1 <ID> 3 <HOST_NAME> 6 <TIME> 9 <TIME_MS> +--replace_column 1 <ID> 3 <HOST_NAME> 6 <TIME> 9 <TIME_MS> 13 <MEMORY> 14 <ROWS> SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST; ---replace_column 1 <ID> 3 <HOST_NAME> 6 <TIME> 9 <TIME_MS> +--replace_column 1 <ID> 3 <HOST_NAME> 6 <TIME> 9 <TIME_MS> 13 <MEMORY> 14 <ROWS> SHOW FULL PROCESSLIST; # # Determine the connection id of the current connection (default) @@ -166,7 +166,7 @@ let $wait_condition= SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE COMMAND = 'Sleep' AND USER = 'test_user'; --source include/wait_condition.inc # 1. Just dump what we get ---replace_column 1 <ID> 3 <HOST_NAME> 6 <TIME> 9 <TIME_MS> +--replace_column 1 <ID> 3 <HOST_NAME> 6 <TIME> 9 <TIME_MS> 13 <MEMORY> 14 <ROWS> SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST; --replace_column 1 <ID> 3 <HOST_NAME> 6 <TIME> SHOW FULL PROCESSLIST; @@ -211,7 +211,7 @@ echo # ----- switch to connection con1 (user = test_user) ----- ; connection con1; ---replace_column 1 <ID> 3 <HOST_NAME> 6 <TIME> 9 <TIME_MS> +--replace_column 1 <ID> 3 <HOST_NAME> 6 <TIME> 9 <TIME_MS> 13 <MEMORY> 14 <ROWS> SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST; --replace_column 1 <ID> 3 <HOST_NAME> 6 <TIME> SHOW FULL PROCESSLIST; @@ -245,7 +245,7 @@ echo ; connection con2; # Just dump what we get ---replace_column 1 <ID> 3 <HOST_NAME> 6 <TIME> 9 <TIME_MS> +--replace_column 1 <ID> 3 <HOST_NAME> 6 <TIME> 9 <TIME_MS> 13 <MEMORY> 14 <ROWS> SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST; --replace_column 1 <ID> 3 <HOST_NAME> 6 <TIME> SHOW FULL PROCESSLIST; @@ -305,7 +305,7 @@ WHERE ID = @test_user_con2_id AND Command IN('Query','Execute') AND State = 'User sleep' AND INFO IS NOT NULL ; --source include/wait_condition.inc # 1. Just dump what we get ---replace_column 1 <ID> 3 <HOST_NAME> 6 <TIME> 9 <TIME_MS> +--replace_column 1 <ID> 3 <HOST_NAME> 6 <TIME> 9 <TIME_MS> 13 <MEMORY> 14 <ROWS> SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST; --replace_column 1 <ID> 3 <HOST_NAME> 6 <TIME> SHOW FULL PROCESSLIST; @@ -376,7 +376,7 @@ let $wait_condition= SELECT COUNT(*) FROM INFORMATION_SCHEMA.PROCESSLIST # # Expect to see the state 'Waiting for table metadata lock' for the third # connection because the SELECT collides with the WRITE TABLE LOCK. ---replace_column 1 <ID> 3 <HOST_NAME> 6 <TIME> 9 <TIME_MS> +--replace_column 1 <ID> 3 <HOST_NAME> 6 <TIME> 9 <TIME_MS> 13 <MEMORY> 14 <ROWS> SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST; UNLOCK TABLES; # @@ -435,7 +435,7 @@ echo # SHOW FULL PROCESSLIST Complete statement # SHOW PROCESSLIST statement truncated after 100 char ; ---replace_column 1 <ID> 3 <HOST_NAME> 5 <COMMAND> 6 <TIME> 7 <STATE> 9 <TIME_MS> +--replace_column 1 <ID> 3 <HOST_NAME> 5 <COMMAND> 6 <TIME> 7 <STATE> 9 <TIME_MS> 13 <MEMORY> 14 <ROWS> SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST; --replace_column 1 <ID> 3 <HOST_NAME> 5 <COMMAND> 6 <TIME> 7 <STATE> SHOW FULL PROCESSLIST; diff --git a/mysql-test/suite/funcs_1/r/is_columns_is.result b/mysql-test/suite/funcs_1/r/is_columns_is.result index 4da7eeb2ada..e161e8ed058 100644 --- a/mysql-test/suite/funcs_1/r/is_columns_is.result +++ b/mysql-test/suite/funcs_1/r/is_columns_is.result @@ -221,10 +221,12 @@ def information_schema PLUGINS PLUGIN_TYPE_VERSION 5 NO varchar 20 60 NULL NULL def information_schema PLUGINS PLUGIN_VERSION 2 NO varchar 20 60 NULL NULL NULL utf8 utf8_general_ci varchar(20) select def information_schema PROCESSLIST COMMAND 5 NO varchar 16 48 NULL NULL NULL utf8 utf8_general_ci varchar(16) select def information_schema PROCESSLIST DB 4 NULL YES varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select +def information_schema PROCESSLIST EXAMINED_ROWS 14 0 NO int NULL NULL 10 0 NULL NULL NULL int(7) select def information_schema PROCESSLIST HOST 3 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select def information_schema PROCESSLIST ID 1 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(4) select def information_schema PROCESSLIST INFO 8 NULL YES longtext 4294967295 4294967295 NULL NULL NULL utf8 utf8_general_ci longtext select def information_schema PROCESSLIST MAX_STAGE 11 0 NO tinyint NULL NULL 3 0 NULL NULL NULL tinyint(2) select +def information_schema PROCESSLIST MEMORY_USED 13 0 NO int NULL NULL 10 0 NULL NULL NULL int(7) select def information_schema PROCESSLIST PROGRESS 12 0.000 NO decimal NULL NULL 7 3 NULL NULL NULL decimal(7,3) select def information_schema PROCESSLIST STAGE 10 0 NO tinyint NULL NULL 3 0 NULL NULL NULL tinyint(2) select def information_schema PROCESSLIST STATE 7 NULL YES varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select @@ -699,6 +701,8 @@ NULL information_schema PROCESSLIST TIME_MS decimal NULL NULL NULL NULL decimal( NULL information_schema PROCESSLIST STAGE tinyint NULL NULL NULL NULL tinyint(2) NULL information_schema PROCESSLIST MAX_STAGE tinyint NULL NULL NULL NULL tinyint(2) NULL information_schema PROCESSLIST PROGRESS decimal NULL NULL NULL NULL decimal(7,3) +NULL information_schema PROCESSLIST MEMORY_USED int NULL NULL NULL NULL int(7) +NULL information_schema PROCESSLIST EXAMINED_ROWS int NULL NULL NULL NULL int(7) 3.0000 information_schema REFERENTIAL_CONSTRAINTS CONSTRAINT_CATALOG varchar 512 1536 utf8 utf8_general_ci varchar(512) 3.0000 information_schema REFERENTIAL_CONSTRAINTS CONSTRAINT_SCHEMA varchar 64 192 utf8 utf8_general_ci varchar(64) 3.0000 information_schema REFERENTIAL_CONSTRAINTS CONSTRAINT_NAME varchar 64 192 utf8 utf8_general_ci varchar(64) diff --git a/mysql-test/suite/funcs_1/r/processlist_priv_no_prot.result b/mysql-test/suite/funcs_1/r/processlist_priv_no_prot.result index 2112da6761e..17c88527959 100644 --- a/mysql-test/suite/funcs_1/r/processlist_priv_no_prot.result +++ b/mysql-test/suite/funcs_1/r/processlist_priv_no_prot.result @@ -33,28 +33,30 @@ PROCESSLIST CREATE TEMPORARY TABLE `PROCESSLIST` ( `TIME_MS` decimal(22,3) NOT NULL DEFAULT '0.000', `STAGE` tinyint(2) NOT NULL DEFAULT '0', `MAX_STAGE` tinyint(2) NOT NULL DEFAULT '0', - `PROGRESS` decimal(7,3) NOT NULL DEFAULT '0.000' + `PROGRESS` decimal(7,3) NOT NULL DEFAULT '0.000', + `MEMORY_USED` int(7) NOT NULL DEFAULT '0', + `EXAMINED_ROWS` int(7) NOT NULL DEFAULT '0' ) DEFAULT CHARSET=utf8 SHOW processlist; Id User Host db Command Time State Info Progress ID root HOST_NAME information_schema Query TIME NULL SHOW processlist TIME_MS ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS SELECT * FROM processlist ORDER BY id; -ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS -ID root HOST_NAME information_schema Query TIME executing SELECT * FROM processlist ORDER BY id TIME_MS 0 0 0.000 -ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000 -SELECT ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO, TIME_MS, STAGE, MAX_STAGE, PROGRESS FROM processlist ORDER BY id; -ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS -ID root HOST_NAME information_schema Query TIME executing SELECT ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO, TIME_MS, STAGE, MAX_STAGE, PROGRESS FROM processlist ORDER BY id TIME_MS 0 0 0.000 -ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000 +ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS MEMORY_USED EXAMINED_ROWS +ID root HOST_NAME information_schema Query TIME executing SELECT * FROM processlist ORDER BY id TIME_MS 0 0 0.000 MEMORY ROWS +ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000 MEMORY ROWS +SELECT ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO, TIME_MS, STAGE, MAX_STAGE, PROGRESS, MEMORY_USED, EXAMINED_ROWS FROM processlist ORDER BY id; +ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS MEMORY_USED EXAMINED_ROWS +ID root HOST_NAME information_schema Query TIME executing SELECT ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO, TIME_MS, STAGE, MAX_STAGE, PROGRESS, MEMORY_USED, EXAMINED_ROWS FROM processlist ORDER BY id TIME_MS 0 0 0.000 MEMORY ROWS +ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000 MEMORY ROWS CREATE TEMPORARY TABLE test.t_processlist AS SELECT * FROM processlist; UPDATE test.t_processlist SET user='horst' WHERE id=1 ; INSERT INTO processlist SELECT * FROM test.t_processlist; ERROR 42000: Access denied for user 'root'@'localhost' to database 'information_schema' DROP TABLE test.t_processlist; -CREATE VIEW test.v_processlist (ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO, TIME_MS, STAGE, MAX_STAGE, PROGRESS) AS SELECT * FROM processlist WITH CHECK OPTION; +CREATE VIEW test.v_processlist (ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO, TIME_MS, STAGE, MAX_STAGE, PROGRESS, MEMORY_USED, EXAMINED_ROWS) AS SELECT * FROM processlist WITH CHECK OPTION; ERROR HY000: CHECK OPTION on non-updatable view 'test.v_processlist' -CREATE VIEW test.v_processlist (ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO, TIME_MS, STAGE, MAX_STAGE, PROGRESS) AS SELECT * FROM processlist; +CREATE VIEW test.v_processlist (ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO, TIME_MS, STAGE, MAX_STAGE, PROGRESS, MEMORY_USED, EXAMINED_ROWS) AS SELECT * FROM processlist; DROP VIEW test.v_processlist; UPDATE processlist SET user='any_user' WHERE id=1 ; ERROR 42000: Access denied for user 'root'@'localhost' to database 'information_schema' @@ -106,25 +108,27 @@ PROCESSLIST CREATE TEMPORARY TABLE `PROCESSLIST` ( `TIME_MS` decimal(22,3) NOT NULL DEFAULT '0.000', `STAGE` tinyint(2) NOT NULL DEFAULT '0', `MAX_STAGE` tinyint(2) NOT NULL DEFAULT '0', - `PROGRESS` decimal(7,3) NOT NULL DEFAULT '0.000' + `PROGRESS` decimal(7,3) NOT NULL DEFAULT '0.000', + `MEMORY_USED` int(7) NOT NULL DEFAULT '0', + `EXAMINED_ROWS` int(7) NOT NULL DEFAULT '0' ) DEFAULT CHARSET=utf8 SHOW processlist; Id User Host db Command Time State Info Progress ID ddicttestuser1 HOST_NAME information_schema Query TIME NULL SHOW processlist TIME_MS SELECT * FROM processlist ORDER BY id; -ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS -ID ddicttestuser1 HOST_NAME information_schema Query TIME executing SELECT * FROM processlist ORDER BY id TIME_MS 0 0 0.000 -SELECT ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO, TIME_MS, STAGE, MAX_STAGE, PROGRESS FROM processlist ORDER BY id; -ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS -ID ddicttestuser1 HOST_NAME information_schema Query TIME executing SELECT ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO, TIME_MS, STAGE, MAX_STAGE, PROGRESS FROM processlist ORDER BY id TIME_MS 0 0 0.000 +ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS MEMORY_USED EXAMINED_ROWS +ID ddicttestuser1 HOST_NAME information_schema Query TIME executing SELECT * FROM processlist ORDER BY id TIME_MS 0 0 0.000 MEMORY ROWS +SELECT ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO, TIME_MS, STAGE, MAX_STAGE, PROGRESS, MEMORY_USED, EXAMINED_ROWS FROM processlist ORDER BY id; +ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS MEMORY_USED EXAMINED_ROWS +ID ddicttestuser1 HOST_NAME information_schema Query TIME executing SELECT ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO, TIME_MS, STAGE, MAX_STAGE, PROGRESS, MEMORY_USED, EXAMINED_ROWS FROM processlist ORDER BY id TIME_MS 0 0 0.000 MEMORY ROWS CREATE TEMPORARY TABLE test.t_processlist AS SELECT * FROM processlist; UPDATE test.t_processlist SET user='horst' WHERE id=1 ; INSERT INTO processlist SELECT * FROM test.t_processlist; ERROR 42000: Access denied for user 'ddicttestuser1'@'localhost' to database 'information_schema' DROP TABLE test.t_processlist; -CREATE VIEW test.v_processlist (ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO, TIME_MS, STAGE, MAX_STAGE, PROGRESS) AS SELECT * FROM processlist WITH CHECK OPTION; +CREATE VIEW test.v_processlist (ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO, TIME_MS, STAGE, MAX_STAGE, PROGRESS, MEMORY_USED, EXAMINED_ROWS) AS SELECT * FROM processlist WITH CHECK OPTION; ERROR HY000: CHECK OPTION on non-updatable view 'test.v_processlist' -CREATE VIEW test.v_processlist (ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO, TIME_MS, STAGE, MAX_STAGE, PROGRESS) AS SELECT * FROM processlist; +CREATE VIEW test.v_processlist (ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO, TIME_MS, STAGE, MAX_STAGE, PROGRESS, MEMORY_USED, EXAMINED_ROWS) AS SELECT * FROM processlist; DROP VIEW test.v_processlist; UPDATE processlist SET user='any_user' WHERE id=1 ; ERROR 42000: Access denied for user 'ddicttestuser1'@'localhost' to database 'information_schema' @@ -175,8 +179,8 @@ SHOW processlist; Id User Host db Command Time State Info Progress ID ddicttestuser1 HOST_NAME information_schema Query TIME NULL SHOW processlist TIME_MS SELECT * FROM information_schema.processlist; -ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS -ID ddicttestuser1 HOST_NAME information_schema Query TIME executing SELECT * FROM information_schema.processlist TIME_MS 0 0 0.000 +ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS MEMORY_USED EXAMINED_ROWS +ID ddicttestuser1 HOST_NAME information_schema Query TIME executing SELECT * FROM information_schema.processlist TIME_MS 0 0 0.000 MEMORY ROWS #################################################################################### 4.2 New connection con101 (ddicttestuser1 with PROCESS privilege) SHOW/SELECT shows all processes/threads. @@ -190,10 +194,10 @@ ID root HOST_NAME information_schema Sleep TIME NULL TIME_MS ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS ID ddicttestuser1 HOST_NAME information_schema Query TIME NULL SHOW processlist TIME_MS SELECT * FROM information_schema.processlist; -ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS -ID ddicttestuser1 HOST_NAME information_schema Query TIME executing SELECT * FROM information_schema.processlist TIME_MS 0 0 0.000 -ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000 -ID root HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000 +ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS MEMORY_USED EXAMINED_ROWS +ID ddicttestuser1 HOST_NAME information_schema Query TIME executing SELECT * FROM information_schema.processlist TIME_MS 0 0 0.000 MEMORY ROWS +ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000 MEMORY ROWS +ID root HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000 MEMORY ROWS #################################################################################### 5 Grant PROCESS privilege to anonymous user. connection default (user=root) @@ -214,11 +218,11 @@ ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS ID HOST_NAME information_schema Query TIME NULL SHOW processlist TIME_MS SELECT * FROM information_schema.processlist; -ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS -ID HOST_NAME information_schema Query TIME executing SELECT * FROM information_schema.processlist TIME_MS 0 0 0.000 -ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000 -ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000 -ID root HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000 +ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS MEMORY_USED EXAMINED_ROWS +ID HOST_NAME information_schema Query TIME executing SELECT * FROM information_schema.processlist TIME_MS 0 0 0.000 MEMORY ROWS +ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000 MEMORY ROWS +ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000 MEMORY ROWS +ID root HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000 MEMORY ROWS #################################################################################### 6 Revoke PROCESS privilege from ddicttestuser1 connection default (user=root) @@ -238,10 +242,10 @@ ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS ID ddicttestuser1 HOST_NAME information_schema Query TIME NULL SHOW processlist TIME_MS SELECT * FROM information_schema.processlist; -ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS -ID ddicttestuser1 HOST_NAME information_schema Query TIME executing SELECT * FROM information_schema.processlist TIME_MS 0 0 0.000 -ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000 -ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000 +ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS MEMORY_USED EXAMINED_ROWS +ID ddicttestuser1 HOST_NAME information_schema Query TIME executing SELECT * FROM information_schema.processlist TIME_MS 0 0 0.000 MEMORY ROWS +ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000 MEMORY ROWS +ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000 MEMORY ROWS #################################################################################### 7 Revoke PROCESS privilege from anonymous user connection default (user=root) @@ -256,9 +260,9 @@ SHOW GRANTS FOR ''@'localhost'; Grants for @localhost GRANT USAGE ON *.* TO ''@'localhost' SELECT * FROM information_schema.processlist; -ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS -ID HOST_NAME information_schema Query TIME executing SELECT * FROM information_schema.processlist TIME_MS 0 0 0.000 -ID HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000 +ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS MEMORY_USED EXAMINED_ROWS +ID HOST_NAME information_schema Query TIME executing SELECT * FROM information_schema.processlist TIME_MS 0 0 0.000 MEMORY ROWS +ID HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000 MEMORY ROWS #################################################################################### 8 Grant SUPER (does not imply PROCESS) privilege to ddicttestuser1 connection default (user=root) @@ -278,11 +282,11 @@ ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS ID ddicttestuser1 HOST_NAME information_schema Query TIME NULL SHOW processlist TIME_MS SELECT * FROM information_schema.processlist; -ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS -ID ddicttestuser1 HOST_NAME information_schema Query TIME executing SELECT * FROM information_schema.processlist TIME_MS 0 0 0.000 -ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000 -ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000 -ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000 +ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS MEMORY_USED EXAMINED_ROWS +ID ddicttestuser1 HOST_NAME information_schema Query TIME executing SELECT * FROM information_schema.processlist TIME_MS 0 0 0.000 MEMORY ROWS +ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000 MEMORY ROWS +ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000 MEMORY ROWS +ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000 MEMORY ROWS #################################################################################### 9 Revoke SUPER privilege from user ddicttestuser1 connection default (user=root) @@ -304,12 +308,12 @@ ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS ID ddicttestuser1 HOST_NAME information_schema Query TIME NULL SHOW processlist TIME_MS SELECT * FROM information_schema.processlist; -ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS -ID ddicttestuser1 HOST_NAME information_schema Query TIME executing SELECT * FROM information_schema.processlist TIME_MS 0 0 0.000 -ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000 -ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000 -ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000 -ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000 +ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS MEMORY_USED EXAMINED_ROWS +ID ddicttestuser1 HOST_NAME information_schema Query TIME executing SELECT * FROM information_schema.processlist TIME_MS 0 0 0.000 MEMORY ROWS +ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000 MEMORY ROWS +ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000 MEMORY ROWS +ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000 MEMORY ROWS +ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000 MEMORY ROWS #################################################################################### 10 Grant SUPER privilege with grant option to user ddicttestuser1. connection default (user=root) @@ -358,18 +362,18 @@ ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS ID ddicttestuser2 HOST_NAME information_schema Query TIME NULL SHOW processlist TIME_MS SELECT * FROM information_schema.processlist; -ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS -ID ddicttestuser2 HOST_NAME information_schema Query TIME executing SELECT * FROM information_schema.processlist TIME_MS 0 0 0.000 -ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000 -ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000 -ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000 -ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000 -ID HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000 -ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000 -ID HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000 -ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000 -ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000 -ID root HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000 +ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS MEMORY_USED EXAMINED_ROWS +ID ddicttestuser2 HOST_NAME information_schema Query TIME executing SELECT * FROM information_schema.processlist TIME_MS 0 0 0.000 MEMORY ROWS +ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000 MEMORY ROWS +ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000 MEMORY ROWS +ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000 MEMORY ROWS +ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000 MEMORY ROWS +ID HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000 MEMORY ROWS +ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000 MEMORY ROWS +ID HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000 MEMORY ROWS +ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000 MEMORY ROWS +ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000 MEMORY ROWS +ID root HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000 MEMORY ROWS #################################################################################### 11 User ddicttestuser1 revokes PROCESS privilege from user ddicttestuser2 connection ddicttestuser1; @@ -387,9 +391,9 @@ Id User Host db Command Time State Info Progress ID ddicttestuser2 HOST_NAME information_schema Sleep TIME NULL TIME_MS ID ddicttestuser2 HOST_NAME information_schema Query TIME NULL SHOW processlist TIME_MS SELECT * FROM information_schema.processlist; -ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS -ID ddicttestuser2 HOST_NAME information_schema Query TIME executing SELECT * FROM information_schema.processlist TIME_MS 0 0 0.000 -ID ddicttestuser2 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000 +ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS MEMORY_USED EXAMINED_ROWS +ID ddicttestuser2 HOST_NAME information_schema Query TIME executing SELECT * FROM information_schema.processlist TIME_MS 0 0 0.000 MEMORY ROWS +ID ddicttestuser2 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000 MEMORY ROWS #################################################################################### 11.2 Revoke SUPER,PROCESS,GRANT OPTION privilege from user ddicttestuser1 connection default (user=root) @@ -416,15 +420,15 @@ ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS ID ddicttestuser1 HOST_NAME information_schema Query TIME NULL SHOW processlist TIME_MS SELECT * FROM information_schema.processlist; -ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS -ID ddicttestuser1 HOST_NAME information_schema Query TIME executing SELECT * FROM information_schema.processlist TIME_MS 0 0 0.000 -ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000 -ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000 -ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000 -ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000 -ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000 -ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000 -ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000 +ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS MEMORY_USED EXAMINED_ROWS +ID ddicttestuser1 HOST_NAME information_schema Query TIME executing SELECT * FROM information_schema.processlist TIME_MS 0 0 0.000 MEMORY ROWS +ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000 MEMORY ROWS +ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000 MEMORY ROWS +ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000 MEMORY ROWS +ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000 MEMORY ROWS +ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000 MEMORY ROWS +ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000 MEMORY ROWS +ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000 MEMORY ROWS #################################################################################### 12 Revoke the SELECT privilege from user ddicttestuser1 connection default (user=root) @@ -452,16 +456,16 @@ ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS ID ddicttestuser1 HOST_NAME information_schema Query TIME NULL SHOW processlist TIME_MS SELECT * FROM information_schema.processlist; -ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS -ID ddicttestuser1 HOST_NAME information_schema Query TIME executing SELECT * FROM information_schema.processlist TIME_MS 0 0 0.000 -ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000 -ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000 -ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000 -ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000 -ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000 -ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000 -ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000 -ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000 +ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS MEMORY_USED EXAMINED_ROWS +ID ddicttestuser1 HOST_NAME information_schema Query TIME executing SELECT * FROM information_schema.processlist TIME_MS 0 0 0.000 MEMORY ROWS +ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000 MEMORY ROWS +ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000 MEMORY ROWS +ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000 MEMORY ROWS +ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000 MEMORY ROWS +ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000 MEMORY ROWS +ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000 MEMORY ROWS +ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000 MEMORY ROWS +ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000 MEMORY ROWS #################################################################################### 12.2 Revoke only the SELECT privilege on the information_schema from ddicttestuser1. connection default (user=root) diff --git a/mysql-test/suite/funcs_1/r/processlist_val_no_prot.result b/mysql-test/suite/funcs_1/r/processlist_val_no_prot.result index 0893fa3ca20..9560f77e0da 100644 --- a/mysql-test/suite/funcs_1/r/processlist_val_no_prot.result +++ b/mysql-test/suite/funcs_1/r/processlist_val_no_prot.result @@ -23,14 +23,16 @@ PROCESSLIST CREATE TEMPORARY TABLE `PROCESSLIST` ( `TIME_MS` decimal(22,3) NOT NULL DEFAULT '0.000', `STAGE` tinyint(2) NOT NULL DEFAULT '0', `MAX_STAGE` tinyint(2) NOT NULL DEFAULT '0', - `PROGRESS` decimal(7,3) NOT NULL DEFAULT '0.000' + `PROGRESS` decimal(7,3) NOT NULL DEFAULT '0.000', + `MEMORY_USED` int(7) NOT NULL DEFAULT '0', + `EXAMINED_ROWS` int(7) NOT NULL DEFAULT '0' ) DEFAULT CHARSET=utf8 # Ensure that the information about the own connection is correct. #-------------------------------------------------------------------------- SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST; -ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS -<ID> root <HOST_NAME> test Query <TIME> executing SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST <TIME_MS> 0 0 0.000 +ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS MEMORY_USED EXAMINED_ROWS +<ID> root <HOST_NAME> test Query <TIME> executing SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST <TIME_MS> 0 0 0.000 <MEMORY> <ROWS> SHOW FULL PROCESSLIST; Id User Host db Command Time State Info Progress <ID> root <HOST_NAME> test Query <TIME> NULL SHOW FULL PROCESSLIST <TIME_MS> @@ -76,9 +78,9 @@ Has TIME a reasonable value? # Poll till the connection con1 is in state COMMAND = 'Sleep'. SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST; -ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS -<ID> test_user <HOST_NAME> information_schema Sleep <TIME> NULL <TIME_MS> 0 0 0.000 -<ID> root <HOST_NAME> information_schema Query <TIME> executing SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST <TIME_MS> 0 0 0.000 +ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS MEMORY_USED EXAMINED_ROWS +<ID> test_user <HOST_NAME> information_schema Sleep <TIME> NULL <TIME_MS> 0 0 0.000 <MEMORY> <ROWS> +<ID> root <HOST_NAME> information_schema Query <TIME> executing SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST <TIME_MS> 0 0 0.000 <MEMORY> <ROWS> SHOW FULL PROCESSLIST; Id User Host db Command Time State Info Progress <ID> root <HOST_NAME> information_schema Query <TIME> NULL SHOW FULL PROCESSLIST 0.000 @@ -110,8 +112,8 @@ Expect 1 # ----- switch to connection con1 (user = test_user) ----- SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST; -ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS -<ID> test_user <HOST_NAME> information_schema Query <TIME> executing SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST <TIME_MS> 0 0 0.000 +ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS MEMORY_USED EXAMINED_ROWS +<ID> test_user <HOST_NAME> information_schema Query <TIME> executing SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST <TIME_MS> 0 0 0.000 <MEMORY> <ROWS> SHOW FULL PROCESSLIST; Id User Host db Command Time State Info Progress <ID> test_user <HOST_NAME> information_schema Query <TIME> NULL SHOW FULL PROCESSLIST 0.000 @@ -127,9 +129,9 @@ Id User Host db Command Time State Info Progress # ----- switch to connection con2 (user = test_user) ----- SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST; -ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS -<ID> test_user <HOST_NAME> information_schema Query <TIME> executing SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST <TIME_MS> 0 0 0.000 -<ID> test_user <HOST_NAME> information_schema Sleep <TIME> NULL <TIME_MS> 0 0 0.000 +ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS MEMORY_USED EXAMINED_ROWS +<ID> test_user <HOST_NAME> information_schema Query <TIME> executing SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST <TIME_MS> 0 0 0.000 <MEMORY> <ROWS> +<ID> test_user <HOST_NAME> information_schema Sleep <TIME> NULL <TIME_MS> 0 0 0.000 <MEMORY> <ROWS> SHOW FULL PROCESSLIST; Id User Host db Command Time State Info Progress <ID> test_user <HOST_NAME> information_schema Sleep <TIME> NULL 0.000 @@ -153,10 +155,10 @@ SELECT sleep(10), 17; # Poll till connection con2 is in state 'User sleep'. SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST; -ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS -<ID> test_user <HOST_NAME> information_schema Query <TIME> User sleep SELECT sleep(10), 17 <TIME_MS> 0 0 0.000 -<ID> test_user <HOST_NAME> information_schema Sleep <TIME> NULL <TIME_MS> 0 0 0.000 -<ID> root <HOST_NAME> information_schema Query <TIME> executing SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST <TIME_MS> 0 0 0.000 +ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS MEMORY_USED EXAMINED_ROWS +<ID> test_user <HOST_NAME> information_schema Query <TIME> User sleep SELECT sleep(10), 17 <TIME_MS> 0 0 0.000 <MEMORY> <ROWS> +<ID> test_user <HOST_NAME> information_schema Sleep <TIME> NULL <TIME_MS> 0 0 0.000 <MEMORY> <ROWS> +<ID> root <HOST_NAME> information_schema Query <TIME> executing SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST <TIME_MS> 0 0 0.000 <MEMORY> <ROWS> SHOW FULL PROCESSLIST; Id User Host db Command Time State Info Progress <ID> root <HOST_NAME> information_schema Query <TIME> NULL SHOW FULL PROCESSLIST 0.000 @@ -200,10 +202,10 @@ SELECT COUNT(*) FROM test.t1; # Poll till INFO is no more NULL and State = 'Waiting for table metadata lock'. SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST; -ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS -<ID> test_user <HOST_NAME> information_schema Query <TIME> Waiting for table metadata lock SELECT COUNT(*) FROM test.t1 <TIME_MS> 0 0 0.000 -<ID> test_user <HOST_NAME> information_schema Sleep <TIME> NULL <TIME_MS> 0 0 0.000 -<ID> root <HOST_NAME> information_schema Query <TIME> executing SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST <TIME_MS> 0 0 0.000 +ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS MEMORY_USED EXAMINED_ROWS +<ID> test_user <HOST_NAME> information_schema Query <TIME> Waiting for table metadata lock SELECT COUNT(*) FROM test.t1 <TIME_MS> 0 0 0.000 <MEMORY> <ROWS> +<ID> test_user <HOST_NAME> information_schema Sleep <TIME> NULL <TIME_MS> 0 0 0.000 <MEMORY> <ROWS> +<ID> root <HOST_NAME> information_schema Query <TIME> executing SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST <TIME_MS> 0 0 0.000 <MEMORY> <ROWS> UNLOCK TABLES; # ----- switch to connection con2 (user = test_user) ----- @@ -234,10 +236,10 @@ SELECT count(*),'BEGIN-This is the representative of a very long statement.This # SHOW PROCESSLIST statement truncated after 100 char SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST; -ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS -<ID> test_user <HOST_NAME> information_schema <COMMAND> <TIME> <STATE> SELECT count(*),'BEGIN-This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.-END' AS "Long string" FROM test.t1 <TIME_MS> 0 0 0.000 -<ID> test_user <HOST_NAME> information_schema <COMMAND> <TIME> <STATE> NULL <TIME_MS> 0 0 0.000 -<ID> root <HOST_NAME> information_schema <COMMAND> <TIME> <STATE> SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST <TIME_MS> 0 0 0.000 +ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS MEMORY_USED EXAMINED_ROWS +<ID> test_user <HOST_NAME> information_schema <COMMAND> <TIME> <STATE> SELECT count(*),'BEGIN-This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.-END' AS "Long string" FROM test.t1 <TIME_MS> 0 0 0.000 <MEMORY> <ROWS> +<ID> test_user <HOST_NAME> information_schema <COMMAND> <TIME> <STATE> NULL <TIME_MS> 0 0 0.000 <MEMORY> <ROWS> +<ID> root <HOST_NAME> information_schema <COMMAND> <TIME> <STATE> SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST <TIME_MS> 0 0 0.000 <MEMORY> <ROWS> SHOW FULL PROCESSLIST; Id User Host db Command Time State Info Progress <ID> root <HOST_NAME> information_schema <COMMAND> <TIME> <STATE> SHOW FULL PROCESSLIST 0.000 diff --git a/mysql-test/suite/sys_vars/t/transaction_prealloc_size_bug27322.test b/mysql-test/suite/sys_vars/t/transaction_prealloc_size_bug27322.test index 58098f4c879..b55388d7c4f 100644 --- a/mysql-test/suite/sys_vars/t/transaction_prealloc_size_bug27322.test +++ b/mysql-test/suite/sys_vars/t/transaction_prealloc_size_bug27322.test @@ -6,7 +6,7 @@ # The test would allocate and initialize 5GB of memory # if compiled with debug. It can take a lot of time # of for paging/swapping. ---source include/not_debug.inc +#--source include/not_debug.inc # # Bug#27322 failure to allocate transaction_prealloc_size causes crash diff --git a/mysql-test/t/file_contents.test b/mysql-test/t/file_contents.test index 835ea563c7b..d54a60e62a3 100644 --- a/mysql-test/t/file_contents.test +++ b/mysql-test/t/file_contents.test @@ -42,8 +42,8 @@ if ($dir_bin eq '/usr/') { $dir_docs = "$dir_docs/Docs"; # development tree } } -$found_version = "No line 'MySQL source #.#.#'"; -$found_revision = "No line 'revision-id: .....'"; +$found_version = "No line 'MySQL source #.#.#' in $dir_docs/INFO_SRC"; +$found_revision = "No line 'revision-id: .....' in $dir_docs/INFO_SRC"; open(I_SRC,"<","$dir_docs/INFO_SRC") or print "Cannot open 'INFO_SRC' in '$dir_docs' (starting from bindir '$dir_bin')\n"; while(defined ($line = <I_SRC>)) { if ($line =~ m|^MySQL source \d+\.\d\.\d+|) {$found_version = "Found MySQL version number";} diff --git a/mysql-test/t/show_explain.test b/mysql-test/t/show_explain.test index ee2eccbc95f..2df9df65996 100644 --- a/mysql-test/t/show_explain.test +++ b/mysql-test/t/show_explain.test @@ -8,6 +8,7 @@ drop table if exists t0, t1, t2, t3, t4; drop view if exists v1; --enable_warnings +SET @old_debug= @@session.debug; # # Testcases in this file do not work with embedded server. The reason for this @@ -56,6 +57,7 @@ let $thr1=`select connection_id()`; connect (con1, localhost, root,,); connection con1; let $thr2=`select connection_id()`; +SET @old_debug= @@session.debug; connection default; # SHOW EXPLAIN FOR <idle thread> @@ -73,7 +75,7 @@ let $wait_condition= select State='show_explain_trap' from information_schema.pr # connection con1; set @show_explain_probe_select_id=1; -set debug_dbug='d,show_explain_probe_join_exec_start'; +set debug_dbug='+d,show_explain_probe_join_exec_start'; send select count(*) from t1 where a < 100000; connection default; @@ -101,95 +103,102 @@ evalp show explain for $thr2; connection con1; reap; set optimizer_switch= @show_expl_tmp; - +set debug_dbug=@old_debug; --echo # UNION, first branch set @show_explain_probe_select_id=1; -set debug_dbug='d,show_explain_probe_join_exec_start'; +set debug_dbug='+d,show_explain_probe_join_exec_start'; send explain select a from t0 A union select a+1 from t0 B; connection default; --source include/wait_condition.inc evalp show explain for $thr2; connection con1; reap; +set debug_dbug=@old_debug; --echo # UNION, second branch set @show_explain_probe_select_id=1; -set debug_dbug='d,show_explain_probe_join_exec_start'; +set debug_dbug='+d,show_explain_probe_join_exec_start'; send explain select a from t0 A union select a+1 from t0 B; connection default; --source include/wait_condition.inc evalp show explain for $thr2; connection con1; reap; +set debug_dbug=@old_debug; --echo # Uncorrelated subquery, select set @show_explain_probe_select_id=1; -set debug_dbug='d,show_explain_probe_join_exec_start'; +set debug_dbug='+d,show_explain_probe_join_exec_start'; send select a, (select max(a) from t0 B) from t0 A where a<1; connection default; --source include/wait_condition.inc evalp show explain for $thr2; connection con1; reap; +set debug_dbug=@old_debug; --echo # Uncorrelated subquery, explain set @show_explain_probe_select_id=1; -set debug_dbug='d,show_explain_probe_join_exec_start'; +set debug_dbug='+d,show_explain_probe_join_exec_start'; send explain select a, (select max(a) from t0 B) from t0 A where a<1; connection default; --source include/wait_condition.inc evalp show explain for $thr2; connection con1; reap; +set debug_dbug=@old_debug; --echo # correlated subquery, select set @show_explain_probe_select_id=1; -set debug_dbug='d,show_explain_probe_join_exec_start'; +set debug_dbug='+d,show_explain_probe_join_exec_start'; send select a, (select max(a) from t0 b where b.a+a.a<10) from t0 a where a<1; connection default; --source include/wait_condition.inc evalp show explain for $thr2; connection con1; reap; +set debug_dbug=@old_debug; --echo # correlated subquery, explain set @show_explain_probe_select_id=1; -set debug_dbug='d,show_explain_probe_join_exec_start'; +set debug_dbug='+d,show_explain_probe_join_exec_start'; send select a, (select max(a) from t0 b where b.a+a.a<10) from t0 a where a<1; connection default; --source include/wait_condition.inc evalp show explain for $thr2; connection con1; reap; +set debug_dbug=@old_debug; --echo # correlated subquery, select, while inside the subquery set @show_explain_probe_select_id=2; # <--- -set debug_dbug='d,show_explain_probe_join_exec_start'; +set debug_dbug='+d,show_explain_probe_join_exec_start'; send select a, (select max(a) from t0 b where b.a+a.a<10) from t0 a where a<1; connection default; --source include/wait_condition.inc evalp show explain for $thr2; connection con1; reap; +set debug_dbug=@old_debug; --echo # correlated subquery, explain, while inside the subquery set @show_explain_probe_select_id=2; -set debug_dbug='d,show_explain_probe_join_exec_start'; +set debug_dbug='+d,show_explain_probe_join_exec_start'; send select a, (select max(a) from t0 b where b.a+a.a<10) from t0 a where a<1; connection default; --source include/wait_condition.inc evalp show explain for $thr2; connection con1; reap; - +set debug_dbug=@old_debug; --echo # correlated subquery, explain, while inside the subquery set @show_explain_probe_select_id=1; -set debug_dbug='d,show_explain_probe_join_exec_end'; +set debug_dbug='+d,show_explain_probe_join_exec_end'; send select a, (select max(a) from t0 b where b.a+a.a<10) from t0 a where a<1; connection default; --source include/wait_condition.inc @@ -197,6 +206,7 @@ connection default; evalp show explain for $thr2; connection con1; reap; +set debug_dbug=@old_debug; # TODO: explain in the parent subuqery when the un-correlated child has been # run (and have done irreversible cleanups) @@ -209,7 +219,7 @@ reap; --echo # I've found experimentally that select_id==2 here... --echo # set @show_explain_probe_select_id=2; -set debug_dbug='d,show_explain_probe_join_exec_start'; +set debug_dbug='+d,show_explain_probe_join_exec_start'; send set @foo= (select max(a) from t0 where sin(a) >0); connection default; --source include/wait_condition.inc @@ -217,13 +227,14 @@ connection default; evalp show explain for $thr2; connection con1; reap; +set debug_dbug=@old_debug; --echo # --echo # Attempt SHOW EXPLAIN for an UPDATE --echo # create table t2 as select a as a, a as dummy from t0 limit 2; set @show_explain_probe_select_id=2; -set debug_dbug='d,show_explain_probe_join_exec_start'; +set debug_dbug='+d,show_explain_probe_join_exec_start'; send update t2 set dummy=0 where (select max(a) from t0 where t2.a + t0.a <3) >3 ; connection default; --source include/wait_condition.inc @@ -234,13 +245,14 @@ evalp show explain for $thr2; connection con1; reap; drop table t2; +set debug_dbug=@old_debug; --echo # --echo # Attempt SHOW EXPLAIN for a DELETE --echo # create table t2 as select a as a, a as dummy from t0 limit 2; set @show_explain_probe_select_id=2; -set debug_dbug='d,show_explain_probe_join_exec_start'; +set debug_dbug='+d,show_explain_probe_join_exec_start'; send delete from t2 where (select max(a) from t0 where t2.a + t0.a <3) >3 ; connection default; --source include/wait_condition.inc @@ -251,14 +263,14 @@ evalp show explain for $thr2; connection con1; reap; drop table t2; - +set debug_dbug=@old_debug; --echo # --echo # Multiple SHOW EXPLAIN calls for one select --echo # create table t2 as select a as a, a as dummy from t0 limit 3; set @show_explain_probe_select_id=2; -set debug_dbug='d,show_explain_probe_join_exec_start'; +set debug_dbug='+d,show_explain_probe_join_exec_start'; send select t2.a, ((select max(a) from t0 where t2.a + t0.a <3) >3) as SUBQ from t2; connection default; --source include/wait_condition.inc @@ -268,13 +280,14 @@ evalp show explain for $thr2; connection con1; reap; drop table t2; +set debug_dbug=@old_debug; --echo # --echo # SHOW EXPLAIN for SELECT ... ORDER BY with "Using filesort" --echo # explain select * from t0 order by a; -set debug_dbug='d,show_explain_probe_join_exec_start'; +set debug_dbug='+d,show_explain_probe_join_exec_start'; set @show_explain_probe_select_id=1; send select * from t0 order by a; connection default; @@ -282,6 +295,7 @@ connection default; evalp show explain for $thr2; connection con1; reap; +set debug_dbug=@old_debug; --echo # --echo # SHOW EXPLAIN for SELECT ... with "Using temporary" @@ -290,7 +304,7 @@ connection default; explain select distinct a from t0; connection con1; -set debug_dbug='d,show_explain_probe_join_exec_start'; +set debug_dbug='+d,show_explain_probe_join_exec_start'; set @show_explain_probe_select_id=1; send select distinct a from t0; connection default; @@ -298,6 +312,7 @@ connection default; evalp show explain for $thr2; connection con1; reap; +set debug_dbug=@old_debug; --echo # --echo # SHOW EXPLAIN for SELECT ... with "Using temporary; Using filesort" @@ -306,7 +321,7 @@ connection default; explain select distinct a from t0; connection con1; -set debug_dbug='d,show_explain_probe_join_exec_start'; +set debug_dbug='+d,show_explain_probe_join_exec_start'; set @show_explain_probe_select_id=1; send select distinct a from t0; connection default; @@ -314,7 +329,7 @@ connection default; evalp show explain for $thr2; connection con1; reap; -set debug_dbug=''; +set debug_dbug=@old_debug; --echo # --echo # MDEV-238: SHOW EXPLAIN: Server crashes in JOIN::print_explain with FROM subquery and GROUP BY @@ -323,7 +338,7 @@ CREATE TABLE t2 ( a INT ); INSERT INTO t2 VALUES (1),(2),(1),(4),(2); explain SELECT alias.a FROM t2, ( SELECT * FROM t2 ) AS alias GROUP BY alias.a; -set debug_dbug='d,show_explain_in_find_all_keys'; +set debug_dbug='+d,show_explain_in_find_all_keys'; send SELECT alias.a FROM t2, ( SELECT * FROM t2 ) AS alias GROUP BY alias.a; connection default; @@ -334,7 +349,7 @@ connection default; evalp show explain for $thr2; connection con1; reap; -set debug_dbug=''; +set debug_dbug=@old_debug; DROP TABLE t2; @@ -350,7 +365,7 @@ INSERT INTO t2 VALUES (1),(2),(1),(4),(2); EXPLAIN EXTENDED SELECT alias.a FROM t2, ( SELECT * FROM t2 ) AS alias GROUP BY alias.a ; set @show_explain_probe_select_id=1; -set debug_dbug='d,show_explain_probe_join_exec_end'; +set debug_dbug='+d,show_explain_probe_join_exec_end'; send EXPLAIN EXTENDED SELECT alias.a FROM t2, ( SELECT * FROM t2 ) AS alias GROUP BY alias.a ; connection default; @@ -358,7 +373,7 @@ connection default; evalp show explain for $thr2; connection con1; reap; -set debug_dbug=''; +set debug_dbug=@old_debug; DROP TABLE t2; @@ -374,7 +389,7 @@ INSERT INTO t2 VALUES (4),(5),(6),(7),(8),(9); explain SELECT * FROM v1, t2; set @show_explain_probe_select_id=2; -set debug_dbug='d,show_explain_probe_join_exec_end'; +set debug_dbug='+d,show_explain_probe_join_exec_end'; send SELECT * FROM v1, t2; connection default; @@ -383,7 +398,7 @@ connection default; evalp show explain for $thr2; connection con1; reap; -set debug_dbug=''; +set debug_dbug=@old_debug; DROP VIEW v1; DROP TABLE t2, t3; @@ -391,21 +406,21 @@ DROP TABLE t2, t3; --echo # MDEV-267: SHOW EXPLAIN: Server crashes in JOIN::print_explain on most of queries --echo # set @show_explain_probe_select_id=1; -set debug_dbug='d,show_explain_probe_join_exec_end'; +set debug_dbug='+d,show_explain_probe_join_exec_end'; send select sleep(1); connection default; --source include/wait_condition.inc evalp show explain for $thr2; connection con1; reap; -set debug_dbug=''; +set debug_dbug=@old_debug; --echo # --echo # Same as above, but try another reason for JOIN to be degenerate --echo # set @show_explain_probe_select_id=1; -set debug_dbug='d,show_explain_probe_join_exec_end'; +set debug_dbug='+d,show_explain_probe_join_exec_end'; send select * from t0 where 1>10; connection default; --source include/wait_condition.inc @@ -413,7 +428,7 @@ connection default; evalp show explain for $thr2; connection con1; reap; -set debug_dbug=''; +set debug_dbug=@old_debug; --echo # --echo # Same as above, but try another reason for JOIN to be degenerate (2) @@ -421,7 +436,7 @@ set debug_dbug=''; create table t3(a int primary key); insert into t3 select a from t0; set @show_explain_probe_select_id=1; -set debug_dbug='d,show_explain_probe_join_exec_end'; +set debug_dbug='+d,show_explain_probe_join_exec_end'; send select * from t0,t3 where t3.a=112233; connection default; --source include/wait_condition.inc @@ -429,7 +444,7 @@ connection default; evalp show explain for $thr2; connection con1; reap; -set debug_dbug=''; +set debug_dbug=@old_debug; drop table t3; --echo # @@ -448,7 +463,7 @@ explain SELECT * FROM t2 WHERE a = ); set @show_explain_probe_select_id=2; -set debug_dbug='d,show_explain_probe_do_select'; +set debug_dbug='+d,show_explain_probe_do_select'; send SELECT * FROM t2 WHERE a = (SELECT MAX(a) FROM t2 WHERE pk= (SELECT MAX(pk) FROM t2 WHERE pk = 3) @@ -458,7 +473,7 @@ connection default; evalp show explain for $thr2; connection con1; reap; -set debug_dbug=''; +set debug_dbug=@old_debug; drop table t2; @@ -491,7 +506,7 @@ WHERE a1 < ALL ( ); set @show_explain_probe_select_id=1; -set debug_dbug='d,show_explain_probe_do_select'; +set debug_dbug='+d,show_explain_probe_do_select'; send SELECT count(*) FROM t2, t3 WHERE a1 < ALL ( @@ -504,7 +519,7 @@ connection default; evalp show explain for $thr2; connection con1; reap; -set debug_dbug=''; +set debug_dbug=@old_debug; drop table t2, t3, t4; --echo # @@ -516,7 +531,7 @@ INSERT INTO t2 VALUES (11,23),(12,3),(13,45),(14,16),(15,2),(16,33),(17,2),(18,5),(19,9),(20,2); set @show_explain_probe_select_id=1; -set debug_dbug='d,show_explain_probe_join_exec_end'; +set debug_dbug='+d,show_explain_probe_join_exec_end'; send SELECT * FROM t2 WHERE (5, 78) IN (SELECT `a1`, MAX(`a1`) FROM t2 GROUP BY `a1`); connection default; @@ -525,10 +540,9 @@ connection default; evalp show explain for $thr2; connection con1; reap; -set debug_dbug=''; +set debug_dbug=@old_debug; DROP TABLE t2; - DROP TABLE t1; --echo # @@ -538,7 +552,7 @@ CREATE TABLE t1(a INT, KEY(a)); INSERT INTO t1 VALUES (3),(1),(5),(1); set @show_explain_probe_select_id=1; -set debug_dbug='d,show_explain_probe_join_exec_start'; +set debug_dbug='+d,show_explain_probe_join_exec_start'; send SELECT 'test' FROM t1 WHERE a=1; connection default; @@ -546,7 +560,7 @@ connection default; evalp show explain for $thr2; connection con1; reap; -set debug_dbug=''; +set debug_dbug=@old_debug; DROP TABLE t1; @@ -570,7 +584,7 @@ set join_cache_level=0; explain select count(*) from t1 A, t1 B where B.key1 < A.col2 and A.col1=3 AND B.col2 + 1 < 100; set @show_explain_probe_select_id=1; -set debug_dbug='d,show_explain_probe_test_if_quick_select'; +set debug_dbug='+d,show_explain_probe_test_if_quick_select'; send select count(*) from t1 A, t1 B where B.key1 < A.col2 and A.col1=3 AND B.col2 + 1 < 100; @@ -587,7 +601,7 @@ evalp show explain for $thr2; connection con1; reap; -set debug_dbug=''; +set debug_dbug=@old_debug; drop table t1; --echo # @@ -598,7 +612,7 @@ CREATE TABLE t1(a INT, b INT, c INT, KEY(a), KEY(b), KEY(c)); INSERT INTO t1 (a) VALUES (3),(1),(5),(1); set @show_explain_probe_select_id=1; -set debug_dbug='d,show_explain_probe_join_exec_start'; +set debug_dbug='+d,show_explain_probe_join_exec_start'; send SHOW INDEX FROM t1; connection default; @@ -606,7 +620,7 @@ connection default; evalp show explain for $thr2; connection con1; reap; -set debug_dbug=''; +set debug_dbug=@old_debug; DROP TABLE t1; @@ -620,7 +634,7 @@ CREATE ALGORITHM=TEMPTABLE VIEW v1 AS SELECT * FROM t1; EXPLAIN SELECT a + 1 FROM v1; -set debug_dbug='d,show_explain_probe_join_tab_preread'; +set debug_dbug='+d,show_explain_probe_join_tab_preread'; set @show_explain_probe_select_id=1; send @@ -630,7 +644,7 @@ connection default; evalp show explain for $thr2; connection con1; reap; -set debug_dbug=''; +set debug_dbug=@old_debug; DROP VIEW v1; DROP TABLE t1; @@ -646,7 +660,7 @@ INSERT INTO t1 VALUES (4),(6); EXPLAIN SELECT a FROM t1 WHERE a IN ( SELECT 1+SLEEP(0.01) UNION SELECT 2 ); -set debug_dbug='d,show_explain_probe_union_read'; +set debug_dbug='+d,show_explain_probe_union_read'; send SELECT a FROM t1 WHERE a IN ( SELECT 1+SLEEP(0.01) UNION SELECT 2 ); @@ -660,8 +674,7 @@ evalp show explain for $thr2; connection con1; reap; -set debug_dbug=''; - +set debug_dbug=@old_debug; DROP TABLE t1; --echo # @@ -683,7 +696,7 @@ SELECT * FROM t1, ( SELECT * FROM t2 ) AS alias WHERE a < ALL ( SELECT b FROM t1, t2 WHERE a = b ); set @show_explain_probe_select_id=1; -set debug_dbug='d,show_explain_probe_join_exec_start'; +set debug_dbug='+d,show_explain_probe_join_exec_start'; --send SELECT * FROM t1, ( SELECT * FROM t2 ) AS alias WHERE a < ALL ( SELECT b FROM t1, t2 WHERE a = b ); @@ -694,7 +707,7 @@ evalp show explain for $thr2; connection con1; reap; -set debug_dbug=''; +set debug_dbug=@old_debug; DROP TABLE t1, t2; --echo # @@ -717,7 +730,7 @@ insert into t3 select * from t4; explain select distinct t1.a from t1,t3 where t1.a=t3.a; set @show_explain_probe_select_id=1; -set debug_dbug='d,show_explain_probe_join_exec_start'; +set debug_dbug='+d,show_explain_probe_join_exec_start'; --send select distinct t1.a from t1,t3 where t1.a=t3.a; connection default; @@ -726,7 +739,7 @@ evalp show explain for $thr2; connection con1; reap; -set debug_dbug=''; +set debug_dbug=@old_debug; drop table t1,t3,t4; @@ -744,7 +757,7 @@ connection con1; --echo # First, make sure that user 'test2' cannot do SHOW EXPLAIN on us --echo # set @show_explain_probe_select_id=1; -set debug_dbug='d,show_explain_probe_join_exec_start'; +set debug_dbug='+d,show_explain_probe_join_exec_start'; send select * from t0 where a < 3; @@ -760,7 +773,7 @@ evalp show explain for $thr2; connection con1; reap; -set debug_dbug=''; +set debug_dbug=@old_debug; --echo # --echo # Check that user test2 can do SHOW EXPLAIN on its own queries @@ -770,7 +783,7 @@ connect (con3, localhost, test2,,); connection con2; let $thr_con2=`select connection_id()`; set @show_explain_probe_select_id=1; -set debug_dbug='d,show_explain_probe_join_exec_start'; +set debug_dbug='+d,show_explain_probe_join_exec_start'; send select * from t0 where a < 3; @@ -796,9 +809,10 @@ disconnect con2; grant process on *.* to test2@localhost; connect (con2, localhost, test2,,); connection con1; +set debug_dbug=@old_debug; set @show_explain_probe_select_id=1; -set debug_dbug='d,show_explain_probe_join_exec_start'; +set debug_dbug='+d,show_explain_probe_join_exec_start'; send select * from t0 where a < 3; @@ -810,7 +824,7 @@ evalp show explain for $thr2; connection con1; reap; -set debug_dbug=''; +set debug_dbug=@old_debug; revoke all privileges on test.* from test2@localhost; drop user test2@localhost; @@ -890,7 +904,7 @@ WHERE a IN ( 255, 0 ) OR b BETWEEN 6 AND 129 ORDER BY b; set @show_explain_probe_select_id=1; -set debug_dbug='d,show_explain_probe_join_exec_start'; +set debug_dbug='+d,show_explain_probe_join_exec_start'; --send SELECT a+SLEEP(0.01) FROM t1 WHERE a IN ( 255, 0 ) OR b BETWEEN 6 AND 129 @@ -902,9 +916,10 @@ evalp show explain for $thr2; connection con1; reap; +set debug_dbug=@old_debug; set @show_explain_probe_select_id=1; -set debug_dbug='d,show_explain_probe_do_select'; +set debug_dbug='+d,show_explain_probe_do_select'; --send SELECT a+SLEEP(0.01) FROM t1 WHERE a IN ( 255, 0 ) OR b BETWEEN 6 AND 129 @@ -917,7 +932,7 @@ evalp show explain for $thr2; connection con1; reap; -set debug_dbug=''; +set debug_dbug=@old_debug; drop table t1; @@ -933,7 +948,7 @@ INSERT INTO t1 SELECT t11.a FROM t1 t11, t1 t12, t1 t13; EXPLAIN SELECT a FROM t1 GROUP BY a; set @show_explain_probe_select_id=1; -set debug_dbug='d,show_explain_probe_join_exec_start'; +set debug_dbug='+d,show_explain_probe_join_exec_start'; --send SELECT a FROM t1 GROUP BY a; @@ -944,7 +959,7 @@ evalp show explain for $thr2; connection con1; reap; -set debug_dbug=''; +set debug_dbug=@old_debug; drop table t1; @@ -960,7 +975,7 @@ INSERT INTO t2 VALUES (86,'English'),(87,'Russian'); explain SELECT SUM(a + SLEEP(0.1)) FROM t1 WHERE a IN ( SELECT c FROM t2 WHERE d < b ) OR b < 's'; set @show_explain_probe_select_id=1; -set debug_dbug='d,show_explain_probe_join_exec_start'; +set debug_dbug='+d,show_explain_probe_join_exec_start'; --send SELECT SUM(a + SLEEP(0.1)) FROM t1 WHERE a IN ( SELECT c FROM t2 WHERE d < b ) OR b < 's'; @@ -971,8 +986,7 @@ evalp show explain for $thr2; connection con1; reap; -set debug_dbug=''; - +set debug_dbug=@old_debug; drop table t1, t2; --echo # @@ -1011,7 +1025,7 @@ explain SELECT b AS field1, b AS field2 FROM t1, t2, t3 WHERE d = b ORDER BY field1, field2; set @show_explain_probe_select_id=1; -set debug_dbug='d,show_explain_probe_do_select'; +set debug_dbug='+d,show_explain_probe_do_select'; send SELECT b AS field1, b AS field2 FROM t1, t2, t3 WHERE d = b ORDER BY field1, field2; @@ -1023,7 +1037,7 @@ evalp show explain for $thr2; connection con1; reap; -set debug_dbug=''; +set debug_dbug=@old_debug; DROP TABLE t1,t2,t3; @@ -1047,7 +1061,7 @@ SELECT max(a+b+c) FROM t1 AS alias1, ( SELECT * FROM t2 ) AS alias WHERE EXISTS ( SELECT * FROM t3 WHERE b = c ) OR a <= 10; set @show_explain_probe_select_id=1; -set debug_dbug='d,show_explain_probe_join_exec_start'; +set debug_dbug='+d,show_explain_probe_join_exec_start'; send SELECT max(a+b+c) FROM t1 AS alias1, ( SELECT * FROM t2 ) AS alias @@ -1060,8 +1074,7 @@ evalp show explain for $thr2; connection con1; reap; -set debug_dbug=''; - +set debug_dbug=@old_debug; DROP TABLE t1,t2,t3; --echo # @@ -1088,7 +1101,7 @@ select charset('ãû'); select hex('ãû'); set @show_explain_probe_select_id=1; -set debug_dbug='d,show_explain_probe_join_exec_start'; +set debug_dbug='+d,show_explain_probe_join_exec_start'; send select * from t0 where length('ãû') = a; @@ -1103,7 +1116,7 @@ connection con1; # The constant should be two letters, the last looking like 'bl' reap; -set debug_dbug=''; +set debug_dbug=@old_debug; set names default; --echo # diff --git a/mysql-test/t/user_var.test b/mysql-test/t/user_var.test index c6c4e4d9d2f..b815c825b75 100644 --- a/mysql-test/t/user_var.test +++ b/mysql-test/t/user_var.test @@ -452,4 +452,19 @@ SELECT DISTINCT POW(COUNT(distinct a), @a:=(SELECT 1 FROM t1 LEFT JOIN t1 AS t2 SELECT @a; DROP TABLE t1; +--echo # +--echo # Check that used memory extends if we set a variable +--echo # + +# Execute twice so number stablizes a bit +let $tmp= `select memory_used from information_schema.processlist`; +let $tmp= `select memory_used from information_schema.processlist`; +set @var= repeat('a',20000); +let $tmp2= `select memory_used from information_schema.processlist`; +--disable_query_log +--disable_column_names +eval select $tmp < $tmp2; +--enable_column_names +--enable_query_log + --echo End of 5.5 tests diff --git a/mysys/array.c b/mysys/array.c index c969da83586..5aa1b1abb88 100644 --- a/mysys/array.c +++ b/mysys/array.c @@ -28,6 +28,7 @@ init_buffer Initial buffer pointer init_alloc Number of initial elements alloc_increment Increment for adding new elements + my_flags Flags to my_malloc DESCRIPTION init_dynamic_array() initiates array and allocate space for @@ -42,7 +43,7 @@ my_bool init_dynamic_array2(DYNAMIC_ARRAY *array, uint element_size, void *init_buffer, uint init_alloc, - uint alloc_increment) + uint alloc_increment, myf my_flags) { DBUG_ENTER("init_dynamic_array2"); if (!alloc_increment) @@ -55,6 +56,7 @@ my_bool init_dynamic_array2(DYNAMIC_ARRAY *array, uint element_size, array->max_element=init_alloc; array->alloc_increment=alloc_increment; array->size_of_element=element_size; + array->malloc_flags= my_flags; if ((array->buffer= init_buffer)) DBUG_RETURN(FALSE); /* @@ -62,18 +64,12 @@ my_bool init_dynamic_array2(DYNAMIC_ARRAY *array, uint element_size, should not throw an error */ if (init_alloc && - !(array->buffer= (uchar*) my_malloc(element_size*init_alloc, MYF(0)))) + !(array->buffer= (uchar*) my_malloc(element_size*init_alloc, + MYF(my_flags)))) array->max_element=0; DBUG_RETURN(FALSE); } -my_bool init_dynamic_array(DYNAMIC_ARRAY *array, uint element_size, - uint init_alloc, uint alloc_increment) -{ - /* placeholder to preserve ABI */ - return my_init_dynamic_array_ci(array, element_size, init_alloc, - alloc_increment); -} /* Insert element at the end of array. Allocate memory if needed. @@ -137,7 +133,7 @@ uchar *alloc_dynamic(DYNAMIC_ARRAY *array) if (!(new_ptr= (char *) my_malloc((array->max_element+ array->alloc_increment) * array->size_of_element, - MYF(MY_WME)))) + MYF(array->malloc_flags | MY_WME)))) DBUG_RETURN(0); memcpy(new_ptr, array->buffer, array->elements * array->size_of_element); @@ -146,7 +142,8 @@ uchar *alloc_dynamic(DYNAMIC_ARRAY *array) my_realloc(array->buffer,(array->max_element+ array->alloc_increment)* array->size_of_element, - MYF(MY_WME | MY_ALLOW_ZERO_PTR)))) + MYF(MY_WME | MY_ALLOW_ZERO_PTR | + array->malloc_flags)))) DBUG_RETURN(0); array->buffer= (uchar*) new_ptr; array->max_element+=array->alloc_increment; @@ -242,14 +239,15 @@ my_bool allocate_dynamic(DYNAMIC_ARRAY *array, uint max_elements) */ if (!(new_ptr= (uchar *) my_malloc(size * array->size_of_element, - MYF(MY_WME)))) + MYF(array->malloc_flags | MY_WME)))) DBUG_RETURN(0); memcpy(new_ptr, array->buffer, array->elements * array->size_of_element); } else if (!(new_ptr= (uchar*) my_realloc(array->buffer,size* array->size_of_element, - MYF(MY_WME | MY_ALLOW_ZERO_PTR)))) + MYF(MY_WME | MY_ALLOW_ZERO_PTR | + array->malloc_flags)))) DBUG_RETURN(TRUE); array->buffer= new_ptr; array->max_element= size; @@ -347,7 +345,7 @@ void freeze_size(DYNAMIC_ARRAY *array) { array->buffer=(uchar*) my_realloc(array->buffer, elements*array->size_of_element, - MYF(MY_WME)); + MYF(MY_WME | array->malloc_flags)); array->max_element=elements; } } diff --git a/mysys/default.c b/mysys/default.c index c7ac0d89462..94609ba4539 100644 --- a/mysys/default.c +++ b/mysys/default.c @@ -520,7 +520,7 @@ int my_load_defaults(const char *conf_file, const char **groups, uint args_sep= my_getopt_use_args_separator ? 1 : 0; DBUG_ENTER("load_defaults"); - init_alloc_root(&alloc,512,0); + init_alloc_root(&alloc, 512, 0, 0); if ((dirs= init_default_directories(&alloc)) == NULL) goto err; /* @@ -566,7 +566,7 @@ int my_load_defaults(const char *conf_file, const char **groups, for (; *groups ; groups++) group.count++; - if (my_init_dynamic_array(&args, sizeof(char*),*argc, 32)) + if (my_init_dynamic_array(&args, sizeof(char*),*argc, 32, 0)) goto err; ctx.alloc= &alloc; @@ -1043,7 +1043,7 @@ void my_print_default_files(const char *conf_file) { const char **dirs; MEM_ROOT alloc; - init_alloc_root(&alloc,512,0); + init_alloc_root(&alloc, 512, 0, 0); if ((dirs= init_default_directories(&alloc)) == NULL) { diff --git a/mysys/hash.c b/mysys/hash.c index b93f6b666d6..0a830d8e3f4 100644 --- a/mysys/hash.c +++ b/mysys/hash.c @@ -89,8 +89,10 @@ _my_hash_init(HASH *hash, uint growth_size, CHARSET_INFO *charset, hash->free=free_element; hash->flags=flags; hash->charset=charset; - res= my_init_dynamic_array_ci(&hash->array, - sizeof(HASH_LINK), size, growth_size); + res= my_init_dynamic_array2(&hash->array, + sizeof(HASH_LINK), NULL, size, growth_size, + MYF((flags & HASH_THREAD_SPECIFIC ? + MY_THREAD_SPECIFIC : 0))); DBUG_RETURN(res); } diff --git a/mysys/ma_dyncol.c b/mysys/ma_dyncol.c index f45f73fbd8e..2441243c132 100644 --- a/mysys/ma_dyncol.c +++ b/mysys/ma_dyncol.c @@ -342,8 +342,10 @@ static my_bool type_and_offset_store_num(uchar *place, size_t offset_size, int3store(place, val); break; case 4: +#if SIZEOF_SIZE_T > 4 if (offset >= 0x1fffffff) /* all 1 value is reserved */ return TRUE; +#endif int4store(place, val); break; default: @@ -381,8 +383,10 @@ static my_bool type_and_offset_store_named(uchar *place, size_t offset_size, int4store(place, val); break; case 5: +#if SIZEOF_SIZE_T > 4 if (offset >= 0xfffffffffull) /* all 1 value is reserved */ return TRUE; +#endif int5store(place, val); break; case 1: @@ -482,8 +486,10 @@ static size_t dynamic_column_offset_bytes_named(size_t data_length) return 3; if (data_length < 0xfffffff) /* all 1 value is reserved */ return 4; +#if SIZEOF_SIZE_T > 4 if (data_length < 0xfffffffffull) /* all 1 value is reserved */ return 5; +#endif return MAX_OFFSET_LENGTH_NM + 1; /* For an error generation */ } @@ -2403,7 +2409,8 @@ dynamic_column_list(DYNAMIC_COLUMN *str, DYNAMIC_ARRAY *array_of_uint) str->length) return ER_DYNCOL_FORMAT; - if (init_dynamic_array(array_of_uint, sizeof(uint), header.column_count, 0)) + if (my_init_dynamic_array(array_of_uint, sizeof(uint), header.column_count, + 0, 0)) return ER_DYNCOL_RESOURCE; for (i= 0, read= header.header; diff --git a/mysys/mf_tempdir.c b/mysys/mf_tempdir.c index eceb90bb619..bd42002ae86 100644 --- a/mysys/mf_tempdir.c +++ b/mysys/mf_tempdir.c @@ -30,7 +30,7 @@ my_bool init_tmpdir(MY_TMPDIR *tmpdir, const char *pathlist) DBUG_PRINT("enter", ("pathlist: %s", pathlist ? pathlist : "NULL")); mysql_mutex_init(key_TMPDIR_mutex, &tmpdir->mutex, MY_MUTEX_INIT_FAST); - if (my_init_dynamic_array(&tmpdir->full_list, sizeof(char*), 1, 5)) + if (my_init_dynamic_array(&tmpdir->full_list, sizeof(char*), 1, 5, 0)) goto err; if (!pathlist || !pathlist[0]) { diff --git a/mysys/my_alloc.c b/mysys/my_alloc.c index 1054db6cee4..6c8a73df4a7 100644 --- a/mysys/my_alloc.c +++ b/mysys/my_alloc.c @@ -22,6 +22,10 @@ #undef EXTRA_DEBUG #define EXTRA_DEBUG +/* data packed in MEM_ROOT -> min_malloc */ + +#define MALLOC_FLAG(A) ((A & 1) ? MY_THREAD_SPECIFIC : 0) + /* Initialize memory root @@ -34,6 +38,7 @@ should be no less than ALLOC_ROOT_MIN_BLOCK_SIZE) pre_alloc_size - if non-0, then size of block that should be pre-allocated during memory root initialization. + my_flags MY_THREAD_SPECIFIC flag for my_malloc DESCRIPTION This function prepares memory root for further use, sets initial size of @@ -41,17 +46,24 @@ Altough error can happen during execution of this function if pre_alloc_size is non-0 it won't be reported. Instead it will be reported as error in first alloc_root() on this memory root. + + We don't want to change the structure size for MEM_ROOT. + Because of this, we store in MY_THREAD_SPECIFIC as bit 1 in block_size */ void init_alloc_root(MEM_ROOT *mem_root, size_t block_size, - size_t pre_alloc_size __attribute__((unused))) + size_t pre_alloc_size __attribute__((unused)), + myf my_flags) { DBUG_ENTER("init_alloc_root"); DBUG_PRINT("enter",("root: 0x%lx", (long) mem_root)); mem_root->free= mem_root->used= mem_root->pre_alloc= 0; mem_root->min_malloc= 32; - mem_root->block_size= block_size - ALLOC_ROOT_MIN_BLOCK_SIZE; + mem_root->block_size= (block_size - ALLOC_ROOT_MIN_BLOCK_SIZE) & ~1; + if (test(my_flags & MY_THREAD_SPECIFIC)) + mem_root->block_size|= 1; + mem_root->error_handler= 0; mem_root->block_num= 4; /* We shift this with >>2 */ mem_root->first_block_usage= 0; @@ -61,7 +73,7 @@ void init_alloc_root(MEM_ROOT *mem_root, size_t block_size, { if ((mem_root->free= mem_root->pre_alloc= (USED_MEM*) my_malloc(pre_alloc_size+ ALIGN_SIZE(sizeof(USED_MEM)), - MYF(0)))) + MYF(my_flags)))) { mem_root->free->size= pre_alloc_size+ALIGN_SIZE(sizeof(USED_MEM)); mem_root->free->left= pre_alloc_size; @@ -72,7 +84,6 @@ void init_alloc_root(MEM_ROOT *mem_root, size_t block_size, DBUG_VOID_RETURN; } - /* SYNOPSIS reset_root_defaults() @@ -95,7 +106,8 @@ void reset_root_defaults(MEM_ROOT *mem_root, size_t block_size, { DBUG_ASSERT(alloc_root_inited(mem_root)); - mem_root->block_size= block_size - ALLOC_ROOT_MIN_BLOCK_SIZE; + mem_root->block_size= (((block_size - ALLOC_ROOT_MIN_BLOCK_SIZE) & ~1) | + (mem_root->block_size & 1)); #if !(defined(HAVE_valgrind) && defined(EXTRA_DEBUG)) if (pre_alloc_size) { @@ -126,7 +138,9 @@ void reset_root_defaults(MEM_ROOT *mem_root, size_t block_size, prev= &mem->next; } /* Allocate new prealloc block and add it to the end of free list */ - if ((mem= (USED_MEM *) my_malloc(size, MYF(0)))) + if ((mem= (USED_MEM *) my_malloc(size, + MYF(MALLOC_FLAG(mem_root-> + block_size))))) { mem->size= size; mem->left= pre_alloc_size; @@ -163,7 +177,9 @@ void *alloc_root(MEM_ROOT *mem_root, size_t length) }); length+=ALIGN_SIZE(sizeof(USED_MEM)); - if (!(next = (USED_MEM*) my_malloc(length,MYF(MY_WME | ME_FATALERROR)))) + if (!(next = (USED_MEM*) my_malloc(length, + MYF(MY_WME | ME_FATALERROR | + MALLOC_FLAG(mem_root->block_size))))) { if (mem_root->error_handler) (*mem_root->error_handler)(); @@ -210,11 +226,14 @@ void *alloc_root(MEM_ROOT *mem_root, size_t length) } if (! next) { /* Time to alloc new block */ - block_size= mem_root->block_size * (mem_root->block_num >> 2); + block_size= (mem_root->block_size & ~1) * (mem_root->block_num >> 2); get_size= length+ALIGN_SIZE(sizeof(USED_MEM)); get_size= max(get_size, block_size); - if (!(next = (USED_MEM*) my_malloc(get_size,MYF(MY_WME | ME_FATALERROR)))) + if (!(next = (USED_MEM*) my_malloc(get_size, + MYF(MY_WME | ME_FATALERROR | + MALLOC_FLAG(mem_root-> + block_size))))) { if (mem_root->error_handler) (*mem_root->error_handler)(); diff --git a/mysys/my_chmod.c b/mysys/my_chmod.c index afdea758833..91fd51b47d2 100644 --- a/mysys/my_chmod.c +++ b/mysys/my_chmod.c @@ -34,7 +34,7 @@ int my_chmod(const char *name, mode_t mode, myf my_flags) { DBUG_ENTER("my_chmod"); - DBUG_PRINT("my",("name: %s mode: %lu flags: %d", name, (ulong) mode, + DBUG_PRINT("my",("name: %s mode: %lu flags: %lu", name, (ulong) mode, my_flags)); if (chmod(name, mode)) diff --git a/mysys/my_chsize.c b/mysys/my_chsize.c index 63964916d6f..51da6be7935 100644 --- a/mysys/my_chsize.c +++ b/mysys/my_chsize.c @@ -43,7 +43,7 @@ int my_chsize(File fd, my_off_t newlength, int filler, myf MyFlags) my_off_t oldsize; uchar buff[IO_SIZE]; DBUG_ENTER("my_chsize"); - DBUG_PRINT("my",("fd: %d length: %lu MyFlags: %d",fd,(ulong) newlength, + DBUG_PRINT("my",("fd: %d length: %lu MyFlags: %lu",fd,(ulong) newlength, MyFlags)); if ((oldsize= my_seek(fd, 0L, MY_SEEK_END, MYF(MY_WME+MY_FAE))) == newlength) diff --git a/mysys/my_copy.c b/mysys/my_copy.c index 21de1e953a2..58cacb9639d 100644 --- a/mysys/my_copy.c +++ b/mysys/my_copy.c @@ -61,7 +61,7 @@ int my_copy(const char *from, const char *to, myf MyFlags) MY_STAT stat_buff,new_stat_buff; my_bool file_created= 0; DBUG_ENTER("my_copy"); - DBUG_PRINT("my",("from %s to %s MyFlags %d", from, to, MyFlags)); + DBUG_PRINT("my",("from %s to %s MyFlags %lu", from, to, MyFlags)); from_file=to_file= -1; DBUG_ASSERT(!(MyFlags & (MY_FNABP | MY_NABP))); /* for my_read/my_write */ diff --git a/mysys/my_create.c b/mysys/my_create.c index 2e4e8eb1af2..51de343d4a1 100644 --- a/mysys/my_create.c +++ b/mysys/my_create.c @@ -38,7 +38,7 @@ File my_create(const char *FileName, int CreateFlags, int access_flags, { int fd, rc; DBUG_ENTER("my_create"); - DBUG_PRINT("my",("Name: '%s' CreateFlags: %d AccessFlags: %d MyFlags: %d", + DBUG_PRINT("my",("Name: '%s' CreateFlags: %d AccessFlags: %d MyFlags: %lu", FileName, CreateFlags, access_flags, MyFlags)); #if defined(_WIN32) fd= my_win_open(FileName, access_flags | O_CREAT); diff --git a/mysys/my_delete.c b/mysys/my_delete.c index cf9573f592b..0655501aa16 100644 --- a/mysys/my_delete.c +++ b/mysys/my_delete.c @@ -21,7 +21,7 @@ int my_delete(const char *name, myf MyFlags) { int err; DBUG_ENTER("my_delete"); - DBUG_PRINT("my",("name %s MyFlags %d", name, MyFlags)); + DBUG_PRINT("my",("name %s MyFlags %lu", name, MyFlags)); if ((err = unlink(name)) == -1) { diff --git a/mysys/my_error.c b/mysys/my_error.c index 3302add688b..08c67412fe1 100644 --- a/mysys/my_error.c +++ b/mysys/my_error.c @@ -75,7 +75,7 @@ void my_error(int nr, myf MyFlags, ...) va_list args; char ebuff[ERRMSGSIZE]; DBUG_ENTER("my_error"); - DBUG_PRINT("my", ("nr: %d MyFlags: %d errno: %d", nr, MyFlags, errno)); + DBUG_PRINT("my", ("nr: %d MyFlags: %lu errno: %d", nr, MyFlags, errno)); /* Search for the error messages array, which could contain the message. */ for (meh_p= my_errmsgs_list; meh_p; meh_p= meh_p->meh_next) @@ -114,7 +114,7 @@ void my_printf_error(uint error, const char *format, myf MyFlags, ...) va_list args; char ebuff[ERRMSGSIZE]; DBUG_ENTER("my_printf_error"); - DBUG_PRINT("my", ("nr: %d MyFlags: %d errno: %d format: %s", + DBUG_PRINT("my", ("nr: %d MyFlags: %lu errno: %d format: %s", error, MyFlags, errno, format)); va_start(args,MyFlags); @@ -140,7 +140,7 @@ void my_printv_error(uint error, const char *format, myf MyFlags, va_list ap) { char ebuff[ERRMSGSIZE]; DBUG_ENTER("my_printv_error"); - DBUG_PRINT("my", ("nr: %d MyFlags: %d errno: %d format: %s", + DBUG_PRINT("my", ("nr: %d MyFlags: %lu errno: %d format: %s", error, MyFlags, errno, format)); (void) my_vsnprintf(ebuff, sizeof(ebuff), format, ap); diff --git a/mysys/my_fopen.c b/mysys/my_fopen.c index 54469d2c05a..8a30dd6c10b 100644 --- a/mysys/my_fopen.c +++ b/mysys/my_fopen.c @@ -44,7 +44,7 @@ FILE *my_fopen(const char *filename, int flags, myf MyFlags) FILE *fd; char type[5]; DBUG_ENTER("my_fopen"); - DBUG_PRINT("my",("Name: '%s' flags: %d MyFlags: %d", + DBUG_PRINT("my",("Name: '%s' flags: %d MyFlags: %lu", filename, flags, MyFlags)); make_ftype(type,flags); @@ -229,7 +229,7 @@ int my_fclose(FILE *fd, myf MyFlags) { int err,file; DBUG_ENTER("my_fclose"); - DBUG_PRINT("my",("stream: 0x%lx MyFlags: %d", (long) fd, MyFlags)); + DBUG_PRINT("my",("stream: 0x%lx MyFlags: %lu", (long) fd, MyFlags)); mysql_mutex_lock(&THR_LOCK_open); file= my_fileno(fd); @@ -265,7 +265,7 @@ FILE *my_fdopen(File Filedes, const char *name, int Flags, myf MyFlags) FILE *fd; char type[5]; DBUG_ENTER("my_fdopen"); - DBUG_PRINT("my",("fd: %d Flags: %d MyFlags: %d", + DBUG_PRINT("my",("fd: %d Flags: %d MyFlags: %lu", Filedes, Flags, MyFlags)); make_ftype(type,Flags); diff --git a/mysys/my_fstream.c b/mysys/my_fstream.c index e758609741b..de752fa149f 100644 --- a/mysys/my_fstream.c +++ b/mysys/my_fstream.c @@ -46,7 +46,7 @@ size_t my_fread(FILE *stream, uchar *Buffer, size_t Count, myf MyFlags) { size_t readbytes; DBUG_ENTER("my_fread"); - DBUG_PRINT("my",("stream: 0x%lx Buffer: 0x%lx Count: %u MyFlags: %d", + DBUG_PRINT("my",("stream: 0x%lx Buffer: 0x%lx Count: %u MyFlags: %lu", (long) stream, (long) Buffer, (uint) Count, MyFlags)); if ((readbytes= fread(Buffer, sizeof(char), Count, stream)) != Count) @@ -94,7 +94,7 @@ size_t my_fwrite(FILE *stream, const uchar *Buffer, size_t Count, myf MyFlags) uint errors; #endif DBUG_ENTER("my_fwrite"); - DBUG_PRINT("my",("stream: 0x%lx Buffer: 0x%lx Count: %u MyFlags: %d", + DBUG_PRINT("my",("stream: 0x%lx Buffer: 0x%lx Count: %u MyFlags: %lu", (long) stream, (long) Buffer, (uint) Count, MyFlags)); #if !defined(NO_BACKGROUND) && defined(USE_MY_STREAM) @@ -163,7 +163,7 @@ my_off_t my_fseek(FILE *stream, my_off_t pos, int whence, myf MyFlags __attribute__((unused))) { DBUG_ENTER("my_fseek"); - DBUG_PRINT("my",("stream: 0x%lx pos: %lu whence: %d MyFlags: %d", + DBUG_PRINT("my",("stream: 0x%lx pos: %lu whence: %d MyFlags: %lu", (long) stream, (long) pos, whence, MyFlags)); DBUG_RETURN(fseek(stream, (off_t) pos, whence) ? MY_FILEPOS_ERROR : (my_off_t) ftell(stream)); @@ -176,7 +176,7 @@ my_off_t my_ftell(FILE *stream, myf MyFlags __attribute__((unused))) { off_t pos; DBUG_ENTER("my_ftell"); - DBUG_PRINT("my",("stream: 0x%lx MyFlags: %d", (long) stream, MyFlags)); + DBUG_PRINT("my",("stream: 0x%lx MyFlags: %lu", (long) stream, MyFlags)); pos=ftell(stream); DBUG_PRINT("exit",("ftell: %lu",(ulong) pos)); DBUG_RETURN((my_off_t) pos); diff --git a/mysys/my_getwd.c b/mysys/my_getwd.c index 444ed4273b5..79ec58d3c5c 100644 --- a/mysys/my_getwd.c +++ b/mysys/my_getwd.c @@ -48,7 +48,7 @@ int my_getwd(char * buf, size_t size, myf MyFlags) { char * pos; DBUG_ENTER("my_getwd"); - DBUG_PRINT("my",("buf: 0x%lx size: %u MyFlags %d", + DBUG_PRINT("my",("buf: 0x%lx size: %u MyFlags %lu", (long) buf, (uint) size, MyFlags)); if (size < 1) @@ -95,7 +95,7 @@ int my_setwd(const char *dir, myf MyFlags) size_t length; char *start, *pos; DBUG_ENTER("my_setwd"); - DBUG_PRINT("my",("dir: '%s' MyFlags %d", dir, MyFlags)); + DBUG_PRINT("my",("dir: '%s' MyFlags %lu", dir, MyFlags)); start=(char *) dir; if (! dir[0] || (dir[0] == FN_LIBCHAR && dir[1] == 0)) diff --git a/mysys/my_lib.c b/mysys/my_lib.c index b42a3d55d93..543d96455ff 100644 --- a/mysys/my_lib.c +++ b/mysys/my_lib.c @@ -100,7 +100,7 @@ MY_DIR *my_dir(const char *path, myf MyFlags) char dirent_tmp[sizeof(struct dirent)+_POSIX_PATH_MAX+1]; DBUG_ENTER("my_dir"); - DBUG_PRINT("my",("path: '%s' MyFlags: %d",path,MyFlags)); + DBUG_PRINT("my",("path: '%s' MyFlags: %lu",path,MyFlags)); #if !defined(HAVE_READDIR_R) mysql_mutex_lock(&THR_LOCK_open); @@ -122,12 +122,14 @@ MY_DIR *my_dir(const char *path, myf MyFlags) ALIGN_SIZE(sizeof(DYNAMIC_ARRAY))); if (my_init_dynamic_array(dir_entries_storage, sizeof(FILEINFO), - ENTRIES_START_SIZE, ENTRIES_INCREMENT)) + ENTRIES_START_SIZE, ENTRIES_INCREMENT, + MyFlags)) { my_free(buffer); goto error; } - init_alloc_root(names_storage, NAMES_START_SIZE, NAMES_START_SIZE); + init_alloc_root(names_storage, NAMES_START_SIZE, NAMES_START_SIZE, + MyFlags); /* MY_DIR structure is allocated and completly initialized at this point */ result= (MY_DIR*)buffer; @@ -263,12 +265,13 @@ MY_DIR *my_dir(const char *path, myf MyFlags) ALIGN_SIZE(sizeof(DYNAMIC_ARRAY))); if (my_init_dynamic_array(dir_entries_storage, sizeof(FILEINFO), - ENTRIES_START_SIZE, ENTRIES_INCREMENT)) + ENTRIES_START_SIZE, ENTRIES_INCREMENT, + MyFlags)) { my_free(buffer); goto error; } - init_alloc_root(names_storage, NAMES_START_SIZE, NAMES_START_SIZE); + init_alloc_root(names_storage, NAMES_START_SIZE, NAMES_START_SIZE, MyFlags); /* MY_DIR structure is allocated and completly initialized at this point */ result= (MY_DIR*)buffer; @@ -383,7 +386,7 @@ int my_fstat(File Filedes, MY_STAT *stat_area, myf MyFlags __attribute__((unused))) { DBUG_ENTER("my_fstat"); - DBUG_PRINT("my",("fd: %d MyFlags: %d", Filedes, MyFlags)); + DBUG_PRINT("my",("fd: %d MyFlags: %lu", Filedes, MyFlags)); #ifdef _WIN32 DBUG_RETURN(my_win_fstat(Filedes, stat_area)); #else @@ -396,7 +399,7 @@ MY_STAT *my_stat(const char *path, MY_STAT *stat_area, myf my_flags) { int m_used; DBUG_ENTER("my_stat"); - DBUG_PRINT("my", ("path: '%s' stat_area: 0x%lx MyFlags: %d", path, + DBUG_PRINT("my", ("path: '%s' stat_area: 0x%lx MyFlags: %lu", path, (long) stat_area, my_flags)); if ((m_used= (stat_area == NULL))) diff --git a/mysys/my_lock.c b/mysys/my_lock.c index 54ec3838b58..0abbc6c3084 100644 --- a/mysys/my_lock.c +++ b/mysys/my_lock.c @@ -144,7 +144,7 @@ int my_lock(File fd, int locktype, my_off_t start, my_off_t length, #endif DBUG_ENTER("my_lock"); - DBUG_PRINT("my",("fd: %d Op: %d start: %ld Length: %ld MyFlags: %d", + DBUG_PRINT("my",("fd: %d Op: %d start: %ld Length: %ld MyFlags: %lu", fd,locktype,(long) start,(long) length,MyFlags)); if (my_disable_locking && ! (MyFlags & MY_FORCE_LOCK)) DBUG_RETURN(0); diff --git a/mysys/my_malloc.c b/mysys/my_malloc.c index 1a9caf71380..88f3f412faf 100644 --- a/mysys/my_malloc.c +++ b/mysys/my_malloc.c @@ -18,6 +18,60 @@ #include "mysys_err.h" #include <m_string.h> +/* If we have our own safemalloc (for debugging) */ +#if defined(SAFEMALLOC) +#define MALLOC_SIZE_AND_FLAG(p,b) sf_malloc_usable_size(p,b) +#define MALLOC_PREFIX_SIZE 0 +#define MALLOC_STORE_SIZE(a,b,c,d) +#define MALLOC_FIX_POINTER_FOR_FREE(a) a +#else +/* + * We use double as prefix size as this guarantees the correct + * alignment on all platforms and will optimize things for + * memcpy(), memcmp() etc. + */ +#define MALLOC_PREFIX_SIZE (sizeof(double)) +#define MALLOC_SIZE(p) (*(size_t*) ((char*)(p) - MALLOC_PREFIX_SIZE)) +#define MALLOC_STORE_SIZE(p, type_of_p, size, flag) \ +{\ + *(size_t*) p= (size) | (flag); \ + (p)= (type_of_p) (((char*) (p)) + MALLOC_PREFIX_SIZE); \ +} +static inline size_t malloc_size_and_flag(void *p, myf *flags) +{ + size_t size= MALLOC_SIZE(p); + *flags= (size & 1); + return size & ~ (ulonglong) 1; +} +#define MALLOC_SIZE_AND_FLAG(p,b) malloc_size_and_flag(p, b); +#define MALLOC_FIX_POINTER_FOR_FREE(p) (((char*) (p)) - MALLOC_PREFIX_SIZE) +#endif /* SAFEMALLOC */ + +static MALLOC_SIZE_CB malloc_size_cb_func= NULL; + +/** + Inform application that memory usage has changed + + @param size Size of memory segment allocated or freed + @param flag 1 if thread specific (allocated by MY_THREAD_SPECIFIC), + 0 if system specific. + + The type os size is long long, to be able to handle negative numbers to + decrement the memory usage +*/ + +static void update_malloc_size(long long size, myf my_flags) +{ + if (malloc_size_cb_func) + malloc_size_cb_func(size, my_flags); +} + +void set_malloc_size_cb(MALLOC_SIZE_CB func) +{ + malloc_size_cb_func= func; +} + + /** Allocate a sized block of memory. @@ -30,7 +84,9 @@ void *my_malloc(size_t size, myf my_flags) { void* point; DBUG_ENTER("my_malloc"); - DBUG_PRINT("my",("size: %lu my_flags: %d", (ulong) size, my_flags)); + DBUG_PRINT("my",("size: %lu my_flags: %lu", (ulong) size, my_flags)); + compile_time_assert(sizeof(size_t) <= sizeof(double)); + if (!(my_flags & (MY_WME | MY_FAE))) my_flags|= my_global_flags; @@ -38,12 +94,9 @@ void *my_malloc(size_t size, myf my_flags) if (!size) size=1; - point= sf_malloc(size); - DBUG_EXECUTE_IF("simulate_out_of_memory", - { - my_free(point); - point= NULL; - }); + /* We have to align size to be able to store markers in it */ + size= ALIGN_SIZE(size); + point= sf_malloc(size + MALLOC_PREFIX_SIZE, my_flags); if (point == NULL) { @@ -59,8 +112,20 @@ void *my_malloc(size_t size, myf my_flags) if (my_flags & MY_FAE) exit(1); } - else if (my_flags & MY_ZEROFILL) - bzero(point, size); + else + { + MALLOC_STORE_SIZE(point, void*, size, test(my_flags & MY_THREAD_SPECIFIC)); + update_malloc_size(size + MALLOC_PREFIX_SIZE, + test(my_flags & MY_THREAD_SPECIFIC)); + DBUG_EXECUTE_IF("simulate_out_of_memory", + { + /* my_free() handles memory accounting */ + my_free(point); + point= NULL; + }); + if (my_flags & MY_ZEROFILL) + bzero(point, size); + } DBUG_PRINT("exit",("ptr: %p", point)); DBUG_RETURN(point); } @@ -79,23 +144,53 @@ void *my_malloc(size_t size, myf my_flags) void *my_realloc(void *oldpoint, size_t size, myf my_flags) { void *point; + size_t old_size; + myf old_flags; DBUG_ENTER("my_realloc"); - DBUG_PRINT("my",("ptr: %p size: %lu my_flags: %d", oldpoint, + DBUG_PRINT("my",("ptr: %p size: %lu my_flags: %lu", oldpoint, (ulong) size, my_flags)); DBUG_ASSERT(size > 0); if (!oldpoint && (my_flags & MY_ALLOW_ZERO_PTR)) DBUG_RETURN(my_malloc(size, my_flags)); - if ((point= sf_realloc(oldpoint, size)) == NULL) + + size= ALIGN_SIZE(size); + old_size= MALLOC_SIZE_AND_FLAG(oldpoint, &old_flags); + /* + Test that the new and old area are the same, if not MY_THREAD_MOVE is + given + */ + DBUG_ASSERT((test(my_flags & MY_THREAD_SPECIFIC) == old_flags) || + (my_flags & MY_THREAD_MOVE)); + if ((point= sf_realloc(MALLOC_FIX_POINTER_FOR_FREE(oldpoint), + size + MALLOC_PREFIX_SIZE, my_flags)) == NULL) { if (my_flags & MY_FREE_ON_ERROR) + { + /* my_free will take care of size accounting */ my_free(oldpoint); + oldpoint= 0; + } if (my_flags & MY_HOLD_ON_ERROR) DBUG_RETURN(oldpoint); my_errno=errno; if (my_flags & (MY_FAE+MY_WME)) my_error(EE_OUTOFMEMORY, MYF(ME_BELL+ME_WAITTANG), size); } + else + { + MALLOC_STORE_SIZE(point, void*, size, test(my_flags & MY_THREAD_SPECIFIC)); + if (test(my_flags & MY_THREAD_SPECIFIC) != old_flags) + { + /* memory moved between system and thread specific */ + update_malloc_size(-(longlong) old_size - MALLOC_PREFIX_SIZE, old_flags); + update_malloc_size((longlong) size + MALLOC_PREFIX_SIZE, + my_flags & MY_THREAD_SPECIFIC); + } + else + update_malloc_size((longlong) (size - old_size), old_flags); + } + DBUG_PRINT("exit",("ptr: %p", point)); DBUG_RETURN(point); } @@ -112,7 +207,14 @@ void my_free(void *ptr) { DBUG_ENTER("my_free"); DBUG_PRINT("my",("ptr: %p", ptr)); - sf_free(ptr); + if (ptr) + { + size_t old_size; + myf old_flags; + old_size= MALLOC_SIZE_AND_FLAG(ptr, &old_flags); + update_malloc_size(- (longlong) old_size - MALLOC_PREFIX_SIZE, old_flags); + sf_free(MALLOC_FIX_POINTER_FOR_FREE(ptr)); + } DBUG_VOID_RETURN; } diff --git a/mysys/my_open.c b/mysys/my_open.c index 645d6709358..5263ba4b5c8 100644 --- a/mysys/my_open.c +++ b/mysys/my_open.c @@ -39,7 +39,7 @@ File my_open(const char *FileName, int Flags, myf MyFlags) { File fd; DBUG_ENTER("my_open"); - DBUG_PRINT("my",("Name: '%s' Flags: %d MyFlags: %d", + DBUG_PRINT("my",("Name: '%s' Flags: %d MyFlags: %lu", FileName, Flags, MyFlags)); if (!(MyFlags & (MY_WME | MY_FAE | MY_FFNF))) MyFlags|= my_global_flags; @@ -71,7 +71,7 @@ int my_close(File fd, myf MyFlags) { int err; DBUG_ENTER("my_close"); - DBUG_PRINT("my",("fd: %d MyFlags: %d",fd, MyFlags)); + DBUG_PRINT("my",("fd: %d MyFlags: %lu",fd, MyFlags)); if (!(MyFlags & (MY_WME | MY_FAE))) MyFlags|= my_global_flags; diff --git a/mysys/my_pread.c b/mysys/my_pread.c index 51b4c5f5599..745cde9ec41 100644 --- a/mysys/my_pread.c +++ b/mysys/my_pread.c @@ -52,7 +52,7 @@ size_t my_pread(File Filedes, uchar *Buffer, size_t Count, my_off_t offset, DBUG_ENTER("my_pread"); - DBUG_PRINT("my",("fd: %d Seek: %llu Buffer: %p Count: %lu MyFlags: %d", + DBUG_PRINT("my",("fd: %d Seek: %llu Buffer: %p Count: %lu MyFlags: %lu", Filedes, (ulonglong)offset, Buffer, (ulong)Count, MyFlags)); if (!(MyFlags & (MY_WME | MY_FAE | MY_FNABP))) @@ -130,7 +130,7 @@ size_t my_pwrite(int Filedes, const uchar *Buffer, size_t Count, size_t writtenbytes, written; uint errors; DBUG_ENTER("my_pwrite"); - DBUG_PRINT("my",("fd: %d Seek: %llu Buffer: %p Count: %lu MyFlags: %d", + DBUG_PRINT("my",("fd: %d Seek: %llu Buffer: %p Count: %lu MyFlags: %lu", Filedes, (ulonglong)offset, Buffer, (ulong)Count, MyFlags)); errors= 0; written= 0; diff --git a/mysys/my_read.c b/mysys/my_read.c index 0afbf3773f3..66b7f6d353d 100644 --- a/mysys/my_read.c +++ b/mysys/my_read.c @@ -37,7 +37,7 @@ size_t my_read(File Filedes, uchar *Buffer, size_t Count, myf MyFlags) { size_t readbytes, save_count; DBUG_ENTER("my_read"); - DBUG_PRINT("my",("fd: %d Buffer: %p Count: %lu MyFlags: %d", + DBUG_PRINT("my",("fd: %d Buffer: %p Count: %lu MyFlags: %lu", Filedes, Buffer, (ulong) Count, MyFlags)); save_count= Count; if (!(MyFlags & (MY_WME | MY_FAE | MY_FNABP))) diff --git a/mysys/my_redel.c b/mysys/my_redel.c index d15dd87001a..e4d88b70f38 100644 --- a/mysys/my_redel.c +++ b/mysys/my_redel.c @@ -46,7 +46,7 @@ int my_redel(const char *org_name, const char *tmp_name, { int error=1; DBUG_ENTER("my_redel"); - DBUG_PRINT("my",("org_name: '%s' tmp_name: '%s' MyFlags: %d", + DBUG_PRINT("my",("org_name: '%s' tmp_name: '%s' MyFlags: %lu", org_name,tmp_name,MyFlags)); if (my_copystat(org_name,tmp_name,MyFlags) < 0) diff --git a/mysys/my_rename.c b/mysys/my_rename.c index b89bc4c8fbd..8a9e6eb3dfd 100644 --- a/mysys/my_rename.c +++ b/mysys/my_rename.c @@ -25,7 +25,7 @@ int my_rename(const char *from, const char *to, myf MyFlags) { int error = 0; DBUG_ENTER("my_rename"); - DBUG_PRINT("my",("from %s to %s MyFlags %d", from, to, MyFlags)); + DBUG_PRINT("my",("from %s to %s MyFlags %lu", from, to, MyFlags)); #if defined(HAVE_RENAME) #if defined(__WIN__) diff --git a/mysys/my_seek.c b/mysys/my_seek.c index 1033d7ac806..e15179a408f 100644 --- a/mysys/my_seek.c +++ b/mysys/my_seek.c @@ -48,7 +48,7 @@ my_off_t my_seek(File fd, my_off_t pos, int whence, myf MyFlags) { os_off_t newpos= -1; DBUG_ENTER("my_seek"); - DBUG_PRINT("my",("fd: %d Pos: %llu Whence: %d MyFlags: %d", + DBUG_PRINT("my",("fd: %d Pos: %llu Whence: %d MyFlags: %lu", fd, (ulonglong) pos, whence, MyFlags)); DBUG_ASSERT(pos != MY_FILEPOS_ERROR); /* safety check */ @@ -84,7 +84,7 @@ my_off_t my_tell(File fd, myf MyFlags) { os_off_t pos; DBUG_ENTER("my_tell"); - DBUG_PRINT("my",("fd: %d MyFlags: %d",fd, MyFlags)); + DBUG_PRINT("my",("fd: %d MyFlags: %lu",fd, MyFlags)); DBUG_ASSERT(fd >= 0); #if defined (HAVE_TELL) && !defined (_WIN32) pos= tell(fd); diff --git a/mysys/my_sync.c b/mysys/my_sync.c index 88bcb685271..c0afd587ada 100644 --- a/mysys/my_sync.c +++ b/mysys/my_sync.c @@ -65,16 +65,13 @@ int my_sync(File fd, myf my_flags) { int res; DBUG_ENTER("my_sync"); - - DBUG_PRINT("my",("fd: %d my_flags: %d", fd, my_flags)); + DBUG_PRINT("my",("fd: %d my_flags: %lu", fd, my_flags)); if (my_disable_sync) DBUG_RETURN(0); statistic_increment(my_sync_count,&THR_LOCK_open); - DBUG_PRINT("my",("Fd: %d my_flags: %d", fd, my_flags)); - if (before_sync_wait) (*before_sync_wait)(); @@ -158,7 +155,7 @@ int my_sync_dir(const char *dir_name __attribute__((unused)), int res= 0; const char *correct_dir_name; DBUG_ENTER("my_sync_dir"); - DBUG_PRINT("my",("Dir: '%s' my_flags: %d", dir_name, my_flags)); + DBUG_PRINT("my",("Dir: '%s' my_flags: %lu", dir_name, my_flags)); /* Sometimes the path does not contain an explicit directory */ correct_dir_name= (dir_name[0] == 0) ? cur_dir_name : dir_name; /* diff --git a/mysys/my_thr_init.c b/mysys/my_thr_init.c index ac16189f3a7..56f7ca8b31a 100644 --- a/mysys/my_thr_init.c +++ b/mysys/my_thr_init.c @@ -427,7 +427,12 @@ struct st_my_thread_var *_my_thread_var(void) my_thread_id my_thread_dbug_id() { - return my_thread_var->id; + /* + We need to do this test as some system thread may not yet have called + my_thread_init(). + */ + struct st_my_thread_var *tmp= my_thread_var; + return tmp ? tmp->id : 0; } #ifdef DBUG_OFF diff --git a/mysys/my_write.c b/mysys/my_write.c index c4cba7a927d..204e2e1488d 100644 --- a/mysys/my_write.c +++ b/mysys/my_write.c @@ -25,7 +25,7 @@ size_t my_write(File Filedes, const uchar *Buffer, size_t Count, myf MyFlags) size_t writtenbytes, written; uint errors; DBUG_ENTER("my_write"); - DBUG_PRINT("my",("fd: %d Buffer: %p Count: %lu MyFlags: %d", + DBUG_PRINT("my",("fd: %d Buffer: %p Count: %lu MyFlags: %lu", Filedes, Buffer, (ulong) Count, MyFlags)); errors= 0; written= 0; if (!(MyFlags & (MY_WME | MY_FAE | MY_FNABP))) diff --git a/mysys/mysys_priv.h b/mysys/mysys_priv.h index f5d2f301837..aa4af92202a 100644 --- a/mysys/mysys_priv.h +++ b/mysys/mysys_priv.h @@ -70,12 +70,13 @@ extern PSI_file_key key_file_charset, key_file_cnf; #endif /* HAVE_PSI_INTERFACE */ #ifdef SAFEMALLOC -void *sf_malloc(size_t size); -void *sf_realloc(void *ptr, size_t size); +void *sf_malloc(size_t size, myf my_flags); +void *sf_realloc(void *ptr, size_t size, myf my_flags); void sf_free(void *ptr); +size_t sf_malloc_usable_size(void *ptr, myf *my_flags); #else -#define sf_malloc(X) malloc(X) -#define sf_realloc(X,Y) realloc(X,Y) +#define sf_malloc(X,Y) malloc(X) +#define sf_realloc(X,Y,Z) realloc(X,Y) #define sf_free(X) free(X) #endif diff --git a/mysys/safemalloc.c b/mysys/safemalloc.c index 31f0333725f..d9a04d9e8d1 100644 --- a/mysys/safemalloc.c +++ b/mysys/safemalloc.c @@ -58,6 +58,8 @@ struct st_irem #ifdef HAVE_BACKTRACE void *frame[SF_REMEMBER_FRAMES]; /* call stack */ #endif + uint32 flags; /* Flags passed to malloc */ + my_thread_id thread_id; /* Which thread did the allocation */ uint32 marker; /* Underrun marker value */ }; @@ -79,11 +81,21 @@ static int bad_ptr(const char *where, void *ptr); static void free_memory(void *ptr); static void sf_terminate(); +/* Setup default call to get a thread id for the memory */ + +my_thread_id default_sf_malloc_dbug_id(void) +{ + return my_thread_dbug_id(); +} + +my_thread_id (*sf_malloc_dbug_id)(void)= default_sf_malloc_dbug_id; + + /** allocates memory */ -void *sf_malloc(size_t size) +void *sf_malloc(size_t size, myf my_flags) { struct st_irem *irem; uchar *data; @@ -114,7 +126,9 @@ void *sf_malloc(size_t size) data= (uchar*) (irem + 1); irem->datasize= size; irem->prev= 0; + irem->flags= my_flags; irem->marker= MAGICSTART; + irem->thread_id= sf_malloc_dbug_id(); data[size + 0]= MAGICEND0; data[size + 1]= MAGICEND1; data[size + 2]= MAGICEND2; @@ -154,17 +168,17 @@ void *sf_malloc(size_t size) return data; } -void *sf_realloc(void *ptr, size_t size) +void *sf_realloc(void *ptr, size_t size, myf my_flags) { char *data; if (!ptr) - return sf_malloc(size); + return sf_malloc(size, my_flags); if (bad_ptr("Reallocating", ptr)) return 0; - if ((data= sf_malloc(size))) + if ((data= sf_malloc(size, my_flags))) { struct st_irem *irem= (struct st_irem *)ptr - 1; set_if_smaller(size, irem->datasize); @@ -182,10 +196,38 @@ void sf_free(void *ptr) free_memory(ptr); } +/** + Return size of memory block and if block is thread specific + + sf_malloc_usable_size() + @param ptr Pointer to malloced block + @param flags We will store 1 here if block is marked as MY_THREAD_SPECIFIC + otherwise 0 + + @return Size of block +*/ + +size_t sf_malloc_usable_size(void *ptr, myf *flags) +{ + struct st_irem *irem= (struct st_irem *)ptr - 1; + DBUG_ENTER("sf_malloc_usable_size"); + *flags= test(irem->flags & MY_THREAD_SPECIFIC); + DBUG_PRINT("exit", ("size: %lu flags: %lu", (ulong) irem->datasize, + *flags)); + DBUG_RETURN(irem->datasize); +} + static void free_memory(void *ptr) { struct st_irem *irem= (struct st_irem *)ptr - 1; + if ((irem->flags & MY_THREAD_SPECIFIC) && + irem->thread_id != sf_malloc_dbug_id()) + { + DBUG_PRINT("warning", + ("Memory: %p was allocated by thread %lu and freed by thread %lu", ptr, (ulong) irem->thread_id, (ulong) sf_malloc_dbug_id())); + } + pthread_mutex_lock(&sf_mutex); /* Remove this structure from the linked list */ if (irem->prev) @@ -312,9 +354,11 @@ static int sf_sanity() /** report on all the memory pieces that have not been free'd + + @param id Id of thread to report. 0 if all */ -static void sf_terminate() +void sf_report_leaked_memory(my_thread_id id) { size_t total= 0; struct st_irem *irem; @@ -322,21 +366,29 @@ static void sf_terminate() sf_sanity(); /* Report on all the memory that was allocated but not free'd */ - if (!sf_leaking_memory && sf_malloc_root) + + for (irem= sf_malloc_root; irem; irem= irem->next) { - for (irem= sf_malloc_root; irem; irem= irem->next) + if (!id || (irem->thread_id == id && irem->flags & MY_THREAD_SPECIFIC)) { fprintf(stderr, "Warning: %4lu bytes lost, allocated at ", (ulong) irem->datasize); print_stack(irem->frame); total+= irem->datasize; } + } + if (total) fprintf(stderr, "Memory lost: %lu bytes in %d chunks\n", (ulong) total, sf_malloc_count); - } + return; +} + +static void sf_terminate() +{ + if (!sf_leaking_memory) + sf_report_leaked_memory(0); pthread_mutex_destroy(&sf_mutex); - return; } #endif diff --git a/mysys/tree.c b/mysys/tree.c index 85770194f25..b8c951df4cf 100644 --- a/mysys/tree.c +++ b/mysys/tree.c @@ -84,8 +84,9 @@ static int test_rb_tree(TREE_ELEMENT *element); #endif void init_tree(TREE *tree, size_t default_alloc_size, size_t memory_limit, - int size, qsort_cmp2 compare, my_bool with_delete, - tree_element_free free_element, void *custom_arg) + int size, qsort_cmp2 compare, + tree_element_free free_element, void *custom_arg, + myf my_flags) { DBUG_ENTER("init_tree"); DBUG_PRINT("enter",("tree: 0x%lx size: %d", (long) tree, size)); @@ -104,6 +105,7 @@ void init_tree(TREE *tree, size_t default_alloc_size, size_t memory_limit, tree->custom_arg = custom_arg; tree->null_element.colour=BLACK; tree->null_element.left=tree->null_element.right=0; + tree->my_flags= my_flags; tree->flag= 0; if (!free_element && size >= 0 && ((uint) size <= sizeof(void*) || ((uint) size & (sizeof(void*)-1)))) @@ -125,10 +127,11 @@ void init_tree(TREE *tree, size_t default_alloc_size, size_t memory_limit, tree->offset_to_key=0; /* use key through pointer */ tree->size_of_element+=sizeof(void*); } - if (!(tree->with_delete=with_delete)) + if (!(tree->with_delete= test(my_flags & MY_TREE_WITH_DELETE))) { - init_alloc_root(&tree->mem_root, default_alloc_size, 0); - tree->mem_root.min_malloc=(sizeof(TREE_ELEMENT)+tree->size_of_element); + init_alloc_root(&tree->mem_root, default_alloc_size, 0, + my_flags); + tree->mem_root.min_malloc= sizeof(TREE_ELEMENT)+tree->size_of_element; } DBUG_VOID_RETURN; } @@ -236,7 +239,8 @@ TREE_ELEMENT *tree_insert(TREE *tree, void *key, uint key_size, key_size+=tree->size_of_element; if (tree->with_delete) - element=(TREE_ELEMENT *) my_malloc(alloc_size, MYF(MY_WME)); + element=(TREE_ELEMENT *) my_malloc(alloc_size, + MYF(tree->my_flags | MY_WME)); else element=(TREE_ELEMENT *) alloc_root(&tree->mem_root,alloc_size); if (!element) diff --git a/mysys/waiting_threads.c b/mysys/waiting_threads.c index 0a9474e68b4..7d7fcb69da0 100644 --- a/mysys/waiting_threads.c +++ b/mysys/waiting_threads.c @@ -403,7 +403,7 @@ static void wt_resource_init(uchar *arg) bzero(rc, sizeof(*rc)); rc_rwlock_init(rc); mysql_cond_init(key_WT_RESOURCE_cond, &rc->cond, 0); - my_init_dynamic_array(&rc->owners, sizeof(WT_THD *), 0, 5); + my_init_dynamic_array(&rc->owners, sizeof(WT_THD *), 0, 5, 0); DBUG_VOID_RETURN; } @@ -509,7 +509,7 @@ void wt_thd_lazy_init(WT_THD *thd, const ulong *ds, const ulong *ts, thd->deadlock_search_depth_long= dl; thd->timeout_long= tl; /* dynamic array is also initialized lazily - without memory allocations */ - my_init_dynamic_array(&thd->my_resources, sizeof(WT_RESOURCE *), 0, 5); + my_init_dynamic_array(&thd->my_resources, sizeof(WT_RESOURCE *), 0, 5, 0); #ifndef DBUG_OFF thd->name= my_thread_name(); #endif diff --git a/sql-common/client.c b/sql-common/client.c index d0f1a8d078c..675774b26a7 100644 --- a/sql-common/client.c +++ b/sql-common/client.c @@ -891,7 +891,8 @@ void free_old_query(MYSQL *mysql) DBUG_ENTER("free_old_query"); if (mysql->fields) free_root(&mysql->field_alloc,MYF(0)); - init_alloc_root(&mysql->field_alloc,8192,0); /* Assume rowlength < 8192 */ + /* Assume rowlength < 8192 */ + init_alloc_root(&mysql->field_alloc, 8192, 0, MYF(MY_THREAD_SPECIFIC)); mysql->fields= 0; mysql->field_count= 0; /* For API */ mysql->warning_count= 0; @@ -1169,7 +1170,7 @@ static int add_init_command(struct st_mysql_options *options, const char *cmd) { options->init_commands= (DYNAMIC_ARRAY*)my_malloc(sizeof(DYNAMIC_ARRAY), MYF(MY_WME)); - init_dynamic_array(options->init_commands,sizeof(char*),5,5); + my_init_dynamic_array(options->init_commands,sizeof(char*),5, 5, 0); } if (!(tmp= my_strdup(cmd,MYF(MY_WME))) || @@ -1576,7 +1577,8 @@ MYSQL_DATA *cli_read_rows(MYSQL *mysql,MYSQL_FIELD *mysql_fields, set_mysql_error(mysql, CR_OUT_OF_MEMORY, unknown_sqlstate); DBUG_RETURN(0); } - init_alloc_root(&result->alloc,8192,0); /* Assume rowlength < 8192 */ + /* Assume rowlength < 8192 */ + init_alloc_root(&result->alloc, 8192, 0, MYF(MY_THREAD_SPECIFIC)); result->alloc.min_malloc=sizeof(MYSQL_ROWS); prev_ptr= &result->data; result->rows=0; @@ -3290,7 +3292,9 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user, if (mysql->options.extension && mysql->options.extension->async_context) net->vio->async_context= mysql->options.extension->async_context; - if (my_net_init(net, net->vio)) + if (my_net_init(net, net->vio, + MYF(mysql->options.thread_specific_malloc ? + MY_THREAD_SPECIFIC : 0))) { vio_delete(net->vio); net->vio = 0; @@ -4218,6 +4222,9 @@ mysql_options(MYSQL *mysql,enum mysql_option option, const void *arg) mysql->options.extension->report_progress= (void (*)(const MYSQL *, uint, uint, double, const char *, uint)) arg; break; + case MYSQL_THREAD_SPECIFIC_MALLOC: + mysql->options.thread_specific_malloc= *(uint*) arg; + break; case MYSQL_OPT_NONBLOCK: if (mysql->options.extension && (ctxt = mysql->options.extension->async_context) != 0) diff --git a/sql-common/client_plugin.c b/sql-common/client_plugin.c index f31ddb22a6a..bc0cff85eb6 100644 --- a/sql-common/client_plugin.c +++ b/sql-common/client_plugin.c @@ -251,7 +251,7 @@ int mysql_client_plugin_init() bzero(&mysql, sizeof(mysql)); /* dummy mysql for set_mysql_extended_error */ pthread_mutex_init(&LOCK_load_client_plugin, MY_MUTEX_INIT_SLOW); - init_alloc_root(&mem_root, 128, 128); + init_alloc_root(&mem_root, 128, 128, 0); bzero(&plugin_list, sizeof(plugin_list)); diff --git a/sql/debug_sync.cc b/sql/debug_sync.cc index 1c95869987d..28d1109a0b4 100644 --- a/sql/debug_sync.cc +++ b/sql/debug_sync.cc @@ -239,7 +239,8 @@ void debug_sync_init_thread(THD *thd) if (opt_debug_sync_timeout) { thd->debug_sync_control= (st_debug_sync_control*) - my_malloc(sizeof(st_debug_sync_control), MYF(MY_WME | MY_ZEROFILL)); + my_malloc(sizeof(st_debug_sync_control), + MYF(MY_WME | MY_ZEROFILL | MY_THREAD_SPECIFIC)); if (!thd->debug_sync_control) { /* diff --git a/sql/event_data_objects.cc b/sql/event_data_objects.cc index c41194d1a8d..a5dac4c154b 100644 --- a/sql/event_data_objects.cc +++ b/sql/event_data_objects.cc @@ -209,7 +209,7 @@ Event_basic::Event_basic() { DBUG_ENTER("Event_basic::Event_basic"); /* init memory root */ - init_sql_alloc(&mem_root, 256, 512); + init_sql_alloc(&mem_root, 256, 512, 0); dbname.str= name.str= NULL; dbname.length= name.length= 0; time_zone= NULL; diff --git a/sql/event_scheduler.cc b/sql/event_scheduler.cc index f107914f738..8c3e57778ab 100644 --- a/sql/event_scheduler.cc +++ b/sql/event_scheduler.cc @@ -153,8 +153,6 @@ void deinit_event_thread(THD *thd) { thd->proc_info= "Clearing"; - DBUG_ASSERT(thd->net.buff != 0); - net_end(&thd->net); DBUG_PRINT("exit", ("Event thread finishing")); mysql_mutex_lock(&LOCK_thread_count); thread_count--; @@ -182,12 +180,15 @@ deinit_event_thread(THD *thd) void pre_init_event_thread(THD* thd) { + THD *orig_thd= current_thd; DBUG_ENTER("pre_init_event_thread"); + + set_current_thd(thd); thd->client_capabilities= 0; thd->security_ctx->master_access= 0; thd->security_ctx->db_access= 0; thd->security_ctx->host_or_ip= (char*)my_localhost; - my_net_init(&thd->net, NULL); + my_net_init(&thd->net, NULL, MYF(MY_THREAD_SPECIFIC)); thd->security_ctx->set_user((char*)"event_scheduler"); thd->net.read_timeout= slave_net_timeout; thd->variables.option_bits|= OPTION_AUTO_IS_NULL; @@ -207,6 +208,7 @@ pre_init_event_thread(THD* thd) /* Do not use user-supplied timeout value for system threads. */ thd->variables.lock_wait_timeout= LONG_TIMEOUT; + set_current_thd(orig_thd); DBUG_VOID_RETURN; } @@ -402,6 +404,7 @@ Event_scheduler::start() ret= TRUE; goto end; } + pre_init_event_thread(new_thd); new_thd->system_thread= SYSTEM_THREAD_EVENT_SCHEDULER; new_thd->command= COM_DAEMON; @@ -413,6 +416,7 @@ Event_scheduler::start() */ new_thd->security_ctx->master_access |= SUPER_ACL; + /* This should not be marked with MY_THREAD_SPECIFIC */ scheduler_param_value= (struct scheduler_param *)my_malloc(sizeof(struct scheduler_param), MYF(0)); scheduler_param_value->thd= new_thd; @@ -432,8 +436,6 @@ Event_scheduler::start() ret= TRUE; new_thd->proc_info= "Clearing"; - DBUG_ASSERT(new_thd->net.buff != 0); - net_end(&new_thd->net); mysql_mutex_lock(&LOCK_thread_count); thread_count--; dec_thread_running(); @@ -533,6 +535,7 @@ Event_scheduler::execute_top(Event_queue_element_for_exec *event_name) pthread_t th; int res= 0; DBUG_ENTER("Event_scheduler::execute_top"); + if (!(new_thd= new THD())) goto error; @@ -567,8 +570,6 @@ error: if (new_thd) { new_thd->proc_info= "Clearing"; - DBUG_ASSERT(new_thd->net.buff != 0); - net_end(&new_thd->net); mysql_mutex_lock(&LOCK_thread_count); thread_count--; dec_thread_running(); diff --git a/sql/events.cc b/sql/events.cc index d8caa059c64..46b13056d7d 100644 --- a/sql/events.cc +++ b/sql/events.cc @@ -879,7 +879,7 @@ end: } delete thd; /* Remember that we don't have a THD */ - my_pthread_setspecific_ptr(THR_THD, NULL); + set_current_thd(0); DBUG_RETURN(res); } diff --git a/sql/filesort.cc b/sql/filesort.cc index 9c40ab877a4..3f735e94a11 100644 --- a/sql/filesort.cc +++ b/sql/filesort.cc @@ -200,7 +200,8 @@ ha_rows filesort(THD *thd, TABLE *table, SORT_FIELD *sortorder, uint s_length, table_sort.unpack= unpack_addon_fields; if (param.addon_field && !(table_sort.addon_buf= - (uchar *) my_malloc(param.addon_length, MYF(MY_WME)))) + (uchar *) my_malloc(param.addon_length, MYF(MY_WME | + MY_THREAD_SPECIFIC)))) goto err; if (select && select->quick) @@ -213,7 +214,8 @@ ha_rows filesort(THD *thd, TABLE *table, SORT_FIELD *sortorder, uint s_length, num_rows= table->file->estimate_rows_upper_bound(); if (multi_byte_charset && - !(param.tmp_buffer= (char*) my_malloc(param.sort_length,MYF(MY_WME)))) + !(param.tmp_buffer= (char*) my_malloc(param.sort_length, + MYF(MY_WME | MY_THREAD_SPECIFIC)))) goto err; if (check_if_pq_applicable(¶m, &table_sort, @@ -453,7 +455,7 @@ static uchar *read_buffpek_from_file(IO_CACHE *buffpek_pointers, uint count, if (count > UINT_MAX/sizeof(BUFFPEK)) return 0; /* sizeof(BUFFPEK)*count will overflow */ if (!tmp) - tmp= (uchar *)my_malloc(length, MYF(MY_WME)); + tmp= (uchar *)my_malloc(length, MYF(MY_WME | MY_THREAD_SPECIFIC)); if (tmp) { if (reinit_io_cache(buffpek_pointers,READ_CACHE,0L,0,0) || @@ -1155,7 +1157,8 @@ static bool save_index(Sort_param *param, uint count, Filesort_info *table_sort) res_length= param->res_length; offset= param->rec_length-res_length; if (!(to= table_sort->record_pointers= - (uchar*) my_malloc(res_length*count, MYF(MY_WME)))) + (uchar*) my_malloc(res_length*count, + MYF(MY_WME | MY_THREAD_SPECIFIC)))) DBUG_RETURN(1); /* purecov: inspected */ uchar **sort_keys= table_sort->get_sort_keys(); for (uchar **end= sort_keys+count ; sort_keys != end ; sort_keys++) @@ -1897,7 +1900,9 @@ get_addon_fields(ulong max_length_for_sort_data, if (length+sortlength > max_length_for_sort_data || !(addonf= (SORT_ADDON_FIELD *) my_malloc(sizeof(SORT_ADDON_FIELD)* - (fields+1), MYF(MY_WME)))) + (fields+1), + MYF(MY_WME | + MY_THREAD_SPECIFIC)))) return 0; *plength= length; diff --git a/sql/filesort_utils.cc b/sql/filesort_utils.cc index c4480a6376d..f8f6d5c9420 100644 --- a/sql/filesort_utils.cc +++ b/sql/filesort_utils.cc @@ -99,7 +99,7 @@ uchar **Filesort_buffer::alloc_sort_buffer(uint num_records, uint record_length) sort_buff_sz= num_records * (record_length + sizeof(uchar*)); set_if_bigger(sort_buff_sz, record_length * MERGEBUFF2); uchar **sort_keys= - (uchar**) my_malloc(sort_buff_sz, MYF(0)); + (uchar**) my_malloc(sort_buff_sz, MYF(MY_THREAD_SPECIFIC)); m_idx_array= Idx_array(sort_keys, num_records); m_record_length= record_length; uchar **start_of_data= m_idx_array.array() + m_idx_array.size(); @@ -130,7 +130,8 @@ void Filesort_buffer::sort_buffer(const Sort_param *param, uint count) uchar **keys= get_sort_keys(); uchar **buffer= NULL; if (radixsort_is_appliccable(count, param->sort_length) && - (buffer= (uchar**) my_malloc(count*sizeof(char*), MYF(0)))) + (buffer= (uchar**) my_malloc(count*sizeof(char*), + MYF(MY_THREAD_SPECIFIC)))) { radixsort_for_str_ptr(keys, count, param->sort_length, buffer); my_free(buffer); @@ -140,4 +141,3 @@ void Filesort_buffer::sort_buffer(const Sort_param *param, uint count) size_t size= param->sort_length; my_qsort2(keys, count, sizeof(uchar*), get_ptr_compare(size), &size); } - diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index 6ba4fe46441..44d384e7f2d 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -8649,7 +8649,7 @@ NDB_SHARE *ndbcluster_get_share(const char *key, TABLE *table, MEM_ROOT **root_ptr= my_pthread_getspecific_ptr(MEM_ROOT**, THR_MALLOC); MEM_ROOT *old_root= *root_ptr; - init_sql_alloc(&share->mem_root, 1024, 0); + init_sql_alloc(&share->mem_root, 1024, 0, 0); *root_ptr= &share->mem_root; // remember to reset before return share->state= NSS_INITIAL; /* enough space for key, db, and table_name */ @@ -9493,7 +9493,7 @@ pthread_handler_t ndb_util_thread_func(void *arg __attribute__((unused))) thd->init_for_queries(); thd->main_security_ctx.host_or_ip= ""; thd->client_capabilities = 0; - my_net_init(&thd->net, 0); + my_net_init(&thd->net, 0, MYF(MY_THREAD_SPECIFIC)); thd->main_security_ctx.master_access= ~0; thd->main_security_ctx.priv_user[0] = 0; /* Do not use user-supplied timeout value for system threads. */ @@ -9730,11 +9730,9 @@ next: mysql_mutex_lock(&LOCK_ndb_util_thread); ndb_util_thread_end: - net_end(&thd->net); ndb_util_thread_fail: if (share_list) delete [] share_list; - thd->cleanup(); delete thd; /* signal termination */ diff --git a/sql/ha_ndbcluster_binlog.cc b/sql/ha_ndbcluster_binlog.cc index 59b9d6eab6b..e7582d695ce 100644 --- a/sql/ha_ndbcluster_binlog.cc +++ b/sql/ha_ndbcluster_binlog.cc @@ -3665,7 +3665,7 @@ pthread_handler_t ndb_binlog_thread_func(void *arg) thd->system_thread= SYSTEM_THREAD_NDBCLUSTER_BINLOG; thd->main_security_ctx.host_or_ip= ""; thd->client_capabilities= 0; - my_net_init(&thd->net, 0); + my_net_init(&thd->net, 0, MYF(MY_THREAD_SPECIFIC)); thd->main_security_ctx.master_access= ~0; thd->main_security_ctx.priv_user[0]= 0; /* Do not use user-supplied timeout value for system threads. */ @@ -3964,7 +3964,7 @@ restart: my_pthread_getspecific_ptr(MEM_ROOT**, THR_MALLOC); MEM_ROOT *old_root= *root_ptr; MEM_ROOT mem_root; - init_sql_alloc(&mem_root, 4096, 0); + init_sql_alloc(&mem_root, 4096, 0, 0); List<Cluster_schema> post_epoch_log_list; List<Cluster_schema> post_epoch_unlock_list; *root_ptr= &mem_root; @@ -4364,8 +4364,6 @@ err: my_hash_free(&ndb_schema_objects); - net_end(&thd->net); - thd->cleanup(); delete thd; ndb_binlog_thread_running= -1; diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index b87192db69f..e28c461f4ce 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -168,7 +168,7 @@ ha_partition::ha_partition(handlerton *hton, TABLE_SHARE *share) :handler(hton, share) { DBUG_ENTER("ha_partition::ha_partition(table)"); - init_alloc_root(&m_mem_root, 512, 512); + init_alloc_root(&m_mem_root, 512, 512, 0); init_handler_variables(); DBUG_VOID_RETURN; } @@ -190,7 +190,7 @@ ha_partition::ha_partition(handlerton *hton, partition_info *part_info) { DBUG_ENTER("ha_partition::ha_partition(part_info)"); DBUG_ASSERT(part_info); - init_alloc_root(&m_mem_root, 512, 512); + init_alloc_root(&m_mem_root, 512, 512, 0); init_handler_variables(); m_part_info= part_info; m_create_handler= TRUE; @@ -217,7 +217,7 @@ ha_partition::ha_partition(handlerton *hton, TABLE_SHARE *share, :handler(hton, share) { DBUG_ENTER("ha_partition::ha_partition(clone)"); - init_alloc_root(&m_mem_root, 512, 512); + init_alloc_root(&m_mem_root, 512, 512, 0); init_handler_variables(); m_part_info= part_info_arg; m_create_handler= TRUE; diff --git a/sql/handler.cc b/sql/handler.cc index 6634bd6fb7a..0fac0d756ca 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -5352,7 +5352,7 @@ fl_log_iterator_buffer_init(struct handler_iterator *iterator) /* to be able to make my_free without crash in case of error */ iterator->buffer= 0; - if (!(dirp = my_dir(fl_dir, MYF(0)))) + if (!(dirp = my_dir(fl_dir, MYF(MY_THREAD_SPECIFIC)))) { return HA_ITERATOR_ERROR; } @@ -5361,7 +5361,7 @@ fl_log_iterator_buffer_init(struct handler_iterator *iterator) sizeof(enum log_status) + + FN_REFLEN + 1) * (uint) dirp->number_off_files), - MYF(0))) == 0) + MYF(MY_THREAD_SPECIFIC))) == 0) { return HA_ITERATOR_ERROR; } @@ -5395,6 +5395,7 @@ fl_log_iterator_buffer_init(struct handler_iterator *iterator) iterator->buffer= buff; iterator->next= &fl_log_iterator_next; iterator->destroy= &fl_log_iterator_destroy; + my_dirend(dirp); return HA_ITERATOR_OK; } diff --git a/sql/item_func.cc b/sql/item_func.cc index f0ca37152a3..520b5522d38 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -4343,7 +4343,9 @@ user_var_entry *get_variable(HASH *hash, LEX_STRING &name, uint size=ALIGN_SIZE(sizeof(user_var_entry))+name.length+1+extra_size; if (!my_hash_inited(hash)) return 0; - if (!(entry = (user_var_entry*) my_malloc(size,MYF(MY_WME | ME_FATALERROR)))) + if (!(entry = (user_var_entry*) my_malloc(size, + MYF(MY_WME | ME_FATALERROR | + MY_THREAD_SPECIFIC)))) return 0; entry->name.str=(char*) entry+ ALIGN_SIZE(sizeof(user_var_entry))+ extra_size; @@ -4571,7 +4573,8 @@ update_hash(user_var_entry *entry, bool set_null, void *ptr, uint length, entry->value=0; entry->value= (char*) my_realloc(entry->value, length, MYF(MY_ALLOW_ZERO_PTR | MY_WME | - ME_FATALERROR)); + ME_FATALERROR | + MY_THREAD_SPECIFIC)); if (!entry->value) return 1; } diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index ab77bb0e59c..2ee513320ce 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -5053,7 +5053,7 @@ bool Ordered_key::alloc_keys_buffers() DBUG_ASSERT(key_buff_elements > 0); if (!(key_buff= (rownum_t*) my_malloc((size_t)(key_buff_elements * - sizeof(rownum_t)), MYF(MY_WME)))) + sizeof(rownum_t)), MYF(MY_WME | MY_THREAD_SPECIFIC)))) return TRUE; /* @@ -5480,7 +5480,7 @@ subselect_rowid_merge_engine::init(MY_BITMAP *non_null_key_parts, !(null_bitmaps= (MY_BITMAP**) thd->alloc(merge_keys_count * sizeof(MY_BITMAP*))) || !(row_num_to_rowid= (uchar*) my_malloc((size_t)(row_count * rowid_length), - MYF(MY_WME)))) + MYF(MY_WME | MY_THREAD_SPECIFIC)))) return TRUE; /* Create the only non-NULL key if there is any. */ diff --git a/sql/item_sum.cc b/sql/item_sum.cc index 217e65e401f..b1e248032bc 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -3485,7 +3485,8 @@ bool Item_func_group_concat::setup(THD *thd) init_tree(tree, (uint) min(thd->variables.max_heap_table_size, thd->variables.sortbuff_size/16), 0, tree_key_length, - group_concat_key_cmp_with_order , 0, NULL, (void*) this); + group_concat_key_cmp_with_order, NULL, (void*) this, + MYF(MY_THREAD_SPECIFIC)); } if (distinct) diff --git a/sql/log.cc b/sql/log.cc index 1ffceaf05a3..c6d91b1f67e 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -8194,8 +8194,9 @@ binlog_background_thread(void *arg __attribute__((unused))) bool stop; MYSQL_BIN_LOG::xid_count_per_binlog *queue, *next; THD *thd; - my_thread_init(); + DBUG_ENTER("binlog_background_thread"); + thd= new THD; thd->system_thread= SYSTEM_THREAD_BINLOG_BACKGROUND; thd->thread_stack= (char*) &thd; /* Set approximate stack start */ @@ -8259,7 +8260,7 @@ binlog_background_thread(void *arg __attribute__((unused))) mysql_cond_signal(&mysql_bin_log.COND_binlog_background_thread_end); mysql_mutex_unlock(&mysql_bin_log.LOCK_binlog_background_thread); - return 0; + DBUG_RETURN(0); } #ifdef HAVE_PSI_INTERFACE @@ -8310,7 +8311,7 @@ int TC_LOG_BINLOG::recover(LOG_INFO *linfo, const char *last_log_name, sizeof(my_xid), 0, 0, MYF(0))) goto err1; - init_alloc_root(&mem_root, TC_LOG_PAGE_SIZE, TC_LOG_PAGE_SIZE); + init_alloc_root(&mem_root, TC_LOG_PAGE_SIZE, TC_LOG_PAGE_SIZE, 0); fdle->flags&= ~LOG_EVENT_BINLOG_IN_USE_F; // abort on the first error diff --git a/sql/mdl.cc b/sql/mdl.cc index 5e297051377..97858646652 100644 --- a/sql/mdl.cc +++ b/sql/mdl.cc @@ -2200,7 +2200,8 @@ bool MDL_context::acquire_locks(MDL_request_list *mdl_requests, /* Sort requests according to MDL_key. */ if (! (sort_buf= (MDL_request **)my_malloc(req_count * sizeof(MDL_request*), - MYF(MY_WME)))) + MYF(MY_WME | + MY_THREAD_SPECIFIC)))) DBUG_RETURN(TRUE); for (p_req= sort_buf; p_req < sort_buf + req_count; p_req++) diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 6d3c5980280..ca68f8c9ae2 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -1121,7 +1121,7 @@ private: void Buffered_logs::init() { - init_alloc_root(&m_root, 1024, 0); + init_alloc_root(&m_root, 1024, 0, 0); } void Buffered_logs::cleanup() @@ -1765,6 +1765,7 @@ extern "C" void unireg_abort(int exit_code) static void mysqld_exit(int exit_code) { + DBUG_ENTER("mysqld_exit"); /* Important note: we wait for the signal thread to end, but if a kill -15 signal was sent, the signal thread did @@ -1776,6 +1777,7 @@ static void mysqld_exit(int exit_code) clean_up_error_log_mutex(); my_end((opt_endinfo ? MY_CHECK_ERROR | MY_GIVE_INFO : 0)); shutdown_performance_schema(); // we do it as late as possible + DBUG_LEAVE; exit(exit_code); /* purecov: inspected */ } @@ -2485,9 +2487,13 @@ void unlink_thd(THD *thd) sync feature has been shut down at this point. */ DBUG_EXECUTE_IF("sleep_after_lock_thread_count_before_delete_thd", sleep(5);); + /* + We must delete thd inside the lock to ensure that we don't start cleanup + before THD is deleted + */ + delete thd; mysql_mutex_unlock(&LOCK_thread_count); - delete thd; DBUG_VOID_RETURN; } @@ -2594,7 +2600,7 @@ bool one_thread_per_connection_end(THD *thd, bool put_in_cache) DBUG_ENTER("one_thread_per_connection_end"); unlink_thd(thd); /* Mark that current_thd is not valid anymore */ - my_pthread_setspecific_ptr(THR_THD, 0); + set_current_thd(0); if (put_in_cache) { mysql_mutex_lock(&LOCK_thread_count); @@ -2606,9 +2612,10 @@ bool one_thread_per_connection_end(THD *thd, bool put_in_cache) /* It's safe to broadcast outside a lock (COND... is not deleted here) */ DBUG_PRINT("signal", ("Broadcasting COND_thread_count")); + mysql_cond_broadcast(&COND_thread_count); + DBUG_LEAVE; // Must match DBUG_ENTER() my_thread_end(); - mysql_cond_broadcast(&COND_thread_count); pthread_exit(0); return 0; // Avoid compiler warnings @@ -3142,9 +3149,9 @@ void my_message_sql(uint error, const char *str, myf MyFlags) THD *thd= current_thd; MYSQL_ERROR::enum_warning_level level; sql_print_message_func func; - DBUG_ENTER("my_message_sql"); - DBUG_PRINT("error", ("error: %u message: '%s' Flag: %d", error, str, MyFlags)); + DBUG_PRINT("error", ("error: %u message: '%s' Flag: %lu", error, str, + MyFlags)); DBUG_ASSERT(str != NULL); DBUG_ASSERT(error != 0); @@ -3430,6 +3437,28 @@ SHOW_VAR com_status_vars[]= { {NullS, NullS, SHOW_LONG} }; +#ifdef SAFEMALLOC +/* + Return the id for the current THD, to allow safemalloc to associate + the memory with the right id. +*/ + +extern "C" my_thread_id mariadb_dbug_id() +{ + THD *thd; + if ((thd= current_thd)) + { + return thd->thread_id; + } + return my_thread_dbug_id(); +} +#endif /* SAFEMALLOC */ + + +/* + Init common variables +*/ + static int init_common_variables() { umask(((~my_umask) & 0666)); @@ -3438,6 +3467,9 @@ static int init_common_variables() tzset(); // Set tzname sf_leaking_memory= 0; // no memory leaks from now on +#ifdef SAFEMALLOC + sf_malloc_dbug_id= mariadb_dbug_id; +#endif max_system_variables.pseudo_thread_id= (ulong)~0; server_start_time= flush_status_time= my_time(0); @@ -3897,6 +3929,7 @@ You should consider changing lower_case_table_names to 1 or 2", static int init_thread_environment() { + DBUG_ENTER("init_thread_environment"); mysql_mutex_init(key_LOCK_thread_count, &LOCK_thread_count, MY_MUTEX_INIT_FAST); mysql_mutex_init(key_LOCK_status, &LOCK_status, MY_MUTEX_INIT_FAST); mysql_mutex_init(key_LOCK_delayed_insert, @@ -3975,9 +4008,9 @@ static int init_thread_environment() pthread_key_create(&THR_MALLOC,NULL)) { sql_print_error("Can't create thread-keys"); - return 1; + DBUG_RETURN(1); } - return 0; + DBUG_RETURN(0); } @@ -4641,6 +4674,37 @@ static void test_lc_time_sz() } #endif//DBUG_OFF + +/* Thread Mem Usage By P.Linux */ +extern "C" +void my_malloc_size_cb_func(long long size, myf my_flags) +{ + /* If thread specific memory */ + if (my_flags) + { + THD *thd= current_thd; + if (mysqld_server_initialized || thd) + { + /* + THD may not be set if we are called from my_net_init() before THD + thread has started. + However, this should never happen, so better to assert and + fix this. + */ + DBUG_ASSERT(thd); + if (thd) + { + DBUG_PRINT("info", ("memory_used: %lld size: %lld", + (longlong) thd->status_var.memory_used, size)); + thd->status_var.memory_used+= size; + DBUG_ASSERT((longlong) thd->status_var.memory_used >= 0); + } + } + } + my_atomic_add64(&global_status_var.memory_used, size); +} + + #ifdef __WIN__ int win_main(int argc, char **argv) #else @@ -4653,6 +4717,9 @@ int mysqld_main(int argc, char **argv) */ my_progname= argv[0]; sf_leaking_memory= 1; // no safemalloc memory leak reports if we exit early + set_malloc_size_cb(my_malloc_size_cb_func); + mysqld_server_started= mysqld_server_initialized= 0; + #ifdef HAVE_NPTL ld_assume_kernel_is_set= (getenv("LD_ASSUME_KERNEL") != 0); #endif @@ -4665,7 +4732,6 @@ int mysqld_main(int argc, char **argv) } #endif - mysqld_server_started= mysqld_server_initialized= 0; orig_argc= argc; orig_argv= argv; my_getopt_use_args_separator= TRUE; @@ -4695,7 +4761,7 @@ int mysqld_main(int argc, char **argv) my_getopt_skip_unknown= TRUE; /* prepare all_early_options array */ - my_init_dynamic_array(&all_early_options, sizeof(my_option), 100, 25); + my_init_dynamic_array(&all_early_options, sizeof(my_option), 100, 25, 0); sys_var_add_options(&all_early_options, sys_var::PARSE_EARLY); add_terminator(&all_early_options); @@ -4956,8 +5022,6 @@ int mysqld_main(int argc, char **argv) if (Events::init(opt_noacl || opt_bootstrap)) unireg_abort(1); - mysqld_server_initialized= 1; - if (opt_bootstrap) { select_thread_in_use= 0; // Allow 'kill' to work @@ -4971,6 +5035,9 @@ int mysqld_main(int argc, char **argv) } } + /* It's now safe to use thread specific memory */ + mysqld_server_initialized= 1; + create_shutdown_thread(); start_handle_manager(); @@ -5000,7 +5067,6 @@ int mysqld_main(int argc, char **argv) Service.SetRunning(); #endif - /* Signal threads waiting for server to be started */ mysql_mutex_lock(&LOCK_server_started); mysqld_server_started= 1; @@ -5180,6 +5246,7 @@ int mysqld_main(int argc, char **argv) /* Must be initialized early for comparison of service name */ system_charset_info= &my_charset_utf8_general_ci; + set_malloc_size_cb(my_malloc_size_cb_func); if (my_init()) { @@ -5288,7 +5355,7 @@ static void bootstrap(MYSQL_FILE *file) THD *thd= new THD; thd->bootstrap=1; - my_net_init(&thd->net,(st_vio*) 0); + my_net_init(&thd->net,(st_vio*) 0, 0); thd->max_client_packet_length= thd->net.max_packet; thd->security_ctx->master_access= ~(ulong)0; thd->thread_id= thd->variables.pseudo_thread_id= thread_id++; @@ -5705,17 +5772,20 @@ void handle_connections_sockets() ** Don't allow too many connections */ + DBUG_PRINT("info", ("Creating THD for new connection")); if (!(thd= new THD)) { (void) mysql_socket_shutdown(new_sock, SHUT_RDWR); (void) closesocket(new_sock); continue; } + /* Set to get io buffers to be part of THD */ + set_current_thd(thd); if (!(vio_tmp=vio_new(new_sock, sock == unix_sock ? VIO_TYPE_SOCKET : VIO_TYPE_TCPIP, sock == unix_sock ? VIO_LOCALHOST: 0)) || - my_net_init(&thd->net,vio_tmp)) + my_net_init(&thd->net, vio_tmp, MYF(MY_THREAD_SPECIFIC))) { /* Only delete the temporary vio if we didn't already attach it to the @@ -5730,6 +5800,7 @@ void handle_connections_sockets() (void) closesocket(new_sock); } delete thd; + set_current_thd(0); continue; } if (sock == unix_sock) @@ -5741,6 +5812,7 @@ void handle_connections_sockets() thd->scheduler= extra_thread_scheduler; } create_new_thread(thd); + set_current_thd(0); } DBUG_VOID_RETURN; } @@ -5834,16 +5906,19 @@ pthread_handler_t handle_connections_namedpipes(void *arg) CloseHandle(hConnectedPipe); continue; } + set_current_thd(thd); if (!(thd->net.vio= vio_new_win32pipe(hConnectedPipe)) || - my_net_init(&thd->net, thd->net.vio)) + my_net_init(&thd->net, thd->net.vio, MYF(MY_THREAD_SPECIFIC))) { close_connection(thd, ER_OUT_OF_RESOURCES); delete thd; + set_current_thd(0); continue; } /* Host is unknown */ thd->security_ctx->host= my_strdup(my_localhost, MYF(0)); create_new_thread(thd); + set_current_thd(0); } CloseHandle(connectOverlapped.hEvent); DBUG_LEAVE; @@ -6023,6 +6098,7 @@ pthread_handler_t handle_connections_shared_memory(void *arg) errmsg= "Could not set client to read mode"; goto errorconn; } + set_current_thd(thd); if (!(thd->net.vio= vio_new_win32shared_memory(handle_client_file_map, handle_client_map, event_client_wrote, @@ -6030,7 +6106,7 @@ pthread_handler_t handle_connections_shared_memory(void *arg) event_server_wrote, event_server_read, event_conn_closed)) || - my_net_init(&thd->net, thd->net.vio)) + my_net_init(&thd->net, thd->net.vio, MYF(MY_THREAD_SPECIFIC))) { close_connection(thd, ER_OUT_OF_RESOURCES); errmsg= 0; @@ -6039,6 +6115,7 @@ pthread_handler_t handle_connections_shared_memory(void *arg) thd->security_ctx->host= my_strdup(my_localhost, MYF(0)); /* Host is unknown */ create_new_thread(thd); connect_number++; + set_current_thd(thd); continue; errorconn: @@ -6066,6 +6143,7 @@ errorconn: CloseHandle(event_conn_closed); delete thd; } + set_current_thd(0); /* End shared memory handling */ error: @@ -7024,6 +7102,7 @@ SHOW_VAR status_vars[]= { {"Key", (char*) &show_default_keycache, SHOW_FUNC}, {"Last_query_cost", (char*) offsetof(STATUS_VAR, last_query_cost), SHOW_DOUBLE_STATUS}, {"Max_used_connections", (char*) &max_used_connections, SHOW_LONG}, + {"Memory_used", (char*) offsetof(STATUS_VAR, memory_used), SHOW_LONGLONG_STATUS}, {"Not_flushed_delayed_rows", (char*) &delayed_rows_in_use, SHOW_LONG_NOFLUSH}, {"Open_files", (char*) &my_file_opened, SHOW_LONG_NOFLUSH}, {"Open_streams", (char*) &my_stream_opened, SHOW_LONG_NOFLUSH}, @@ -7170,7 +7249,7 @@ static int option_cmp(my_option *a, my_option *b) static void print_help() { MEM_ROOT mem_root; - init_alloc_root(&mem_root, 4096, 4096); + init_alloc_root(&mem_root, 4096, 4096, 0); pop_dynamic(&all_options); sys_var_add_options(&all_options, sys_var::PARSE_EARLY); @@ -7862,7 +7941,7 @@ static int get_options(int *argc_ptr, char ***argv_ptr) /* prepare all_options array */ my_init_dynamic_array(&all_options, sizeof(my_option), array_elements(my_long_options), - array_elements(my_long_options)/4); + array_elements(my_long_options)/4, 0); for (my_option *opt= my_long_options; opt < my_long_options + array_elements(my_long_options) - 1; opt++) @@ -8364,7 +8443,7 @@ void refresh_status(THD *thd) add_to_status(&global_status_var, &thd->status_var); /* Reset thread's status variables */ - bzero((uchar*) &thd->status_var, sizeof(thd->status_var)); + thd->set_status_var_init(); bzero((uchar*) &thd->org_status_var, sizeof(thd->org_status_var)); thd->start_bytes_received= 0; diff --git a/sql/mysqld.h b/sql/mysqld.h index a9b41a5e116..e9c4f713182 100644 --- a/sql/mysqld.h +++ b/sql/mysqld.h @@ -534,6 +534,7 @@ inline THD *_current_thd(void) } #endif #define current_thd _current_thd() +#define set_current_thd(X) my_pthread_setspecific_ptr(THR_THD, (X)) /* @todo remove, make it static in ha_maria.cc diff --git a/sql/net_serv.cc b/sql/net_serv.cc index 08ac93f3091..cf3e962053c 100644 --- a/sql/net_serv.cc +++ b/sql/net_serv.cc @@ -120,14 +120,15 @@ static my_bool net_write_buff(NET *net,const uchar *packet,ulong len); /** Init with packet info. */ -my_bool my_net_init(NET *net, Vio* vio) +my_bool my_net_init(NET *net, Vio* vio, uint my_flags) { DBUG_ENTER("my_net_init"); + DBUG_PRINT("enter", ("my_flags: %u", my_flags)); net->vio = vio; my_net_local_init(net); /* Set some limits */ if (!(net->buff=(uchar*) my_malloc((size_t) net->max_packet+ NET_HEADER_SIZE + COMP_HEADER_SIZE +1, - MYF(MY_WME)))) + MYF(MY_WME | my_flags)))) DBUG_RETURN(1); net->buff_end=net->buff+net->max_packet; net->error=0; net->return_status=0; @@ -139,6 +140,7 @@ my_bool my_net_init(NET *net, Vio* vio) net->net_skip_rest_factor= 0; net->last_errno=0; net->unused= 0; + net->thread_specific_malloc= test(my_flags & MY_THREAD_SPECIFIC); if (vio != 0) /* If real connection */ { @@ -193,7 +195,9 @@ my_bool net_realloc(NET *net, size_t length) */ if (!(buff= (uchar*) my_realloc((char*) net->buff, pkt_length + NET_HEADER_SIZE + COMP_HEADER_SIZE + 1, - MYF(MY_WME)))) + MYF(MY_WME | + (net->thread_specific_malloc ? + MY_THREAD_SPECIFIC : 0))))) { /* @todo: 1 and 2 codes are identical. */ net->error= 1; @@ -603,7 +607,10 @@ net_real_write(NET *net,const uchar *packet, size_t len) uchar *b; uint header_length=NET_HEADER_SIZE+COMP_HEADER_SIZE; if (!(b= (uchar*) my_malloc(len + NET_HEADER_SIZE + - COMP_HEADER_SIZE + 1, MYF(MY_WME)))) + COMP_HEADER_SIZE + 1, + MYF(MY_WME | + (net->thread_specific_malloc ? + MY_THREAD_SPECIFIC : 0))))) { net->error= 2; net->last_errno= ER_OUT_OF_RESOURCES; diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 7f8d527564b..d3c2ec5a132 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -1772,7 +1772,8 @@ QUICK_RANGE_SELECT::QUICK_RANGE_SELECT(THD *thd, TABLE *table, uint key_nr, index= key_nr; head= table; key_part_info= head->key_info[index].key_part; - my_init_dynamic_array(&ranges, sizeof(QUICK_RANGE*), 16, 16); + my_init_dynamic_array(&ranges, sizeof(QUICK_RANGE*), 16, 16, + MYF(MY_THREAD_SPECIFIC)); /* 'thd' is not accessible in QUICK_RANGE_SELECT::reset(). */ mrr_buf_size= thd->variables.mrr_buff_size; @@ -1781,7 +1782,8 @@ QUICK_RANGE_SELECT::QUICK_RANGE_SELECT(THD *thd, TABLE *table, uint key_nr, if (!no_alloc && !parent_alloc) { // Allocates everything through the internal memroot - init_sql_alloc(&alloc, thd->variables.range_alloc_block_size, 0); + init_sql_alloc(&alloc, thd->variables.range_alloc_block_size, 0, + MYF(MY_THREAD_SPECIFIC)); thd->mem_root= &alloc; } else @@ -1793,7 +1795,7 @@ QUICK_RANGE_SELECT::QUICK_RANGE_SELECT(THD *thd, TABLE *table, uint key_nr, /* Allocate a bitmap for used columns (Q: why not on MEM_ROOT?) */ if (!(bitmap= (my_bitmap_map*) my_malloc(head->s->column_bitmap_size, - MYF(MY_WME)))) + MYF(MY_WME | MY_THREAD_SPECIFIC)))) { column_bitmap.bitmap= 0; *create_error= 1; @@ -1879,7 +1881,8 @@ QUICK_INDEX_SORT_SELECT::QUICK_INDEX_SORT_SELECT(THD *thd_param, index= MAX_KEY; head= table; bzero(&read_record, sizeof(read_record)); - init_sql_alloc(&alloc, thd->variables.range_alloc_block_size, 0); + init_sql_alloc(&alloc, thd->variables.range_alloc_block_size, 0, + MYF(MY_THREAD_SPECIFIC)); DBUG_VOID_RETURN; } @@ -1949,7 +1952,8 @@ QUICK_ROR_INTERSECT_SELECT::QUICK_ROR_INTERSECT_SELECT(THD *thd_param, head= table; record= head->record[0]; if (!parent_alloc) - init_sql_alloc(&alloc, thd->variables.range_alloc_block_size, 0); + init_sql_alloc(&alloc, thd->variables.range_alloc_block_size, 0, + MYF(MY_THREAD_SPECIFIC)); else bzero(&alloc, sizeof(MEM_ROOT)); last_rowid= (uchar*) alloc_root(parent_alloc? parent_alloc : &alloc, @@ -2232,7 +2236,8 @@ QUICK_ROR_UNION_SELECT::QUICK_ROR_UNION_SELECT(THD *thd_param, head= table; rowid_length= table->file->ref_length; record= head->record[0]; - init_sql_alloc(&alloc, thd->variables.range_alloc_block_size, 0); + init_sql_alloc(&alloc, thd->variables.range_alloc_block_size, 0, + MYF(MY_THREAD_SPECIFIC)); thd_param->mem_root= &alloc; } @@ -2966,7 +2971,8 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use, param.force_default_mrr= ordered_output; thd->no_errors=1; // Don't warn about NULL - init_sql_alloc(&alloc, thd->variables.range_alloc_block_size, 0); + init_sql_alloc(&alloc, thd->variables.range_alloc_block_size, 0, + MYF(MY_THREAD_SPECIFIC)); if (!(param.key_parts= (KEY_PART*) alloc_root(&alloc, sizeof(KEY_PART) * @@ -3411,7 +3417,8 @@ bool prune_partitions(THD *thd, TABLE *table, Item *pprune_cond) my_bitmap_map *old_sets[2]; prune_param.part_info= part_info; - init_sql_alloc(&alloc, thd->variables.range_alloc_block_size, 0); + init_sql_alloc(&alloc, thd->variables.range_alloc_block_size, 0, + MYF(MY_THREAD_SPECIFIC)); range_par->mem_root= &alloc; range_par->old_root= thd->mem_root; @@ -12859,7 +12866,8 @@ QUICK_GROUP_MIN_MAX_SELECT(TABLE *table, JOIN *join_arg, bool have_min_arg, DBUG_ASSERT(!parent_alloc); if (!parent_alloc) { - init_sql_alloc(&alloc, join->thd->variables.range_alloc_block_size, 0); + init_sql_alloc(&alloc, join->thd->variables.range_alloc_block_size, 0, + MYF(MY_THREAD_SPECIFIC)); join->thd->mem_root= &alloc; } else @@ -12914,7 +12922,8 @@ int QUICK_GROUP_MIN_MAX_SELECT::init() if (min_max_arg_part) { - if (my_init_dynamic_array(&min_max_ranges, sizeof(QUICK_RANGE*), 16, 16)) + if (my_init_dynamic_array(&min_max_ranges, sizeof(QUICK_RANGE*), 16, 16, + MYF(MY_THREAD_SPECIFIC))) return 1; if (have_min) diff --git a/sql/opt_subselect.cc b/sql/opt_subselect.cc index 1c2e037e8cc..75566b97d3b 100644 --- a/sql/opt_subselect.cc +++ b/sql/opt_subselect.cc @@ -3872,7 +3872,7 @@ SJ_TMP_TABLE::create_sj_weedout_tmp_table(THD *thd) using_unique_constraint= TRUE; /* STEP 3: Allocate memory for temptable description */ - init_sql_alloc(&own_root, TABLE_ALLOC_BLOCK_SIZE, 0); + init_sql_alloc(&own_root, TABLE_ALLOC_BLOCK_SIZE, 0, MYF(MY_THREAD_SPECIFIC)); if (!multi_alloc_root(&own_root, &table, sizeof(*table), &share, sizeof(*share), diff --git a/sql/protocol.cc b/sql/protocol.cc index 3af7dc88b88..f6e9e9e62e1 100644 --- a/sql/protocol.cc +++ b/sql/protocol.cc @@ -776,7 +776,7 @@ bool Protocol::send_result_set_metadata(List<Item> *list, uint flags) pos= (char*) local_packet->ptr()+local_packet->length(); *pos++= 12; // Length of packed fields /* inject a NULL to test the client */ - DBUG_EXECUTE_IF("poison_rs_fields", pos[-1]= 0xfb;); + DBUG_EXECUTE_IF("poison_rs_fields", pos[-1]= (char) 0xfb;); if (item->charset_for_protocol() == &my_charset_bin || thd_charset == NULL) { /* No conversion */ diff --git a/sql/records.cc b/sql/records.cc index d52481c36f5..c98532c1424 100644 --- a/sql/records.cc +++ b/sql/records.cc @@ -588,7 +588,7 @@ static int init_rr_cache(THD *thd, READ_RECORD *info) if (info->cache_records <= 2 || !(info->cache=(uchar*) my_malloc_lock(rec_cache_size+info->cache_records* info->struct_length+1, - MYF(0)))) + MYF(MY_THREAD_SPECIFIC)))) DBUG_RETURN(1); #ifdef HAVE_valgrind // Avoid warnings in qsort diff --git a/sql/rpl_filter.cc b/sql/rpl_filter.cc index 0380bc323a3..b44c3c7504c 100644 --- a/sql/rpl_filter.cc +++ b/sql/rpl_filter.cc @@ -573,7 +573,7 @@ void Rpl_filter::init_table_rule_array(DYNAMIC_ARRAY* a, bool* a_inited) { my_init_dynamic_array(a, sizeof(TABLE_RULE_ENT*), TABLE_RULE_ARR_SIZE, - TABLE_RULE_ARR_SIZE); + TABLE_RULE_ARR_SIZE, 0); *a_inited = 1; } diff --git a/sql/rpl_handler.cc b/sql/rpl_handler.cc index 9267190605c..07eeef57842 100644 --- a/sql/rpl_handler.cc +++ b/sql/rpl_handler.cc @@ -189,7 +189,7 @@ void delegates_destroy() DYNAMIC_ARRAY *plugins= &s.plugins; \ plugin_ref *plugins_buffer= s.plugins_buffer; \ my_init_dynamic_array2(plugins, sizeof(plugin_ref), \ - plugins_buffer, 8, 8); \ + plugins_buffer, 8, 8, 0); \ read_lock(); \ Observer_info_iterator iter= observer_info_iter(); \ Observer_info *info= iter++; \ diff --git a/sql/rpl_handler.h b/sql/rpl_handler.h index 4743fffb9a0..e955707f5c3 100644 --- a/sql/rpl_handler.h +++ b/sql/rpl_handler.h @@ -124,7 +124,7 @@ public: inited= FALSE; if (my_rwlock_init(&lock, NULL)) return; - init_sql_alloc(&memroot, 1024, 0); + init_sql_alloc(&memroot, 1024, 0, 0); inited= TRUE; } ~Delegate() diff --git a/sql/rpl_mi.cc b/sql/rpl_mi.cc index fc13fb2c762..73a2e26faba 100644 --- a/sql/rpl_mi.cc +++ b/sql/rpl_mi.cc @@ -61,7 +61,7 @@ Master_info::Master_info(LEX_STRING *connection_name_arg, my_casedn_str(system_charset_info, cmp_connection_name.str); } - my_init_dynamic_array(&ignore_server_ids, sizeof(::server_id), 16, 16); + my_init_dynamic_array(&ignore_server_ids, sizeof(::server_id), 16, 16, 0); bzero((char*) &file, sizeof(file)); mysql_mutex_init(key_master_info_run_lock, &run_lock, MY_MUTEX_INIT_FAST); mysql_mutex_init(key_master_info_data_lock, &data_lock, MY_MUTEX_INIT_FAST); diff --git a/sql/rpl_tblmap.cc b/sql/rpl_tblmap.cc index b7ac1b2d091..92d8ca228b0 100644 --- a/sql/rpl_tblmap.cc +++ b/sql/rpl_tblmap.cc @@ -46,7 +46,7 @@ table_mapping::table_mapping() offsetof(entry,table_id),sizeof(ulong), 0,0,0); /* We don't preallocate any block, this is consistent with m_free=0 above */ - init_alloc_root(&m_mem_root, TABLE_ID_HASH_SIZE*sizeof(entry), 0); + init_alloc_root(&m_mem_root, TABLE_ID_HASH_SIZE*sizeof(entry), 0, 0); DBUG_VOID_RETURN; } diff --git a/sql/rpl_utility.cc b/sql/rpl_utility.cc index 069fac1c3ec..321aead841e 100644 --- a/sql/rpl_utility.cc +++ b/sql/rpl_utility.cc @@ -1117,7 +1117,7 @@ bool event_checksum_test(uchar *event_buf, ulong event_len, uint8 alg) Deferred_log_events::Deferred_log_events(Relay_log_info *rli) : last_added(NULL) { - my_init_dynamic_array(&array, sizeof(Log_event *), 32, 16); + my_init_dynamic_array(&array, sizeof(Log_event *), 32, 16, 0); } Deferred_log_events::~Deferred_log_events() diff --git a/sql/slave.cc b/sql/slave.cc index 1db0261c73e..9e552e64a9e 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -1779,7 +1779,9 @@ past_checksum: } } } +#ifndef DBUG_OFF after_set_capability: +#endif err: if (errmsg) @@ -2426,10 +2428,22 @@ static int init_slave_thread(THD* thd, Master_info *mi, #if !defined(DBUG_OFF) int simulate_error= 0; #endif + DBUG_EXECUTE_IF("simulate_io_slave_error_on_init", + simulate_error|= (1 << SLAVE_THD_IO);); + DBUG_EXECUTE_IF("simulate_sql_slave_error_on_init", + simulate_error|= (1 << SLAVE_THD_SQL);); + /* We must call store_globals() before doing my_net_init() */ + if (init_thr_lock() || thd->store_globals() || + my_net_init(&thd->net, 0, MYF(MY_THREAD_SPECIFIC)) || + IF_DBUG(simulate_error & (1<< thd_type), 0)) + { + thd->cleanup(); + DBUG_RETURN(-1); + } + thd->system_thread = (thd_type == SLAVE_THD_SQL) ? SYSTEM_THREAD_SLAVE_SQL : SYSTEM_THREAD_SLAVE_IO; thd->security_ctx->skip_grants(); - my_net_init(&thd->net, 0); /* Adding MAX_LOG_EVENT_HEADER_LEN to the max_allowed_packet on all slave threads, since a replication event can become this much larger @@ -2446,17 +2460,6 @@ static int init_slave_thread(THD* thd, Master_info *mi, thd->thread_id= thd->variables.pseudo_thread_id= thread_id++; mysql_mutex_unlock(&LOCK_thread_count); - DBUG_EXECUTE_IF("simulate_io_slave_error_on_init", - simulate_error|= (1 << SLAVE_THD_IO);); - DBUG_EXECUTE_IF("simulate_sql_slave_error_on_init", - simulate_error|= (1 << SLAVE_THD_SQL);); - if (init_thr_lock() || thd->store_globals() || - IF_DBUG(simulate_error & (1<< thd_type), 0)) - { - thd->cleanup(); - DBUG_RETURN(-1); - } - if (thd_type == SLAVE_THD_SQL) thd_proc_info(thd, "Waiting for the next event in relay log"); else @@ -3494,8 +3497,6 @@ err_during_init: mi->rli.relay_log.description_event_for_queue= 0; // TODO: make rpl_status part of Master_info change_rpl_status(RPL_ACTIVE_SLAVE,RPL_IDLE_SLAVE); - DBUG_ASSERT(thd->net.buff != 0); - net_end(&thd->net); // destructor will not free it, because net.vio is 0 mysql_mutex_lock(&LOCK_thread_count); THD_CHECK_SENTRY(thd); delete thd; @@ -3901,8 +3902,6 @@ err_during_init: to avoid unneeded position re-init */ thd->temporary_tables = 0; // remove tempation from destructor to close them - DBUG_ASSERT(thd->net.buff != 0); - net_end(&thd->net); // destructor will not free it, because we are weird DBUG_ASSERT(rli->sql_thd == thd); THD_CHECK_SENTRY(thd); rli->sql_thd= 0; diff --git a/sql/sp_head.cc b/sql/sp_head.cc index a24da193c00..1d6aa73fdb0 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -510,7 +510,7 @@ sp_head::operator new(size_t size) throw() MEM_ROOT own_root; sp_head *sp; - init_sql_alloc(&own_root, MEM_ROOT_BLOCK_SIZE, MEM_ROOT_PREALLOC); + init_sql_alloc(&own_root, MEM_ROOT_BLOCK_SIZE, MEM_ROOT_PREALLOC, 0); sp= (sp_head *) alloc_root(&own_root, size); if (sp == NULL) DBUG_RETURN(NULL); @@ -594,7 +594,7 @@ sp_head::init(LEX *lex) types of stored procedures to simplify reset_lex()/restore_lex() code. */ lex->trg_table_fields.empty(); - my_init_dynamic_array(&m_instr, sizeof(sp_instr *), 16, 8); + my_init_dynamic_array(&m_instr, sizeof(sp_instr *), 16, 8, 0); m_param_begin= NULL; m_param_end= NULL; @@ -1224,7 +1224,7 @@ sp_head::execute(THD *thd, bool merge_da_on_success) Reprepare_observer *save_reprepare_observer= thd->m_reprepare_observer; Object_creation_ctx *saved_creation_ctx; Warning_info *saved_warning_info; - Warning_info warning_info(thd->warning_info->warn_id(), false); + Warning_info warning_info(thd->warning_info->warn_id(), false, true); /* Just reporting a stack overrun error @@ -1254,7 +1254,7 @@ sp_head::execute(THD *thd, bool merge_da_on_success) DBUG_RETURN(TRUE); /* init per-instruction memroot */ - init_sql_alloc(&execute_mem_root, MEM_ROOT_BLOCK_SIZE, 0); + init_sql_alloc(&execute_mem_root, MEM_ROOT_BLOCK_SIZE, 0, 0); DBUG_ASSERT(!(m_flags & IS_INVOKED)); m_flags|= IS_INVOKED; @@ -1711,7 +1711,7 @@ sp_head::execute_trigger(THD *thd, TODO: we should create sp_rcontext once per command and reuse it on subsequent executions of a trigger. */ - init_sql_alloc(&call_mem_root, MEM_ROOT_BLOCK_SIZE, 0); + init_sql_alloc(&call_mem_root, MEM_ROOT_BLOCK_SIZE, 0, 0); thd->set_n_backup_active_arena(&call_arena, &backup_arena); if (!(nctx= new sp_rcontext(m_pcont, 0, octx)) || @@ -1828,7 +1828,7 @@ sp_head::execute_function(THD *thd, Item **argp, uint argcount, TODO: we should create sp_rcontext once per command and reuse it on subsequent executions of a function/trigger. */ - init_sql_alloc(&call_mem_root, MEM_ROOT_BLOCK_SIZE, 0); + init_sql_alloc(&call_mem_root, MEM_ROOT_BLOCK_SIZE, 0, 0); thd->set_n_backup_active_arena(&call_arena, &backup_arena); if (!(nctx= new sp_rcontext(m_pcont, return_value_fld, octx)) || diff --git a/sql/sp_pcontext.cc b/sql/sp_pcontext.cc index 4c5087eaf27..cdafc5cd819 100644 --- a/sql/sp_pcontext.cc +++ b/sql/sp_pcontext.cc @@ -61,20 +61,20 @@ sp_pcontext::sp_pcontext() m_label_scope(LABEL_DEFAULT_SCOPE) { (void) my_init_dynamic_array(&m_vars, sizeof(sp_variable_t *), - PCONTEXT_ARRAY_INIT_ALLOC, - PCONTEXT_ARRAY_INCREMENT_ALLOC); + PCONTEXT_ARRAY_INIT_ALLOC, + PCONTEXT_ARRAY_INCREMENT_ALLOC, 0); (void) my_init_dynamic_array(&m_case_expr_id_lst, sizeof(int), - PCONTEXT_ARRAY_INIT_ALLOC, - PCONTEXT_ARRAY_INCREMENT_ALLOC); + PCONTEXT_ARRAY_INIT_ALLOC, + PCONTEXT_ARRAY_INCREMENT_ALLOC, 0); (void) my_init_dynamic_array(&m_conds, sizeof(sp_cond_type_t *), - PCONTEXT_ARRAY_INIT_ALLOC, - PCONTEXT_ARRAY_INCREMENT_ALLOC); + PCONTEXT_ARRAY_INIT_ALLOC, + PCONTEXT_ARRAY_INCREMENT_ALLOC, 0); (void) my_init_dynamic_array(&m_cursors, sizeof(LEX_STRING), - PCONTEXT_ARRAY_INIT_ALLOC, - PCONTEXT_ARRAY_INCREMENT_ALLOC); + PCONTEXT_ARRAY_INIT_ALLOC, + PCONTEXT_ARRAY_INCREMENT_ALLOC, 0); (void) my_init_dynamic_array(&m_handlers, sizeof(sp_cond_type_t *), - PCONTEXT_ARRAY_INIT_ALLOC, - PCONTEXT_ARRAY_INCREMENT_ALLOC); + PCONTEXT_ARRAY_INIT_ALLOC, + PCONTEXT_ARRAY_INCREMENT_ALLOC, 0); m_label.empty(); m_children.empty(); @@ -89,20 +89,20 @@ sp_pcontext::sp_pcontext(sp_pcontext *prev, label_scope_type label_scope) m_label_scope(label_scope) { (void) my_init_dynamic_array(&m_vars, sizeof(sp_variable_t *), - PCONTEXT_ARRAY_INIT_ALLOC, - PCONTEXT_ARRAY_INCREMENT_ALLOC); + PCONTEXT_ARRAY_INIT_ALLOC, + PCONTEXT_ARRAY_INCREMENT_ALLOC, 0); (void) my_init_dynamic_array(&m_case_expr_id_lst, sizeof(int), - PCONTEXT_ARRAY_INIT_ALLOC, - PCONTEXT_ARRAY_INCREMENT_ALLOC); + PCONTEXT_ARRAY_INIT_ALLOC, + PCONTEXT_ARRAY_INCREMENT_ALLOC, 0); (void) my_init_dynamic_array(&m_conds, sizeof(sp_cond_type_t *), - PCONTEXT_ARRAY_INIT_ALLOC, - PCONTEXT_ARRAY_INCREMENT_ALLOC); + PCONTEXT_ARRAY_INIT_ALLOC, + PCONTEXT_ARRAY_INCREMENT_ALLOC, 0); (void) my_init_dynamic_array(&m_cursors, sizeof(LEX_STRING), - PCONTEXT_ARRAY_INIT_ALLOC, - PCONTEXT_ARRAY_INCREMENT_ALLOC); + PCONTEXT_ARRAY_INIT_ALLOC, + PCONTEXT_ARRAY_INCREMENT_ALLOC, 0); (void) my_init_dynamic_array(&m_handlers, sizeof(sp_cond_type_t *), - PCONTEXT_ARRAY_INIT_ALLOC, - PCONTEXT_ARRAY_INCREMENT_ALLOC); + PCONTEXT_ARRAY_INIT_ALLOC, + PCONTEXT_ARRAY_INCREMENT_ALLOC, 0); m_label.empty(); m_children.empty(); diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 31627189296..9fa908c43e2 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -688,7 +688,7 @@ my_bool acl_init(bool dont_read_acl_tables) return_val= acl_reload(thd); delete thd; /* Remember that we don't have a THD */ - my_pthread_setspecific_ptr(THR_THD, 0); + set_current_thd(0); DBUG_RETURN(return_val); } @@ -749,13 +749,13 @@ static my_bool acl_load(THD *thd, TABLE_LIST *tables) acl_cache->clear(1); // Clear locked hostname cache - init_sql_alloc(&mem, ACL_ALLOC_BLOCK_SIZE, 0); + init_sql_alloc(&mem, ACL_ALLOC_BLOCK_SIZE, 0, 0); if (init_read_record(&read_record_info,thd,table= tables[0].table,NULL,1,0, FALSE)) goto end; table->use_all_columns(); - (void) my_init_dynamic_array(&acl_hosts,sizeof(ACL_HOST),20,50); + (void) my_init_dynamic_array(&acl_hosts,sizeof(ACL_HOST), 20, 50, 0); while (!(read_record_info.read_record(&read_record_info))) { ACL_HOST host; @@ -807,7 +807,7 @@ static my_bool acl_load(THD *thd, TABLE_LIST *tables) goto end; table->use_all_columns(); - (void) my_init_dynamic_array(&acl_users,sizeof(ACL_USER),50,100); + (void) my_init_dynamic_array(&acl_users,sizeof(ACL_USER), 50, 100, 0); password_length= table->field[2]->field_length / table->field[2]->charset()->mbmaxlen; if (password_length < SCRAMBLED_PASSWORD_CHAR_LENGTH_323) @@ -1009,7 +1009,7 @@ static my_bool acl_load(THD *thd, TABLE_LIST *tables) goto end; table->use_all_columns(); - (void) my_init_dynamic_array(&acl_dbs,sizeof(ACL_DB),50,100); + (void) my_init_dynamic_array(&acl_dbs,sizeof(ACL_DB), 50, 100, 0); while (!(read_record_info.read_record(&read_record_info))) { ACL_DB db; @@ -1067,7 +1067,7 @@ static my_bool acl_load(THD *thd, TABLE_LIST *tables) freeze_size(&acl_dbs); (void) my_init_dynamic_array(&acl_proxy_users, sizeof(ACL_PROXY_USER), - 50, 100); + 50, 100, 0); if (tables[3].table) { init_read_record(&read_record_info, thd, table= tables[3].table, NULL, 1, @@ -1722,7 +1722,7 @@ static void init_check_host(void) { DBUG_ENTER("init_check_host"); (void) my_init_dynamic_array(&acl_wild_hosts,sizeof(struct acl_host_and_ip), - acl_users.elements,1); + acl_users.elements, 1, 0); (void) my_hash_init(&acl_check_hosts,system_charset_info, acl_users.elements, 0, 0, (my_hash_get_key) check_get_key, 0, 0); @@ -4121,7 +4121,7 @@ my_bool grant_init() return_val= grant_reload(thd); delete thd; /* Remember that we don't have a THD */ - my_pthread_setspecific_ptr(THR_THD, 0); + set_current_thd(0); DBUG_RETURN(return_val); } @@ -4412,7 +4412,7 @@ my_bool grant_reload(THD *thd) opertion possible in case of failure. */ old_mem= memex; - init_sql_alloc(&memex, ACL_ALLOC_BLOCK_SIZE, 0); + init_sql_alloc(&memex, ACL_ALLOC_BLOCK_SIZE, 0, 0); if ((return_val= grant_load(thd, tables))) { // Error. Revert to old hash diff --git a/sql/sql_admin.cc b/sql/sql_admin.cc index e6bbef482a7..ba1ea01efcc 100644 --- a/sql/sql_admin.cc +++ b/sql/sql_admin.cc @@ -398,7 +398,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables, because it's already known that the table is badly damaged. */ - Warning_info wi(thd->query_id, false); + Warning_info wi(thd->query_id, false, true); Warning_info *wi_saved= thd->warning_info; thd->warning_info= &wi; diff --git a/sql/sql_analyse.h b/sql/sql_analyse.h index 34c8e2da3d4..8bac29de5a3 100644 --- a/sql/sql_analyse.h +++ b/sql/sql_analyse.h @@ -121,7 +121,8 @@ public: must_be_blob(0), was_zero_fill(0), was_maybe_zerofill(0), can_be_still_num(1) { init_tree(&tree, 0, 0, sizeof(String), (qsort_cmp2) sortcmp2, - 0, (tree_element_free) free_string, NULL); }; + (tree_element_free) free_string, NULL, + MYF(MY_THREAD_SPECIFIC)); }; void add(); void get_opt_type(String*, ha_rows); @@ -162,7 +163,7 @@ public: { bin_size= my_decimal_get_binary_size(a->max_length, a->decimals); init_tree(&tree, 0, 0, bin_size, (qsort_cmp2)compare_decimal2, - 0, 0, (void *)&bin_size); + 0, (void *)&bin_size, MYF(MY_THREAD_SPECIFIC)); }; void add(); @@ -190,7 +191,8 @@ public: field_real(Item* a, analyse* b) :field_info(a,b), min_arg(0), max_arg(0), sum(0), sum_sqr(0), max_notzero_dec_len(0) { init_tree(&tree, 0, 0, sizeof(double), - (qsort_cmp2) compare_double2, 0, NULL, NULL); } + (qsort_cmp2) compare_double2, NULL, NULL, + MYF(MY_THREAD_SPECIFIC)); } void add(); void get_opt_type(String*, ha_rows); @@ -244,7 +246,8 @@ public: field_longlong(Item* a, analyse* b) :field_info(a,b), min_arg(0), max_arg(0), sum(0), sum_sqr(0) { init_tree(&tree, 0, 0, sizeof(longlong), - (qsort_cmp2) compare_longlong2, 0, NULL, NULL); } + (qsort_cmp2) compare_longlong2, NULL, NULL, + MYF(MY_THREAD_SPECIFIC)); } void add(); void get_opt_type(String*, ha_rows); @@ -289,7 +292,8 @@ public: field_ulonglong(Item* a, analyse * b) :field_info(a,b), min_arg(0), max_arg(0), sum(0),sum_sqr(0) { init_tree(&tree, 0, 0, sizeof(ulonglong), - (qsort_cmp2) compare_ulonglong2, 0, NULL, NULL); } + (qsort_cmp2) compare_ulonglong2, NULL, NULL, + MYF(MY_THREAD_SPECIFIC)); } void add(); void get_opt_type(String*, ha_rows); String *get_min_arg(String *s) { s->set(min_arg,my_thd_charset); return s; } diff --git a/sql/sql_array.h b/sql/sql_array.h index 98a4a4815af..18881d2c345 100644 --- a/sql/sql_array.h +++ b/sql/sql_array.h @@ -100,7 +100,8 @@ template <class Elem> class Dynamic_array public: Dynamic_array(uint prealloc=16, uint increment=16) { - my_init_dynamic_array(&array, sizeof(Elem), prealloc, increment); + my_init_dynamic_array(&array, sizeof(Elem), prealloc, increment, + MY_THREAD_SPECIFIC); } Elem& at(int idx) diff --git a/sql/sql_audit.cc b/sql/sql_audit.cc index 131a71c1d6b..4403034bca8 100644 --- a/sql/sql_audit.cc +++ b/sql/sql_audit.cc @@ -156,7 +156,7 @@ static my_bool acquire_plugins(THD *thd, plugin_ref plugin, void *arg) { /* specify some reasonable initialization defaults */ my_init_dynamic_array(&thd->audit_class_plugins, - sizeof(plugin_ref), 16, 16); + sizeof(plugin_ref), 16, 16, 0); } /* lock the plugin and add it to the list */ diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 9f21b7f006b..fd0d0603395 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -4973,7 +4973,7 @@ bool open_tables(THD *thd, TABLE_LIST **start, uint *counter, uint flags, anything yet, to avoid penalty for statements which don't use views and thus new .FRM format. */ - init_sql_alloc(&new_frm_mem, 8024, 0); + init_sql_alloc(&new_frm_mem, 8024, 0, 0); thd->current_tablenr= 0; restart: @@ -9265,7 +9265,7 @@ my_bool mysql_rm_tmp_tables(void) my_dirend(dirp); } delete thd; - my_pthread_setspecific_ptr(THR_THD, 0); + set_current_thd(0); DBUG_RETURN(0); } diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc index 191cc4e01c8..ddc75254c9e 100644 --- a/sql/sql_cache.cc +++ b/sql/sql_cache.cc @@ -1035,8 +1035,8 @@ void query_cache_insert(const char *packet, ulong length, /* Current_thd can be NULL when a new connection is immediately ended due to "Too many connections". thd->store_globals() has not been - called at this time and hence my_pthread_setspecific_ptr(THR_THD, - this) has not been called for this thread. + called at this time and hence set_current_thd(this) has not been + called for this thread. */ if (!thd) diff --git a/sql/sql_class.cc b/sql/sql_class.cc index d6a0eaf9b52..1d0d23a2390 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -807,17 +807,28 @@ THD::THD() #if defined(ENABLED_DEBUG_SYNC) debug_sync_control(0), #endif /* defined(ENABLED_DEBUG_SYNC) */ - main_warning_info(0, false) + main_warning_info(0, false, false) { ulong tmp; mdl_context.init(this); /* + We set THR_THD to temporally point to this THD to register all the + variables that allocates memory for this THD + */ + THD *old_THR_THD= current_thd; + set_current_thd(this); + status_var.memory_used= 0; + + main_warning_info.init(); + /* Pass nominal parameters to init_alloc_root only to ensure that the destructor works OK in case of an error. The main_mem_root will be re-initialized in init_for_queries(). */ - init_sql_alloc(&main_mem_root, ALLOC_ROOT_MIN_BLOCK_SIZE, 0); + init_sql_alloc(&main_mem_root, ALLOC_ROOT_MIN_BLOCK_SIZE, 0, + MYF(MY_THREAD_SPECIFIC)); + stmt_arena= this; thread_stack= 0; scheduler= thread_scheduler; // Will be fixed later @@ -874,6 +885,7 @@ THD::THD() mysql_audit_init_thd(this); #endif net.vio=0; + net.buff= 0; client_capabilities= 0; // minimalistic client ull=0; system_thread= NON_SYSTEM_THREAD; @@ -915,7 +927,7 @@ THD::THD() user_connect=(USER_CONN *)0; my_hash_init(&user_vars, system_charset_info, USER_VARS_HASH_SIZE, 0, 0, (my_hash_get_key) get_var_key, - (my_hash_free_key) free_user_var, 0); + (my_hash_free_key) free_user_var, HASH_THREAD_SPECIFIC); sp_proc_cache= NULL; sp_func_cache= NULL; @@ -923,7 +935,7 @@ THD::THD() /* For user vars replication*/ if (opt_bin_log) my_init_dynamic_array(&user_var_events, - sizeof(BINLOG_USER_VAR_EVENT *), 16, 16); + sizeof(BINLOG_USER_VAR_EVENT *), 16, 16, 0); else bzero((char*) &user_var_events, sizeof(user_var_events)); @@ -946,6 +958,8 @@ THD::THD() prepare_derived_at_open= FALSE; create_tmp_table_for_derived= FALSE; save_prep_leaf_list= FALSE; + /* Restore THR_THD */ + set_current_thd(old_THR_THD); } @@ -1214,6 +1228,7 @@ extern "C" THD *_current_thd_noinline(void) void THD::init(void) { + DBUG_ENTER("thd::init"); mysql_mutex_lock(&LOCK_global_system_variables); plugin_thdvar_init(this); /* @@ -1243,7 +1258,7 @@ void THD::init(void) tx_isolation= (enum_tx_isolation) variables.tx_isolation; update_charset(); reset_current_stmt_binlog_format_row(); - bzero((char *) &status_var, sizeof(status_var)); + set_status_var_init(); bzero((char *) &org_status_var, sizeof(org_status_var)); if (variables.sql_log_bin) @@ -1260,6 +1275,7 @@ void THD::init(void) debug_sync_init_thread(this); #endif /* defined(ENABLED_DEBUG_SYNC) */ apc_target.init(&LOCK_thd_data); + DBUG_VOID_RETURN; } @@ -1433,8 +1449,16 @@ void THD::cleanup(void) THD::~THD() { + THD *orig_thd= current_thd; THD_CHECK_SENTRY(this); DBUG_ENTER("~THD()"); + + /* + In error cases, thd may not be current thd. We have to fix this so + that memory allocation counting is done correctly + */ + set_current_thd(this); + /* Ensure that no one is using THD */ mysql_mutex_lock(&LOCK_thd_data); mysys_var=0; // Safety (shouldn't be needed) @@ -1443,10 +1467,8 @@ THD::~THD() /* Close connection */ #ifndef EMBEDDED_LIBRARY if (net.vio) - { vio_delete(net.vio); - net_end(&net); - } + net_end(&net); #endif stmt_map.reset(); /* close all prepared statements */ if (!cleanup_done) @@ -1481,6 +1503,15 @@ THD::~THD() #endif free_root(&main_mem_root, MYF(0)); + main_warning_info.free_memory(); + if (status_var.memory_used != 0) + { + DBUG_PRINT("error", ("memory_used: %lld", status_var.memory_used)); + SAFEMALLOC_REPORT_MEMORY(my_thread_dbug_id()); + DBUG_ASSERT(status_var.memory_used == 0); // Ensure everything is freed + } + + set_current_thd(orig_thd); DBUG_VOID_RETURN; } @@ -1752,7 +1783,7 @@ bool THD::store_globals() */ DBUG_ASSERT(thread_stack); - if (my_pthread_setspecific_ptr(THR_THD, this) || + if (set_current_thd(this) || my_pthread_setspecific_ptr(THR_MALLOC, &mem_root)) return 1; /* @@ -1796,7 +1827,7 @@ void THD::reset_globals() mysql_mutex_unlock(&LOCK_thd_data); /* Undocking the thread specific data. */ - my_pthread_setspecific_ptr(THR_THD, NULL); + set_current_thd(0); my_pthread_setspecific_ptr(THR_MALLOC, NULL); } @@ -3652,7 +3683,8 @@ void thd_increment_net_big_packet_count(ulong length) void THD::set_status_var_init() { - bzero((char*) &status_var, sizeof(status_var)); + bzero((char*) &status_var, offsetof(STATUS_VAR, + last_cleared_system_status_var)); } diff --git a/sql/sql_class.h b/sql/sql_class.h index 9ac70d4bcee..f10b517a606 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -683,6 +683,8 @@ typedef struct system_status_var ulonglong binlog_bytes_written; double last_query_cost; double cpu_time, busy_time; + /* Don't initialize */ + volatile int64 memory_used; /* This shouldn't be accumulated */ } STATUS_VAR; /* @@ -692,6 +694,7 @@ typedef struct system_status_var */ #define last_system_status_var questions +#define last_cleared_system_status_var memory_used void mark_transaction_to_rollback(THD *thd, bool all); @@ -1425,7 +1428,8 @@ public: m_reopen_array(NULL), m_locked_tables_count(0) { - init_sql_alloc(&m_locked_tables_root, MEM_ROOT_BLOCK_SIZE, 0); + init_sql_alloc(&m_locked_tables_root, MEM_ROOT_BLOCK_SIZE, 0, + MY_THREAD_SPECIFIC); } void unlock_locked_tables(THD *thd); ~Locked_tables_list() @@ -1881,7 +1885,8 @@ public: { bzero((char*)this, sizeof(*this)); xid_state.xid.null(); - init_sql_alloc(&mem_root, ALLOC_ROOT_MIN_BLOCK_SIZE, 0); + init_sql_alloc(&mem_root, ALLOC_ROOT_MIN_BLOCK_SIZE, 0, + MY_THREAD_SPECIFIC); } } transaction; Global_read_lock global_read_lock; diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index 4e2b5621aca..4bcb62ef764 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -264,7 +264,8 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, { DBUG_ASSERT(usable_index == MAX_KEY); table->sort.io_cache= (IO_CACHE *) my_malloc(sizeof(IO_CACHE), - MYF(MY_FAE | MY_ZEROFILL)); + MYF(MY_FAE | MY_ZEROFILL | + MY_THREAD_SPECIFIC)); if (!(sortorder= make_unireg_sortorder(order, &length, NULL)) || (table->sort.found_records= filesort(thd, table, sortorder, length, diff --git a/sql/sql_error.cc b/sql/sql_error.cc index 06da6250e71..23a60267737 100644 --- a/sql/sql_error.cc +++ b/sql/sql_error.cc @@ -457,23 +457,38 @@ Diagnostics_area::disable_status() m_status= DA_DISABLED; } -Warning_info::Warning_info(ulonglong warn_id_arg, bool allow_unlimited_warnings) +Warning_info::Warning_info(ulonglong warn_id_arg, + bool allow_unlimited_warnings, bool initialize) :m_statement_warn_count(0), m_current_row_for_warning(1), m_warn_id(warn_id_arg), m_allow_unlimited_warnings(allow_unlimited_warnings), + initialized(0), m_read_only(FALSE) { - /* Initialize sub structures */ - init_sql_alloc(&m_warn_root, WARN_ALLOC_BLOCK_SIZE, WARN_ALLOC_PREALLOC_SIZE); m_warn_list.empty(); bzero((char*) m_warn_count, sizeof(m_warn_count)); + if (initialize) + init(); } +void Warning_info::init() +{ + /* Initialize sub structures */ + init_sql_alloc(&m_warn_root, WARN_ALLOC_BLOCK_SIZE, + WARN_ALLOC_PREALLOC_SIZE, MYF(MY_THREAD_SPECIFIC)); + initialized= 1; +} + +void Warning_info::free_memory() +{ + if (initialized) + free_root(&m_warn_root,MYF(0)); +} Warning_info::~Warning_info() { - free_root(&m_warn_root,MYF(0)); + free_memory(); } @@ -484,7 +499,7 @@ Warning_info::~Warning_info() void Warning_info::clear_warning_info(ulonglong warn_id_arg) { m_warn_id= warn_id_arg; - free_root(&m_warn_root, MYF(0)); + free_memory(); bzero((char*) m_warn_count, sizeof(m_warn_count)); m_warn_list.empty(); m_statement_warn_count= 0; diff --git a/sql/sql_error.h b/sql/sql_error.h index 00ade934226..17ec3aa7b56 100644 --- a/sql/sql_error.h +++ b/sql/sql_error.h @@ -355,15 +355,21 @@ class Warning_info /** Indicates if push_warning() allows unlimited number of warnings. */ bool m_allow_unlimited_warnings; + bool initialized; /* Set to 1 if init() has been called */ private: Warning_info(const Warning_info &rhs); /* Not implemented */ Warning_info& operator=(const Warning_info &rhs); /* Not implemented */ public: - Warning_info(ulonglong warn_id_arg, bool allow_unlimited_warnings); + Warning_info(ulonglong warn_id_arg, bool allow_unlimited_warnings, + bool initialize); ~Warning_info(); + /* Allocate memory for structures */ + void init(); + void free_memory(); + /** Reset the warning information. Clear all warnings, the number of warnings, reset current row counter diff --git a/sql/sql_handler.cc b/sql/sql_handler.cc index d03b38171fc..c4055a9221f 100644 --- a/sql/sql_handler.cc +++ b/sql/sql_handler.cc @@ -323,7 +323,7 @@ bool mysql_ha_open(THD *thd, TABLE_LIST *tables, SQL_HANDLER *reopen) /* copy data to sql_handler */ if (!(sql_handler= new SQL_HANDLER(thd))) goto err; - init_alloc_root(&sql_handler->mem_root, 1024, 0); + init_alloc_root(&sql_handler->mem_root, 1024, 0, MYF(MY_THREAD_SPECIFIC)); sql_handler->db.length= strlen(tables->db); sql_handler->table_name.length= strlen(tables->table_name); diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 61a7a56c413..c0eabd3a2f2 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -2481,7 +2481,9 @@ int write_delayed(THD *thd, TABLE *table, enum_duplicates duplic, goto err; } - if (!(row->record= (char*) my_malloc(table->s->reclength, MYF(MY_WME)))) + /* This can't be THREAD_SPECIFIC as it's freed in delayed thread */ + if (!(row->record= (char*) my_malloc(table->s->reclength, + MYF(MY_WME)))) goto err; memcpy(row->record, table->record[0], table->s->reclength); row->start_time= thd->start_time; @@ -2898,24 +2900,28 @@ pthread_handler_t handle_delayed_insert(void *arg) DBUG_LEAVE; } - di->table=0; - thd->killed= KILL_CONNECTION; // If error - mysql_mutex_unlock(&di->mutex); + { + DBUG_ENTER("handle_delayed_insert-cleanup"); + di->table=0; + thd->killed= KILL_CONNECTION; // If error + mysql_mutex_unlock(&di->mutex); - close_thread_tables(thd); // Free the table - thd->mdl_context.release_transactional_locks(); - mysql_cond_broadcast(&di->cond_client); // Safety + close_thread_tables(thd); // Free the table + thd->mdl_context.release_transactional_locks(); + mysql_cond_broadcast(&di->cond_client); // Safety - mysql_mutex_lock(&LOCK_delayed_create); // Because of delayed_get_table - mysql_mutex_lock(&LOCK_delayed_insert); - /* - di should be unlinked from the thread handler list and have no active - clients - */ - delete di; - mysql_mutex_unlock(&LOCK_delayed_insert); - mysql_mutex_unlock(&LOCK_delayed_create); + mysql_mutex_lock(&LOCK_delayed_create); // Because of delayed_get_table + mysql_mutex_lock(&LOCK_delayed_insert); + /* + di should be unlinked from the thread handler list and have no active + clients + */ + delete di; + mysql_mutex_unlock(&LOCK_delayed_insert); + mysql_mutex_unlock(&LOCK_delayed_create); + DBUG_LEAVE; + } my_thread_end(); pthread_exit(0); diff --git a/sql/sql_join_cache.cc b/sql/sql_join_cache.cc index 4626f30df28..fde9f70fa79 100644 --- a/sql/sql_join_cache.cc +++ b/sql/sql_join_cache.cc @@ -934,7 +934,7 @@ int JOIN_CACHE::alloc_buffer() { ulong next_buff_size; - if ((buff= (uchar*) my_malloc(buff_size, MYF(0)))) + if ((buff= (uchar*) my_malloc(buff_size, MYF(MY_THREAD_SPECIFIC)))) break; next_buff_size= buff_size > buff_size_decr ? buff_size-buff_size_decr : 0; @@ -1012,7 +1012,7 @@ int JOIN_CACHE::realloc_buffer() { int rc; free(); - rc= test(!(buff= (uchar*) my_malloc(buff_size, MYF(0)))); + rc= test(!(buff= (uchar*) my_malloc(buff_size, MYF(MY_THREAD_SPECIFIC)))); reset(TRUE); return rc; } @@ -2801,7 +2801,7 @@ int JOIN_CACHE_HASHED::realloc_buffer() { int rc; free(); - rc= test(!(buff= (uchar*) my_malloc(buff_size, MYF(0)))); + rc= test(!(buff= (uchar*) my_malloc(buff_size, MYF(MY_THREAD_SPECIFIC)))); init_hash_table(); reset(TRUE); return rc; diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index fb4d4defe9c..93e3eb51518 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -2552,7 +2552,7 @@ LEX::LEX() my_init_dynamic_array2(&plugins, sizeof(plugin_ref), plugins_static_buffer, INITIAL_LEX_PLUGIN_LIST_SIZE, - INITIAL_LEX_PLUGIN_LIST_SIZE); + INITIAL_LEX_PLUGIN_LIST_SIZE, 0); reset_query_tables_list(TRUE); mi.init(); } diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 492909ee3d5..e1c0940c461 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -305,7 +305,7 @@ struct LEX_MASTER_INFO { bzero(this, sizeof(*this)); my_init_dynamic_array(&repl_ignore_server_ids, - sizeof(::server_id), 0, 16); + sizeof(::server_id), 0, 16, 0); } void reset() { diff --git a/sql/sql_load.cc b/sql/sql_load.cc index 4fdabef37ed..7d030329419 100644 --- a/sql/sql_load.cc +++ b/sql/sql_load.cc @@ -1371,7 +1371,7 @@ READ_INFO::READ_INFO(File file_par, uint tot_length, CHARSET_INFO *cs, set_if_bigger(length,line_start.length()); stack=stack_pos=(int*) sql_alloc(sizeof(int)*length); - if (!(buffer=(uchar*) my_malloc(buff_length+1,MYF(0)))) + if (!(buffer=(uchar*) my_malloc(buff_length+1,MYF(MY_THREAD_SPECIFIC)))) error=1; /* purecov: inspected */ else { @@ -1379,7 +1379,7 @@ READ_INFO::READ_INFO(File file_par, uint tot_length, CHARSET_INFO *cs, if (init_io_cache(&cache,(get_it_from_net) ? -1 : file, 0, (get_it_from_net) ? READ_NET : (is_fifo ? READ_FIFO : READ_CACHE),0L,1, - MYF(MY_WME))) + MYF(MY_WME | MY_THREAD_SPECIFIC))) { my_free(buffer); /* purecov: inspected */ buffer= NULL; @@ -1605,7 +1605,7 @@ int READ_INFO::read_field() ** We come here if buffer is too small. Enlarge it and continue */ if (!(new_buffer=(uchar*) my_realloc((char*) buffer,buff_length+1+IO_SIZE, - MYF(MY_WME)))) + MYF(MY_WME | MY_THREAD_SPECIFIC)))) return (error=1); to=new_buffer + (to-buffer); buffer=new_buffer; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 472273a0a33..2d3d91ff9d8 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -642,8 +642,6 @@ void do_handle_bootstrap(THD *thd) handle_bootstrap_impl(thd); end: - net_end(&thd->net); - thd->cleanup(); delete thd; #ifndef EMBEDDED_LIBRARY @@ -1291,10 +1289,10 @@ bool dispatch_command(enum enum_server_command command, THD *thd, and flushes tables. */ bool res; - my_pthread_setspecific_ptr(THR_THD, NULL); + set_current_thd(0); res= reload_acl_and_cache(NULL, options | REFRESH_FAST, NULL, ¬_used); - my_pthread_setspecific_ptr(THR_THD, thd); + set_current_thd(thd); if (res) break; } @@ -1465,6 +1463,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, thd_proc_info(thd, "cleaning up"); thd->reset_query(); + thd->examined_row_count= 0; // For processlist thd->command=COM_SLEEP; dec_thread_running(); thd_proc_info(thd, 0); @@ -4794,7 +4793,8 @@ static bool execute_show_status(THD *thd, TABLE_LIST *all_tables) mysql_mutex_lock(&LOCK_status); add_diff_to_status(&global_status_var, &thd->status_var, &old_status_var); - thd->status_var= old_status_var; + memcpy(&thd->status_var, &old_status_var, + offsetof(STATUS_VAR, last_cleared_system_status_var)); mysql_mutex_unlock(&LOCK_status); return res; } @@ -6843,7 +6843,7 @@ static uint kill_threads_for_user(THD *thd, LEX_USER *user, mysql_mutex_unlock(&LOCK_thread_count); DBUG_RETURN(ER_KILL_DENIED_ERROR); } - if (!threads_to_kill.push_back(tmp, tmp->mem_root)) + if (!threads_to_kill.push_back(tmp, thd->mem_root)) mysql_mutex_lock(&tmp->LOCK_thd_data); // Lock from delete } } diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc index 45e8adf1f5f..e24b43c0cf6 100644 --- a/sql/sql_plugin.cc +++ b/sql/sql_plugin.cc @@ -1114,7 +1114,7 @@ static bool plugin_add(MEM_ROOT *tmp_root, plugin_array_version++; if (my_hash_insert(&plugin_hash[plugin->type], (uchar*)tmp_plugin_ptr)) tmp_plugin_ptr->state= PLUGIN_IS_FREED; - init_alloc_root(&tmp_plugin_ptr->mem_root, 4096, 4096); + init_alloc_root(&tmp_plugin_ptr->mem_root, 4096, 4096, 0); if (name->str) DBUG_RETURN(FALSE); // all done @@ -1507,8 +1507,8 @@ int plugin_init(int *argc, char **argv, int flags) init_plugin_psi_keys(); #endif - init_alloc_root(&plugin_mem_root, 4096, 4096); - init_alloc_root(&tmp_root, 4096, 4096); + init_alloc_root(&plugin_mem_root, 4096, 4096, 0); + init_alloc_root(&tmp_root, 4096, 4096, 0); if (my_hash_init(&bookmark_hash, &my_charset_bin, 16, 0, 0, get_bookmark_hash_key, NULL, HASH_UNIQUE)) @@ -1518,9 +1518,9 @@ int plugin_init(int *argc, char **argv, int flags) mysql_mutex_init(key_LOCK_plugin, &LOCK_plugin, MY_MUTEX_INIT_FAST); if (my_init_dynamic_array(&plugin_dl_array, - sizeof(struct st_plugin_dl *),16,16) || + sizeof(struct st_plugin_dl *),16,16,0) || my_init_dynamic_array(&plugin_array, - sizeof(struct st_plugin_int *),16,16)) + sizeof(struct st_plugin_int *),16,16,0)) goto err; for (i= 0; i < MYSQL_MAX_PLUGIN_TYPE_NUM; i++) @@ -1716,12 +1716,11 @@ static bool register_builtin(struct st_maria_plugin *plugin, */ static void plugin_load(MEM_ROOT *tmp_root, int *argc, char **argv) { - THD thd; TABLE_LIST tables; TABLE *table; READ_RECORD read_record_info; int error; - THD *new_thd= &thd; + THD *new_thd= new THD; bool result; #ifdef EMBEDDED_LIBRARY No_such_table_error_handler error_handler; @@ -1732,7 +1731,7 @@ static void plugin_load(MEM_ROOT *tmp_root, int *argc, char **argv) new_thd->store_globals(); new_thd->db= my_strdup("mysql", MYF(0)); new_thd->db_length= 5; - bzero((char*) &thd.net, sizeof(thd.net)); + bzero((char*) &new_thd->net, sizeof(new_thd->net)); tables.init_one_table("mysql", 5, "plugin", 6, "plugin", TL_READ); #ifdef EMBEDDED_LIBRARY @@ -1799,7 +1798,8 @@ static void plugin_load(MEM_ROOT *tmp_root, int *argc, char **argv) close_mysql_tables(new_thd); end: /* Remember that we don't have a THD */ - my_pthread_setspecific_ptr(THR_THD, 0); + delete new_thd; + set_current_thd(0); DBUG_VOID_RETURN; } diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 96b7d825bd3..e2398536783 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -2963,7 +2963,7 @@ void mysql_stmt_get_longdata(THD *thd, char *packet, ulong packet_length) param= stmt->param_array[param_number]; Diagnostics_area new_stmt_da, *save_stmt_da= thd->stmt_da; - Warning_info new_warnning_info(thd->query_id, false); + Warning_info new_warnning_info(thd->query_id, false, true); Warning_info *save_warinig_info= thd->warning_info; thd->stmt_da= &new_stmt_da; @@ -3141,7 +3141,7 @@ Prepared_statement::Prepared_statement(THD *thd_arg) flags((uint) IS_IN_USE) { init_sql_alloc(&main_mem_root, thd_arg->variables.query_alloc_block_size, - thd_arg->variables.query_prealloc_size); + thd_arg->variables.query_prealloc_size, MYF(MY_THREAD_SPECIFIC)); *last_error= '\0'; } @@ -4031,7 +4031,7 @@ Ed_result_set::Ed_result_set(List<Ed_row> *rows_arg, */ Ed_connection::Ed_connection(THD *thd) - :m_warning_info(thd->query_id, false), + :m_warning_info(thd->query_id, false, true), m_thd(thd), m_rsets(0), m_current_rset(0) @@ -4455,7 +4455,7 @@ bool Protocol_local::send_result_set_metadata(List<Item> *columns, uint) { DBUG_ASSERT(m_rset == 0 && !alloc_root_inited(&m_rset_root)); - init_sql_alloc(&m_rset_root, MEM_ROOT_BLOCK_SIZE, 0); + init_sql_alloc(&m_rset_root, MEM_ROOT_BLOCK_SIZE, 0, MYF(MY_THREAD_SPECIFIC)); if (! (m_rset= new (&m_rset_root) List<Ed_row>)) return TRUE; diff --git a/sql/sql_reload.cc b/sql/sql_reload.cc index 99fe9267589..2720dc7cd74 100644 --- a/sql/sql_reload.cc +++ b/sql/sql_reload.cc @@ -97,7 +97,7 @@ bool reload_acl_and_cache(THD *thd, unsigned long options, { delete tmp_thd; /* Remember that we don't have a THD */ - my_pthread_setspecific_ptr(THR_THD, 0); + set_current_thd(0); thd= 0; } reset_mqh((LEX_USER *)NULL, TRUE); diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 4ef4311a68a..63718dc9d55 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -4947,7 +4947,8 @@ update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,JOIN_TAB *join_tab, /* set a barrier for the array of SARGABLE_PARAM */ (*sargables)[0].field= 0; - if (my_init_dynamic_array(keyuse,sizeof(KEYUSE),20,64)) + if (my_init_dynamic_array(keyuse,sizeof(KEYUSE),20,64, + MYF(MY_THREAD_SPECIFIC))) return TRUE; if (cond) @@ -14362,7 +14363,7 @@ create_tmp_table(THD *thd, TMP_TABLE_PARAM *param, List<Item> &fields, if (param->precomputed_group_by) copy_func_count+= param->sum_func_count; - init_sql_alloc(&own_root, TABLE_ALLOC_BLOCK_SIZE, 0); + init_sql_alloc(&own_root, TABLE_ALLOC_BLOCK_SIZE, 0, MYF(MY_THREAD_SPECIFIC)); if (!multi_alloc_root(&own_root, &table, sizeof(*table), @@ -19171,7 +19172,8 @@ create_sort_index(THD *thd, JOIN *join, ORDER *order, goto err; /* purecov: inspected */ table->sort.io_cache=(IO_CACHE*) my_malloc(sizeof(IO_CACHE), - MYF(MY_WME | MY_ZEROFILL)); + MYF(MY_WME | MY_ZEROFILL| + MY_THREAD_SPECIFIC)); table->status=0; // May be wrong if quick_select // If table has a range, move it to select @@ -22418,6 +22420,7 @@ static void print_join(THD *thd, List_iterator_fast<TABLE_LIST> ti(*tables); TABLE_LIST **table; uint non_const_tables= 0; + DBUG_ENTER("print_join"); for (TABLE_LIST *t= ti++; t ; t= ti++) { @@ -22431,13 +22434,13 @@ static void print_join(THD *thd, if (!non_const_tables) { str->append(STRING_WITH_LEN("dual")); - return; // all tables were optimized away + DBUG_VOID_RETURN; // all tables were optimized away } ti.rewind(); if (!(table= (TABLE_LIST **)thd->alloc(sizeof(TABLE_LIST*) * non_const_tables))) - return; // out of memory + DBUG_VOID_RETURN; // out of memory TABLE_LIST *tmp, **t= table + (non_const_tables - 1); while ((tmp= ti++)) @@ -22476,6 +22479,7 @@ static void print_join(THD *thd, } print_table_array(thd, eliminated_tables, str, table, table + non_const_tables, query_type); + DBUG_VOID_RETURN; } /** @@ -22984,7 +22988,8 @@ JOIN::reoptimize(Item *added_where, table_map join_tables, reset_query_plan(); if (!keyuse.buffer && - my_init_dynamic_array(&keyuse, sizeof(KEYUSE), 20, 64)) + my_init_dynamic_array(&keyuse, sizeof(KEYUSE), 20, 64, + MYF(MY_THREAD_SPECIFIC))) { delete_dynamic(&added_keyuse); return REOPT_ERROR; diff --git a/sql/sql_servers.cc b/sql/sql_servers.cc index dce679a883f..63f3e6c9d63 100644 --- a/sql/sql_servers.cc +++ b/sql/sql_servers.cc @@ -158,7 +158,7 @@ bool servers_init(bool dont_read_servers_table) } /* Initialize the mem root for data */ - init_sql_alloc(&mem, ACL_ALLOC_BLOCK_SIZE, 0); + init_sql_alloc(&mem, ACL_ALLOC_BLOCK_SIZE, 0, MYF(MY_THREAD_SPECIFIC)); if (dont_read_servers_table) goto end; @@ -178,7 +178,7 @@ bool servers_init(bool dont_read_servers_table) return_val= servers_reload(thd); delete thd; /* Remember that we don't have a THD */ - my_pthread_setspecific_ptr(THR_THD, 0); + set_current_thd(0); end: DBUG_RETURN(return_val); @@ -209,7 +209,7 @@ static bool servers_load(THD *thd, TABLE_LIST *tables) my_hash_reset(&servers_cache); free_root(&mem, MYF(0)); - init_sql_alloc(&mem, ACL_ALLOC_BLOCK_SIZE, 0); + init_sql_alloc(&mem, ACL_ALLOC_BLOCK_SIZE, 0, 0); if (init_read_record(&read_record_info,thd,table=tables[0].table,NULL,1,0, FALSE)) diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 5d57edc53ae..f9458fa8588 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -458,7 +458,7 @@ bool ignore_db_dirs_init() { return my_init_dynamic_array(&ignore_db_dirs_array, sizeof(LEX_STRING *), - 0, 0); + 0, 0, 0); } @@ -737,7 +737,8 @@ find_files(THD *thd, List<LEX_STRING> *files, const char *db, bzero((char*) &table_list,sizeof(table_list)); - if (!(dirp = my_dir(path,MYF(dir ? MY_WANT_STAT : 0)))) + if (!(dirp = my_dir(path,MYF((dir ? MY_WANT_STAT : 0) | + MY_THREAD_SPECIFIC)))) { if (my_errno == ENOENT) my_error(ER_BAD_DB_ERROR, MYF(ME_BELL+ME_WAITTANG), db); @@ -2334,11 +2335,14 @@ void Show_explain_request::call_in_target_thread() target_thd->query_length(), target_thd->query_charset()); + DBUG_ASSERT(current_thd == target_thd); + set_current_thd(request_thd); if (target_thd->lex->unit.print_explain(explain_buf, 0 /* explain flags*/, &printed_anything)) { failed_to_produce= TRUE; } + set_current_thd(target_thd); if (!printed_anything) failed_to_produce= TRUE; @@ -2349,10 +2353,20 @@ void Show_explain_request::call_in_target_thread() int select_result_explain_buffer::send_data(List<Item> &items) { + int res; + THD *cur_thd= current_thd; + DBUG_ENTER("select_result_explain_buffer::send_data"); + + /* + Switch to the recieveing thread, so that we correctly count memory used + by it. This is needed as it's the receiving thread that will free the + memory. + */ + set_current_thd(thd); fill_record(thd, dst_table, dst_table->field, items, TRUE, FALSE); - if ((dst_table->file->ha_write_tmp_row(dst_table->record[0]))) - return 1; - return 0; + res= dst_table->file->ha_write_tmp_row(dst_table->record[0]); + set_current_thd(cur_thd); + DBUG_RETURN(test(res)); } @@ -2578,6 +2592,18 @@ int fill_schema_processlist(THD* thd, TABLE_LIST* tables, COND* cond) } mysql_mutex_unlock(&tmp->LOCK_thd_data); + /* + This may become negative if we free a memory allocated by another + thread in this thread. However it's better that we notice it eventually + than hide it. + */ + table->field[12]->store((longlong) (tmp->status_var.memory_used + + sizeof(THD)), + FALSE); + table->field[12]->set_notnull(); + table->field[13]->store((longlong) tmp->examined_row_count, TRUE); + table->field[13]->set_notnull(); + if (schema_table_store_record(thd, table)) { mysql_mutex_unlock(&LOCK_thread_count); @@ -2650,7 +2676,7 @@ int add_status_vars(SHOW_VAR *list) if (status_vars_inited) mysql_mutex_lock(&LOCK_status); if (!all_status_vars.buffer && // array is not allocated yet - do it now - my_init_dynamic_array(&all_status_vars, sizeof(SHOW_VAR), 200, 20)) + my_init_dynamic_array(&all_status_vars, sizeof(SHOW_VAR), 200, 20, 0)) { res= 1; goto err; @@ -2999,7 +3025,8 @@ static int aggregate_user_stats(HASH *all_user_stats, HASH *agg_user_stats) { // First entry for this role. if (!(agg_user= (USER_STATS*) my_malloc(sizeof(USER_STATS), - MYF(MY_WME | MY_ZEROFILL)))) + MYF(MY_WME | MY_ZEROFILL| + MY_THREAD_SPECIFIC)))) { sql_print_error("Malloc in aggregate_user_stats failed"); DBUG_RETURN(1); @@ -4372,7 +4399,7 @@ static int fill_schema_table_from_frm(THD *thd, TABLE_LIST *tables, if (schema_table->i_s_requested_object & OPEN_TRIGGER_ONLY) { - init_sql_alloc(&tbl.mem_root, TABLE_ALLOC_BLOCK_SIZE, 0); + init_sql_alloc(&tbl.mem_root, TABLE_ALLOC_BLOCK_SIZE, 0, 0); if (!Table_triggers_list::check_n_load(thd, db_name->str, table_name->str, &tbl, 1)) { @@ -7878,7 +7905,7 @@ static bool do_fill_table(THD *thd, // Warning_info, so "useful warnings" get rejected. In order to avoid // that problem we create a Warning_info instance, which is capable of // storing "unlimited" number of warnings. - Warning_info wi(thd->query_id, true); + Warning_info wi(thd->query_id, true, true); Warning_info *wi_saved= thd->warning_info; thd->warning_info= &wi; @@ -8612,6 +8639,8 @@ ST_FIELD_INFO processlist_fields_info[]= {"MAX_STAGE", 2, MYSQL_TYPE_TINY, 0, 0, "Max_stage", SKIP_OPEN_TABLE}, {"PROGRESS", 703, MYSQL_TYPE_DECIMAL, 0, 0, "Progress", SKIP_OPEN_TABLE}, + {"MEMORY_USED", 7, MYSQL_TYPE_LONG, 0, 0, "Memory_used", SKIP_OPEN_TABLE}, + {"EXAMINED_ROWS", 7, MYSQL_TYPE_LONG, 0, 0, "Examined_rows", SKIP_OPEN_TABLE}, {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE} }; @@ -8941,7 +8970,7 @@ int initialize_schema_table(st_plugin_int *plugin) DBUG_ENTER("initialize_schema_table"); if (!(schema_table= (ST_SCHEMA_TABLE *)my_malloc(sizeof(ST_SCHEMA_TABLE), - MYF(MY_WME | MY_ZEROFILL)))) + MYF(MY_WME | MY_ZEROFILL)))) DBUG_RETURN(1); /* Historical Requirement */ plugin->data= schema_table; // shortcut for the future diff --git a/sql/sql_statistics.cc b/sql/sql_statistics.cc index 70ba6897333..687fdf26228 100644 --- a/sql/sql_statistics.cc +++ b/sql/sql_statistics.cc @@ -1387,7 +1387,8 @@ public: is_single_comp_pk= FALSE; uint pk= table->s->primary_key; - if (table->key_info - key_info == pk && table->key_info[pk].key_parts == 1) + if ((uint) (table->key_info - key_info) == pk && + table->key_info[pk].key_parts == 1) { prefixes= 1; is_single_comp_pk= TRUE; diff --git a/sql/sql_string.cc b/sql/sql_string.cc index 126139cd219..9d11677666f 100644 --- a/sql/sql_string.cc +++ b/sql/sql_string.cc @@ -42,7 +42,9 @@ bool String::real_alloc(uint32 length) if (Alloced_length < arg_length) { free(); - if (!(Ptr=(char*) my_malloc(arg_length,MYF(MY_WME)))) + if (!(Ptr=(char*) my_malloc(arg_length,MYF(MY_WME | + (thread_specific ? + MY_THREAD_SPECIFIC : 0))))) return TRUE; Alloced_length=arg_length; alloced=1; @@ -90,10 +92,16 @@ bool String::realloc_raw(uint32 alloc_length) return TRUE; /* Overflow */ if (alloced) { - if (!(new_ptr= (char*) my_realloc(Ptr,len,MYF(MY_WME)))) + if (!(new_ptr= (char*) my_realloc(Ptr,len, + MYF(MY_WME | + (thread_specific ? + MY_THREAD_SPECIFIC : 0))))) return TRUE; // Signal error } - else if ((new_ptr= (char*) my_malloc(len,MYF(MY_WME)))) + else if ((new_ptr= (char*) my_malloc(len, + MYF(MY_WME | + (thread_specific ? + MY_THREAD_SPECIFIC : 0))))) { if (str_length > len - 1) str_length= 0; diff --git a/sql/sql_string.h b/sql/sql_string.h index 2966fc2a920..58cda343dac 100644 --- a/sql/sql_string.h +++ b/sql/sql_string.h @@ -56,23 +56,26 @@ class String { char *Ptr; uint32 str_length,Alloced_length, extra_alloc; - bool alloced; + bool alloced,thread_specific; CHARSET_INFO *str_charset; public: String() { - Ptr=0; str_length=Alloced_length=extra_alloc=0; alloced=0; + Ptr=0; str_length=Alloced_length=extra_alloc=0; + alloced= thread_specific= 0; str_charset= &my_charset_bin; } String(uint32 length_arg) { - alloced=0; Alloced_length= extra_alloc= 0; (void) real_alloc(length_arg); + alloced= thread_specific= 0; + Alloced_length= extra_alloc= 0; (void) real_alloc(length_arg); str_charset= &my_charset_bin; } String(const char *str, CHARSET_INFO *cs) { Ptr=(char*) str; str_length= (uint32) strlen(str); - Alloced_length= extra_alloc= 0; alloced=0; + Alloced_length= extra_alloc= 0; + alloced= thread_specific= 0; str_charset=cs; } /* @@ -82,18 +85,21 @@ public: */ String(const char *str,uint32 len, CHARSET_INFO *cs) { - Ptr=(char*) str; str_length=len; Alloced_length= extra_alloc=0; alloced=0; + Ptr=(char*) str; str_length=len; Alloced_length= extra_alloc=0; + alloced= thread_specific= 0; str_charset=cs; } String(char *str,uint32 len, CHARSET_INFO *cs) { - Ptr=(char*) str; Alloced_length=str_length=len; extra_alloc= 0; alloced=0; + Ptr=(char*) str; Alloced_length=str_length=len; extra_alloc= 0; + alloced= thread_specific= 0; str_charset=cs; } String(const String &str) { Ptr=str.Ptr ; str_length=str.str_length ; - Alloced_length=str.Alloced_length; extra_alloc= 0; alloced=0; + Alloced_length=str.Alloced_length; extra_alloc= 0; + alloced= thread_specific= 0; str_charset=str.str_charset; } static void *operator new(size_t size, MEM_ROOT *mem_root) throw () @@ -108,6 +114,12 @@ public: { /* never called */ } ~String() { free(); } + /* Mark variable thread specific it it's not allocated already */ + inline void set_thread_specific() + { + if (!alloced) + thread_specific= 1; + } inline void set_charset(CHARSET_INFO *charset_arg) { str_charset= charset_arg; } inline CHARSET_INFO *charset() const { return str_charset; } @@ -332,6 +344,7 @@ public: Ptr=s.Ptr ; str_length=s.str_length ; Alloced_length=s.Alloced_length; extra_alloc= s.extra_alloc; alloced= s.alloced; + thread_specific= s.thread_specific; s.alloced= 0; } bool append(const String &s); diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 57d0bf375da..d0a4aedfa4f 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -961,7 +961,7 @@ static int execute_ddl_log_action(THD *thd, DDL_LOG_ENTRY *ddl_log_entry) ddl_log_entry->handler_name)); handler_name.str= (char*)ddl_log_entry->handler_name; handler_name.length= strlen(ddl_log_entry->handler_name); - init_sql_alloc(&mem_root, TABLE_ALLOC_BLOCK_SIZE, 0); + init_sql_alloc(&mem_root, TABLE_ALLOC_BLOCK_SIZE, 0, MYF(MY_THREAD_SPECIFIC)); if (!strcmp(ddl_log_entry->handler_name, reg_ext)) frm_action= TRUE; else @@ -1521,7 +1521,7 @@ void execute_ddl_log_recovery() global_ddl_log.recovery_phase= FALSE; delete thd; /* Remember that we don't have a THD */ - my_pthread_setspecific_ptr(THR_THD, 0); + set_current_thd(0); DBUG_VOID_RETURN; } @@ -5380,7 +5380,7 @@ mysql_compare_tables(TABLE *table, if (table->s->tmp_table == NO_TMP_TABLE) { (void) delete_statistics_for_index(thd, table, table_key, FALSE); - if (table_key - table->key_info == table->s->primary_key) + if ((uint) (table_key - table->key_info) == table->s->primary_key) { KEY *tab_key_info= table->key_info; for (uint j=0; j < table->s->keys; j++, tab_key_info++) @@ -7542,7 +7542,8 @@ copy_data_between_tables(THD *thd, TABLE *from,TABLE *to, else { from->sort.io_cache=(IO_CACHE*) my_malloc(sizeof(IO_CACHE), - MYF(MY_FAE | MY_ZEROFILL)); + MYF(MY_FAE | MY_ZEROFILL | + MY_THREAD_SPECIFIC)); bzero((char *) &tables, sizeof(tables)); tables.table= from; tables.alias= tables.table_name= from->s->table_name.str; diff --git a/sql/sql_test.cc b/sql/sql_test.cc index 25ab84fe4db..5b3286d77b0 100644 --- a/sql/sql_test.cc +++ b/sql/sql_test.cc @@ -484,7 +484,9 @@ static void display_table_locks(void) void *saved_base; DYNAMIC_ARRAY saved_table_locks; - (void) my_init_dynamic_array(&saved_table_locks,sizeof(TABLE_LOCK_INFO), cached_open_tables() + 20,50); + (void) my_init_dynamic_array(&saved_table_locks,sizeof(TABLE_LOCK_INFO), + cached_open_tables() + 20, 50, + MYF(MY_THREAD_SPECIFIC)); mysql_mutex_lock(&THR_LOCK_lock); for (list= thr_lock_thread_list; list; list= list_rest(list)) { diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc index aff00f9fcf4..fa509835dae 100644 --- a/sql/sql_trigger.cc +++ b/sql/sql_trigger.cc @@ -1779,7 +1779,7 @@ bool Table_triggers_list::drop_all_triggers(THD *thd, char *db, char *name) DBUG_ENTER("drop_all_triggers"); bzero(&table, sizeof(table)); - init_sql_alloc(&table.mem_root, 8192, 0); + init_sql_alloc(&table.mem_root, 8192, 0, 0); if (Table_triggers_list::check_n_load(thd, db, name, &table, 1)) { @@ -1999,7 +1999,7 @@ bool Table_triggers_list::change_table_name(THD *thd, const char *db, DBUG_ENTER("change_table_name"); bzero(&table, sizeof(table)); - init_sql_alloc(&table.mem_root, 8192, 0); + init_sql_alloc(&table.mem_root, 8192, 0, 0); /* This method interfaces the mysql server code protected by diff --git a/sql/sql_udf.cc b/sql/sql_udf.cc index 9069d876609..9832f240fb5 100644 --- a/sql/sql_udf.cc +++ b/sql/sql_udf.cc @@ -151,7 +151,7 @@ void udf_init() mysql_rwlock_init(key_rwlock_THR_LOCK_udf, &THR_LOCK_udf); - init_sql_alloc(&mem, UDF_ALLOC_BLOCK_SIZE, 0); + init_sql_alloc(&mem, UDF_ALLOC_BLOCK_SIZE, 0, 0); THD *new_thd = new THD; if (!new_thd || my_hash_init(&udf_hash,system_charset_info,32,0,0,get_hash_key, NULL, 0)) @@ -258,7 +258,7 @@ end: close_mysql_tables(new_thd); delete new_thd; /* Remember that we don't have a THD */ - my_pthread_setspecific_ptr(THR_THD, 0); + set_current_thd(0); DBUG_VOID_RETURN; } diff --git a/sql/sql_update.cc b/sql/sql_update.cc index e320c1a3b86..8a0d95722e8 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -492,7 +492,8 @@ int mysql_update(THD *thd, ha_rows found_rows; table->sort.io_cache = (IO_CACHE *) my_malloc(sizeof(IO_CACHE), - MYF(MY_FAE | MY_ZEROFILL)); + MYF(MY_FAE | MY_ZEROFILL | + MY_THREAD_SPECIFIC)); if (!(sortorder=make_unireg_sortorder(order, &length, NULL)) || (table->sort.found_records= filesort(thd, table, sortorder, length, select, limit, diff --git a/sql/table.cc b/sql/table.cc index 6eafdc916f9..6fc6bd44b22 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -307,7 +307,7 @@ TABLE_SHARE *alloc_table_share(TABLE_LIST *table_list, char *key, path_length= build_table_filename(path, sizeof(path) - 1, table_list->db, table_list->table_name, "", 0); - init_sql_alloc(&mem_root, TABLE_ALLOC_BLOCK_SIZE, 0); + init_sql_alloc(&mem_root, TABLE_ALLOC_BLOCK_SIZE, 0, 0); if (multi_alloc_root(&mem_root, &share, sizeof(*share), &key_buff, key_length, @@ -340,7 +340,7 @@ TABLE_SHARE *alloc_table_share(TABLE_LIST *table_list, char *key, share->free_tables.empty(); share->m_flush_tickets.empty(); - init_sql_alloc(&share->stats_cb.mem_root, TABLE_ALLOC_BLOCK_SIZE, 0); + init_sql_alloc(&share->stats_cb.mem_root, TABLE_ALLOC_BLOCK_SIZE, 0, 0); memcpy((char*) &share->mem_root, (char*) &mem_root, sizeof(mem_root)); mysql_mutex_init(key_TABLE_SHARE_LOCK_ha_data, @@ -381,7 +381,12 @@ void init_tmp_table_share(THD *thd, TABLE_SHARE *share, const char *key, DBUG_PRINT("enter", ("table: '%s'.'%s'", key, table_name)); bzero((char*) share, sizeof(*share)); - init_sql_alloc(&share->mem_root, TABLE_ALLOC_BLOCK_SIZE, 0); + /* + This can't be MY_THREAD_SPECIFIC for slaves as they are freed + during cleanup() from Relay_log_info::close_temporary_tables() + */ + init_sql_alloc(&share->mem_root, TABLE_ALLOC_BLOCK_SIZE, 0, + MYF(thd->slave_thread ? 0 : MY_THREAD_SPECIFIC)); share->table_category= TABLE_CATEGORY_TEMPORARY; share->tmp_table= INTERNAL_TMP_TABLE; share->db.str= (char*) key; @@ -2341,6 +2346,8 @@ int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias, DBUG_ENTER("open_table_from_share"); DBUG_PRINT("enter",("name: '%s.%s' form: 0x%lx", share->db.str, share->table_name.str, (long) outparam)); + LINT_INIT(dfield_ptr); + LINT_INIT(vfield_ptr); thd->lex->context_analysis_only&= ~CONTEXT_ANALYSIS_ONLY_VIEW; // not a view @@ -2351,7 +2358,7 @@ int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias, outparam->db_stat= db_stat; outparam->write_row_record= NULL; - init_sql_alloc(&outparam->mem_root, TABLE_ALLOC_BLOCK_SIZE, 0); + init_sql_alloc(&outparam->mem_root, TABLE_ALLOC_BLOCK_SIZE, 0, 0); if (outparam->alias.copy(alias, strlen(alias), table_alias_charset)) goto err; diff --git a/sql/thr_malloc.cc b/sql/thr_malloc.cc index cedcbefc26f..8c7db0673ac 100644 --- a/sql/thr_malloc.cc +++ b/sql/thr_malloc.cc @@ -61,9 +61,10 @@ extern "C" { } } -void init_sql_alloc(MEM_ROOT *mem_root, uint block_size, uint pre_alloc) +void init_sql_alloc(MEM_ROOT *mem_root, uint block_size, uint pre_alloc, + myf my_flags) { - init_alloc_root(mem_root, block_size, pre_alloc); + init_alloc_root(mem_root, block_size, pre_alloc, my_flags); mem_root->error_handler=sql_alloc_error_handler; } diff --git a/sql/thr_malloc.h b/sql/thr_malloc.h index 81b7d3cc238..0b17c5cdaf1 100644 --- a/sql/thr_malloc.h +++ b/sql/thr_malloc.h @@ -20,7 +20,8 @@ typedef struct st_mem_root MEM_ROOT; -void init_sql_alloc(MEM_ROOT *root, uint block_size, uint pre_alloc_size); +void init_sql_alloc(MEM_ROOT *root, uint block_size, uint pre_alloc_size, + myf my_flags); void *sql_alloc(size_t); void *sql_calloc(size_t); char *sql_strdup(const char *str); diff --git a/sql/tztime.cc b/sql/tztime.cc index ba24cab9ca7..525fc96241c 100644 --- a/sql/tztime.cc +++ b/sql/tztime.cc @@ -1637,7 +1637,7 @@ my_tz_init(THD *org_thd, const char *default_tzname, my_bool bootstrap) my_hash_free(&tz_names); goto end; } - init_sql_alloc(&tz_storage, 32 * 1024, 0); + init_sql_alloc(&tz_storage, 32 * 1024, 0, 0); mysql_mutex_init(key_tz_LOCK, &tz_LOCK, MY_MUTEX_INIT_FAST); tz_inited= 1; @@ -1803,7 +1803,7 @@ end: else { /* Remember that we don't have a THD */ - my_pthread_setspecific_ptr(THR_THD, 0); + set_current_thd(0); my_pthread_setspecific_ptr(THR_MALLOC, 0); } @@ -2541,7 +2541,7 @@ scan_tz_dir(char * name_end) } else if (MY_S_ISREG(cur_dir->dir_entry[i].mystat->st_mode)) { - init_alloc_root(&tz_storage, 32768, 0); + init_alloc_root(&tz_storage, 32768, 0, MYF(MY_THREAD_SPECIFIC)); if (!tz_load(fullname, &tz_info, &tz_storage)) print_tz_as_sql(root_name_end + 1, &tz_info); else @@ -2599,7 +2599,7 @@ main(int argc, char **argv) } else { - init_alloc_root(&tz_storage, 32768, 0); + init_alloc_root(&tz_storage, 32768, 0, 0); if (strcmp(argv[1], "--leap") == 0) { diff --git a/sql/uniques.cc b/sql/uniques.cc index c246cd637bd..22f098f8f9a 100644 --- a/sql/uniques.cc +++ b/sql/uniques.cc @@ -84,10 +84,11 @@ Unique::Unique(qsort_cmp2 comp_func, void * comp_func_fixed_arg, if (min_dupl_count_arg) full_size+= sizeof(element_count); my_b_clear(&file); - init_tree(&tree, (ulong) (max_in_memory_size / 16), 0, size, comp_func, 0, - NULL, comp_func_fixed_arg); + init_tree(&tree, (ulong) (max_in_memory_size / 16), 0, size, comp_func, + NULL, comp_func_fixed_arg, MYF(MY_THREAD_SPECIFIC)); /* If the following fail's the next add will also fail */ - my_init_dynamic_array(&file_ptrs, sizeof(BUFFPEK), 16, 16); + my_init_dynamic_array(&file_ptrs, sizeof(BUFFPEK), 16, 16, + MYF(MY_THREAD_SPECIFIC)); /* If you change the following, change it in get_max_elements function, too. */ @@ -602,7 +603,8 @@ bool Unique::walk(tree_walk_action action, void *walk_action_arg) return 1; if (flush_io_cache(&file) || reinit_io_cache(&file, READ_CACHE, 0L, 0, 0)) return 1; - if (!(merge_buffer= (uchar *) my_malloc((ulong) max_in_memory_size, MYF(0)))) + if (!(merge_buffer= (uchar *) my_malloc((ulong) max_in_memory_size, + MYF(MY_THREAD_SPECIFIC)))) return 1; res= merge_walk(merge_buffer, (ulong) max_in_memory_size, size, (BUFFPEK *) file_ptrs.buffer, @@ -625,7 +627,7 @@ bool Unique::get(TABLE *table) { /* Whole tree is in memory; Don't use disk if you don't need to */ if ((record_pointers=table->sort.record_pointers= (uchar*) - my_malloc(size * tree.elements_in_tree, MYF(0)))) + my_malloc(size * tree.elements_in_tree, MYF(MY_THREAD_SPECIFIC)))) { tree_walk_action action= min_dupl_count ? (tree_walk_action) unique_intersect_write_to_ptrs : @@ -650,7 +652,8 @@ bool Unique::get(TABLE *table) /* Open cached file if it isn't open */ outfile=table->sort.io_cache=(IO_CACHE*) my_malloc(sizeof(IO_CACHE), - MYF(MY_ZEROFILL)); + MYF(MY_ZEROFILL | + MY_THREAD_SPECIFIC)); if (!outfile || (! my_b_inited(outfile) && @@ -673,7 +676,7 @@ bool Unique::get(TABLE *table) if (!(sort_buffer=(uchar*) my_malloc((sort_param.max_keys_per_buffer+1) * sort_param.sort_length, - MYF(0)))) + MYF(MY_THREAD_SPECIFIC)))) return 1; sort_param.unique_buff= sort_buffer+(sort_param.max_keys_per_buffer * sort_param.sort_length); diff --git a/sql/unireg.cc b/sql/unireg.cc index edcfe9eb934..20d101be1a3 100644 --- a/sql/unireg.cc +++ b/sql/unireg.cc @@ -282,7 +282,7 @@ bool mysql_create_frm(THD *thd, const char *file_name, } key_buff_length= uint4korr(fileinfo+47); - keybuff=(uchar*) my_malloc(key_buff_length, MYF(0)); + keybuff=(uchar*) my_malloc(key_buff_length, MYF(MY_THREAD_SPECIFIC)); key_info_length= pack_keys(keybuff, keys, key_info, data_offset); /* @@ -534,7 +534,7 @@ static uchar *pack_screens(List<Create_field> &create_fields, while ((field=it++)) length+=(uint) strlen(field->field_name)+1+TE_INFO_LENGTH+cols/2; - if (!(info=(uchar*) my_malloc(length,MYF(MY_WME)))) + if (!(info=(uchar*) my_malloc(length,MYF(MY_WME | MY_THREAD_SPECIFIC)))) DBUG_RETURN(0); start_screen=0; @@ -1108,7 +1108,9 @@ static bool make_empty_rec(THD *thd, File file,enum legacy_db_type table_type, bzero((char*) &share, sizeof(share)); table.s= &share; - if (!(buff=(uchar*) my_malloc((size_t) reclength,MYF(MY_WME | MY_ZEROFILL)))) + if (!(buff=(uchar*) my_malloc((size_t) reclength, + MYF(MY_WME | MY_ZEROFILL | + MY_THREAD_SPECIFIC)))) { DBUG_RETURN(1); } diff --git a/storage/csv/ha_tina.cc b/storage/csv/ha_tina.cc index ba731298d02..9c749a9f67c 100644 --- a/storage/csv/ha_tina.cc +++ b/storage/csv/ha_tina.cc @@ -497,7 +497,7 @@ ha_tina::ha_tina(handlerton *hton, TABLE_SHARE *table_arg) buffer.set((char*)byte_buffer, IO_SIZE, &my_charset_bin); chain= chain_buffer; file_buff= new Transparent_file(); - init_alloc_root(&blobroot, BLOB_MEMROOT_ALLOC_SIZE, 0);; + init_alloc_root(&blobroot, BLOB_MEMROOT_ALLOC_SIZE, 0, 0); } @@ -961,7 +961,7 @@ int ha_tina::open(const char *name, int mode, uint open_options) */ thr_lock_data_init(&share->lock, &lock, (void*) this); ref_length= sizeof(my_off_t); - init_alloc_root(&blobroot, BLOB_MEMROOT_ALLOC_SIZE, 0); + init_alloc_root(&blobroot, BLOB_MEMROOT_ALLOC_SIZE, 0, 0); share->lock.get_status= tina_get_status; share->lock.update_status= tina_update_status; diff --git a/storage/federated/ha_federated.cc b/storage/federated/ha_federated.cc index b543c9ffc90..65ae11790a0 100644 --- a/storage/federated/ha_federated.cc +++ b/storage/federated/ha_federated.cc @@ -1515,7 +1515,7 @@ static FEDERATED_SHARE *get_share(const char *table_name, TABLE *table) */ query.length(0); - init_alloc_root(&mem_root, 256, 0); + init_alloc_root(&mem_root, 256, 0, 0); mysql_mutex_lock(&federated_mutex); @@ -1656,7 +1656,7 @@ int ha_federated::open(const char *name, int mode, uint test_if_locked) ref_length= sizeof(MYSQL_RES *) + sizeof(MYSQL_ROW_OFFSET); DBUG_PRINT("info", ("ref_length: %u", ref_length)); - my_init_dynamic_array(&results, sizeof(MYSQL_RES *), 4, 4); + my_init_dynamic_array(&results, sizeof(MYSQL_RES *), 4, 4, 0); reset(); DBUG_RETURN(0); @@ -3137,6 +3137,7 @@ int ha_federated::real_connect() { char buffer[FEDERATED_QUERY_BUFFER_SIZE]; String sql_query(buffer, sizeof(buffer), &my_charset_bin); + int int_arg; DBUG_ENTER("ha_federated::real_connect"); /* @@ -3155,6 +3156,10 @@ int ha_federated::real_connect() DBUG_RETURN(-1); } + /* Ensure that memory is registered for the system, not for the THD */ + int_arg= 0; + mysql_options(mysql,MYSQL_THREAD_SPECIFIC_MALLOC, &int_arg); + /* BUG# 17044 Federated Storage Engine is not UTF8 clean Add set names to whatever charset the table is at open @@ -3165,7 +3170,6 @@ int ha_federated::real_connect() this->table->s->table_charset->csname); sql_query.length(0); - if (!mysql_real_connect(mysql, share->hostname, share->username, diff --git a/storage/federatedx/federatedx_io_mysql.cc b/storage/federatedx/federatedx_io_mysql.cc index a2ba496ea47..dc61d7ccc41 100644 --- a/storage/federatedx/federatedx_io_mysql.cc +++ b/storage/federatedx/federatedx_io_mysql.cc @@ -136,7 +136,7 @@ federatedx_io_mysql::federatedx_io_mysql(FEDERATEDX_SERVER *aserver) bzero(&mysql, sizeof(MYSQL)); bzero(&savepoints, sizeof(DYNAMIC_ARRAY)); - my_init_dynamic_array(&savepoints, sizeof(SAVEPT), 16, 16); + my_init_dynamic_array(&savepoints, sizeof(SAVEPT), 16, 16, 0); DBUG_VOID_RETURN; } diff --git a/storage/federatedx/ha_federatedx.cc b/storage/federatedx/ha_federatedx.cc index 7f095a9b96e..1947390e6da 100644 --- a/storage/federatedx/ha_federatedx.cc +++ b/storage/federatedx/ha_federatedx.cc @@ -1519,7 +1519,7 @@ static FEDERATEDX_SERVER *get_server(FEDERATEDX_SHARE *share, TABLE *table) mysql_mutex_assert_owner(&federatedx_mutex); - init_alloc_root(&mem_root, 4096, 4096); + init_alloc_root(&mem_root, 4096, 4096, 0); fill_server(&mem_root, &tmp_server, share, table ? table->s->table_charset : 0); @@ -1577,7 +1577,7 @@ static FEDERATEDX_SHARE *get_share(const char *table_name, TABLE *table) query.length(0); bzero(&tmp_share, sizeof(tmp_share)); - init_alloc_root(&mem_root, 256, 0); + init_alloc_root(&mem_root, 256, 0, 0); mysql_mutex_lock(&federatedx_mutex); @@ -1791,7 +1791,7 @@ int ha_federatedx::open(const char *name, int mode, uint test_if_locked) DBUG_PRINT("info", ("ref_length: %u", ref_length)); - my_init_dynamic_array(&results, sizeof(FEDERATEDX_IO_RESULT*), 4, 4); + my_init_dynamic_array(&results, sizeof(FEDERATEDX_IO_RESULT*), 4, 4, 0); reset(); diff --git a/storage/heap/ha_heap.cc b/storage/heap/ha_heap.cc index b9eef0d155b..8e63799680b 100644 --- a/storage/heap/ha_heap.cc +++ b/storage/heap/ha_heap.cc @@ -634,7 +634,7 @@ heap_prepare_hp_create_info(TABLE *table_arg, bool internal_table, if (!(keydef= (HP_KEYDEF*) my_malloc(keys * sizeof(HP_KEYDEF) + parts * sizeof(HA_KEYSEG), - MYF(MY_WME)))) + MYF(MY_WME | MY_THREAD_SPECIFIC)))) return my_errno; seg= reinterpret_cast<HA_KEYSEG*>(keydef + keys); for (key= 0; key < keys; key++) diff --git a/storage/heap/heapdef.h b/storage/heap/heapdef.h index db00ea87a01..d5c0ad96b05 100644 --- a/storage/heap/heapdef.h +++ b/storage/heap/heapdef.h @@ -62,7 +62,8 @@ typedef struct { extern HP_SHARE *hp_find_named_heap(const char *name); extern int hp_rectest(HP_INFO *info,const uchar *old); extern uchar *hp_find_block(HP_BLOCK *info,ulong pos); -extern int hp_get_new_block(HP_BLOCK *info, size_t* alloc_length); +extern int hp_get_new_block(HP_SHARE *info, HP_BLOCK *block, + size_t* alloc_length); extern void hp_free(HP_SHARE *info); extern uchar *hp_free_level(HP_BLOCK *block,uint level,HP_PTRS *pos, uchar *last_pos); diff --git a/storage/heap/hp_block.c b/storage/heap/hp_block.c index 01978e2b4e8..1c40f982422 100644 --- a/storage/heap/hp_block.c +++ b/storage/heap/hp_block.c @@ -45,6 +45,7 @@ uchar *hp_find_block(HP_BLOCK *block, ulong pos) SYNOPSIS hp_get_new_block() + info heap handle block HP_BLOCK tree-like block alloc_length OUT Amount of memory allocated from the heap @@ -54,7 +55,7 @@ uchar *hp_find_block(HP_BLOCK *block, ulong pos) 1 Out of memory */ -int hp_get_new_block(HP_BLOCK *block, size_t *alloc_length) +int hp_get_new_block(HP_SHARE *info, HP_BLOCK *block, size_t *alloc_length) { reg1 uint i,j; HP_PTRS *root; @@ -77,7 +78,10 @@ int hp_get_new_block(HP_BLOCK *block, size_t *alloc_length) */ *alloc_length= (sizeof(HP_PTRS)* ((i == block->levels) ? i : i - 1) + block->records_in_block* block->recbuffer); - if (!(root=(HP_PTRS*) my_malloc(*alloc_length,MYF(MY_WME)))) + if (!(root=(HP_PTRS*) my_malloc(*alloc_length, + MYF(MY_WME | + (info->internal ? + MY_THREAD_SPECIFIC : 0))))) return 1; if (i == 0) diff --git a/storage/heap/hp_create.c b/storage/heap/hp_create.c index d170d1abc65..a8bc8e63810 100644 --- a/storage/heap/hp_create.c +++ b/storage/heap/hp_create.c @@ -146,7 +146,9 @@ int heap_create(const char *name, HP_CREATE_INFO *create_info, if (!(share= (HP_SHARE*) my_malloc((uint) sizeof(HP_SHARE)+ keys*sizeof(HP_KEYDEF)+ key_segs*sizeof(HA_KEYSEG), - MYF(MY_ZEROFILL)))) + MYF(MY_ZEROFILL | + (create_info->internal_table ? + MY_THREAD_SPECIFIC : 0))))) goto err; share->keydef= (HP_KEYDEF*) (share + 1); share->key_stat_version= 1; @@ -171,7 +173,9 @@ int heap_create(const char *name, HP_CREATE_INFO *create_info, keyseg++; init_tree(&keyinfo->rb_tree, 0, 0, sizeof(uchar*), - (qsort_cmp2)keys_compare, 1, NULL, NULL); + (qsort_cmp2)keys_compare, NULL, NULL, + MYF((create_info->internal_table ? MY_THREAD_SPECIFIC : 0) | + MY_TREE_WITH_DELETE)); keyinfo->delete_key= hp_rb_delete_key; keyinfo->write_key= hp_rb_write_key; } @@ -199,6 +203,7 @@ int heap_create(const char *name, HP_CREATE_INFO *create_info, share->auto_key_type= create_info->auto_key_type; share->auto_increment= create_info->auto_increment; share->create_time= (long) time((time_t*) 0); + share->internal= create_info->internal_table; /* Must be allocated separately for rename to work */ if (!(share->name= my_strdup(name,MYF(0)))) { diff --git a/storage/heap/hp_open.c b/storage/heap/hp_open.c index c456dbdfc84..fc7397989f2 100644 --- a/storage/heap/hp_open.c +++ b/storage/heap/hp_open.c @@ -32,7 +32,9 @@ HP_INFO *heap_open_from_share(HP_SHARE *share, int mode) if (!(info= (HP_INFO*) my_malloc((uint) sizeof(HP_INFO) + 2 * share->max_key_length, - MYF(MY_ZEROFILL)))) + MYF(MY_ZEROFILL + + (share->internal ? + MY_THREAD_SPECIFIC : 0))))) { DBUG_RETURN(0); } diff --git a/storage/heap/hp_write.c b/storage/heap/hp_write.c index 8bfecc7747c..c84fc4b6104 100644 --- a/storage/heap/hp_write.c +++ b/storage/heap/hp_write.c @@ -162,7 +162,7 @@ static uchar *next_free_record_pos(HP_SHARE *info) my_errno=HA_ERR_RECORD_FILE_FULL; DBUG_RETURN(NULL); } - if (hp_get_new_block(&info->block,&length)) + if (hp_get_new_block(info, &info->block,&length)) DBUG_RETURN(NULL); info->data_length+=length; } @@ -407,7 +407,7 @@ static HASH_INFO *hp_find_free_hash(HP_SHARE *info, return hp_find_hash(block,records); if (!(block_pos=(records % block->records_in_block))) { - if (hp_get_new_block(block,&length)) + if (hp_get_new_block(info, block, &length)) return(NULL); info->index_length+=length; } diff --git a/storage/maria/ma_bitmap.c b/storage/maria/ma_bitmap.c index f5d32d6a191..00d79b54dd1 100644 --- a/storage/maria/ma_bitmap.c +++ b/storage/maria/ma_bitmap.c @@ -239,7 +239,7 @@ my_bool _ma_bitmap_init(MARIA_SHARE *share, File file, if (((bitmap->map= (uchar*) my_malloc(size, MYF(MY_WME))) == NULL) || my_init_dynamic_array(&bitmap->pinned_pages, - sizeof(MARIA_PINNED_PAGE), 1, 1)) + sizeof(MARIA_PINNED_PAGE), 1, 1, 0)) return 1; bitmap->block_size= share->block_size; diff --git a/storage/maria/ma_blockrec.c b/storage/maria/ma_blockrec.c index 71faa11fd2b..0f49175905a 100644 --- a/storage/maria/ma_blockrec.c +++ b/storage/maria/ma_blockrec.c @@ -528,7 +528,7 @@ my_bool _ma_init_block_record(MARIA_HA *info) if (my_init_dynamic_array(&info->bitmap_blocks, sizeof(MARIA_BITMAP_BLOCK), default_extents, - 64)) + 64, 0)) goto err; info->cur_row.extents_buffer_length= default_extents * ROW_EXTENT_SIZE; if (!(info->cur_row.extents= my_malloc(info->cur_row.extents_buffer_length, diff --git a/storage/maria/ma_check.c b/storage/maria/ma_check.c index c362a3024ae..88ec6362853 100644 --- a/storage/maria/ma_check.c +++ b/storage/maria/ma_check.c @@ -3765,7 +3765,8 @@ int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info, param->read_cache.end_of_file= sort_info.filelength; sort_param.wordlist=NULL; - init_alloc_root(&sort_param.wordroot, FTPARSER_MEMROOT_ALLOC_SIZE, 0); + init_alloc_root(&sort_param.wordroot, FTPARSER_MEMROOT_ALLOC_SIZE, 0, + param->malloc_flags); sort_param.key_cmp=sort_key_cmp; sort_param.lock_in_memory=maria_lock_memory; @@ -4402,7 +4403,8 @@ int maria_repair_parallel(HA_CHECK *param, register MARIA_HA *info, (FT_MAX_WORD_LEN_FOR_SORT * sort_param[i].keyinfo->seg->charset->mbmaxlen); sort_param[i].key_length+=ft_max_word_len_for_sort-HA_FT_MAXBYTELEN; - init_alloc_root(&sort_param[i].wordroot, FTPARSER_MEMROOT_ALLOC_SIZE, 0); + init_alloc_root(&sort_param[i].wordroot, FTPARSER_MEMROOT_ALLOC_SIZE, 0, + param->malloc_flags); } } sort_info.total_keys=i; diff --git a/storage/maria/ma_ft_boolean_search.c b/storage/maria/ma_ft_boolean_search.c index 83ae08553ef..c98c4b599fc 100644 --- a/storage/maria/ma_ft_boolean_search.c +++ b/storage/maria/ma_ft_boolean_search.c @@ -527,7 +527,7 @@ static void _ftb_init_index_search(FT_INFO *ftb) /* 4 */ if (!is_tree_inited(& ftb->no_dupes)) init_tree(& ftb->no_dupes,0,0,sizeof(my_off_t), - _ftb_no_dupes_cmp,0,0,0); + _ftb_no_dupes_cmp,0,0,0); else reset_tree(& ftb->no_dupes); } @@ -561,7 +561,7 @@ FT_INFO * maria_ft_init_boolean_search(MARIA_HA *info, uint keynr, bzero(& ftb->no_dupes, sizeof(TREE)); ftb->last_word= 0; - init_alloc_root(&ftb->mem_root, 1024, 1024); + init_alloc_root(&ftb->mem_root, 1024, 1024, 0); ftb->queue.max_elements= 0; if (!(ftbe=(FTB_EXPR *)alloc_root(&ftb->mem_root, sizeof(FTB_EXPR)))) goto err; diff --git a/storage/maria/ma_ft_nlq_search.c b/storage/maria/ma_ft_nlq_search.c index c8b87c4f42c..ad859382bfc 100644 --- a/storage/maria/ma_ft_nlq_search.c +++ b/storage/maria/ma_ft_nlq_search.c @@ -239,8 +239,8 @@ FT_INFO *maria_ft_init_nlq_search(MARIA_HA *info, uint keynr, uchar *query, bzero(&wtree,sizeof(wtree)); - init_tree(&aio.dtree,0,0,sizeof(FT_SUPERDOC),(qsort_cmp2)&FT_SUPERDOC_cmp,0, - NULL, NULL); + init_tree(&aio.dtree,0,0,sizeof(FT_SUPERDOC),(qsort_cmp2)&FT_SUPERDOC_cmp, + NULL, NULL, 0); maria_ft_parse_init(&wtree, aio.charset); ftparser_param->flags= 0; diff --git a/storage/maria/ma_ft_parser.c b/storage/maria/ma_ft_parser.c index 3dd6fab5214..78f3591d6e9 100644 --- a/storage/maria/ma_ft_parser.c +++ b/storage/maria/ma_ft_parser.c @@ -254,8 +254,8 @@ void maria_ft_parse_init(TREE *wtree, CHARSET_INFO *cs) { DBUG_ENTER("maria_ft_parse_init"); if (!is_tree_inited(wtree)) - init_tree(wtree,0,0,sizeof(FT_WORD),(qsort_cmp2)&FT_WORD_cmp,0, NULL, - (void*) cs); + init_tree(wtree,0,0,sizeof(FT_WORD),(qsort_cmp2)&FT_WORD_cmp, NULL, + (void*) cs, 0); DBUG_VOID_RETURN; } @@ -348,7 +348,7 @@ MYSQL_FTPARSER_PARAM* maria_ftparser_alloc_param(MARIA_HA *info) info->ftparser_param= (MYSQL_FTPARSER_PARAM *) my_malloc(MAX_PARAM_NR * sizeof(MYSQL_FTPARSER_PARAM) * info->s->ftkeys, MYF(MY_WME | MY_ZEROFILL)); - init_alloc_root(&info->ft_memroot, FTPARSER_MEMROOT_ALLOC_SIZE, 0); + init_alloc_root(&info->ft_memroot, FTPARSER_MEMROOT_ALLOC_SIZE, 0, 0); } return info->ftparser_param; } diff --git a/storage/maria/ma_loghandler.c b/storage/maria/ma_loghandler.c index 341bbc6088f..de998ca9a2c 100644 --- a/storage/maria/ma_loghandler.c +++ b/storage/maria/ma_loghandler.c @@ -3629,10 +3629,10 @@ my_bool translog_init_with_table(const char *directory, mysql_rwlock_init(key_TRANSLOG_DESCRIPTOR_open_files_lock, &log_descriptor.open_files_lock) || my_init_dynamic_array(&log_descriptor.open_files, - sizeof(TRANSLOG_FILE*), 10, 10) || + sizeof(TRANSLOG_FILE*), 10, 10, 0) || my_init_dynamic_array(&log_descriptor.unfinished_files, sizeof(struct st_file_counter), - 10, 10)) + 10, 10, 0)) goto err; log_descriptor.min_need_file= 0; log_descriptor.min_file_number= 0; @@ -5528,7 +5528,7 @@ translog_write_variable_record_mgroup(LSN *lsn, if (my_init_dynamic_array(&groups, sizeof(struct st_translog_group_descriptor), - 10, 10)) + 10, 10, 0)) { translog_unlock(); DBUG_PRINT("error", ("init array failed")); diff --git a/storage/maria/ma_open.c b/storage/maria/ma_open.c index 5f90f61c786..493551c002e 100644 --- a/storage/maria/ma_open.c +++ b/storage/maria/ma_open.c @@ -160,7 +160,7 @@ static MARIA_HA *maria_clone_internal(MARIA_SHARE *share, const char *name, if (my_init_dynamic_array(&info.pinned_pages, sizeof(MARIA_PINNED_PAGE), max(share->base.blobs*2 + 4, - MARIA_MAX_TREE_LEVELS*3), 16)) + MARIA_MAX_TREE_LEVELS*3), 16, 0)) goto err; diff --git a/storage/maria/ma_sort.c b/storage/maria/ma_sort.c index e1e7b323683..7894c56fc21 100644 --- a/storage/maria/ma_sort.c +++ b/storage/maria/ma_sort.c @@ -164,7 +164,7 @@ int _ma_create_index_by_sort(MARIA_SORT_PARAM *info, my_bool no_messages, HA_FT_MAXBYTELEN, MYF(0)))) { if (my_init_dynamic_array(&buffpek, sizeof(BUFFPEK), maxbuffer, - maxbuffer/2)) + maxbuffer/2, 0)) { my_free(sort_keys); sort_keys= 0; @@ -397,7 +397,7 @@ pthread_handler_t _ma_thr_find_all_keys(void *arg) HA_FT_MAXBYTELEN : 0), MYF(0)))) { if (my_init_dynamic_array(&sort_param->buffpek, sizeof(BUFFPEK), - maxbuffer, maxbuffer/2)) + maxbuffer, maxbuffer/2, 0)) { my_free(sort_keys); sort_keys= (uchar **) NULL; /* for err: label */ diff --git a/storage/maria/ma_write.c b/storage/maria/ma_write.c index f1649083105..ca0b39537a2 100644 --- a/storage/maria/ma_write.c +++ b/storage/maria/ma_write.c @@ -881,7 +881,7 @@ ChangeSet@1.2562, 2008-04-09 07:41:40+02:00, serg@janus.mylan +9 -0 /* Yup. converting */ info->ft1_to_ft2=(DYNAMIC_ARRAY *) my_malloc(sizeof(DYNAMIC_ARRAY), MYF(MY_WME)); - my_init_dynamic_array(info->ft1_to_ft2, ft2len, 300, 50); + my_init_dynamic_array(info->ft1_to_ft2, ft2len, 300, 50, 0); /* Now, adding all keys from the page to dynarray @@ -1766,8 +1766,8 @@ int maria_init_bulk_insert(MARIA_HA *info, ulong cache_size, ha_rows rows) init_tree(&info->bulk_insert[i], cache_size * key[i].maxlength, cache_size * key[i].maxlength, 0, - (qsort_cmp2)keys_compare, 0, - (tree_element_free) keys_free, (void *)params++); + (qsort_cmp2)keys_compare, + (tree_element_free) keys_free, (void *)params++, 0); } else info->bulk_insert[i].root=0; diff --git a/storage/maria/maria_pack.c b/storage/maria/maria_pack.c index 481b77a2cc6..0bc68f95d1e 100644 --- a/storage/maria/maria_pack.c +++ b/storage/maria/maria_pack.c @@ -798,8 +798,8 @@ static HUFF_COUNTS *init_huff_count(MARIA_HA *info,my_off_t records) 'tree_pos'. It's keys are implemented by pointers into 'tree_buff'. This is accomplished by '-1' as the element size. */ - init_tree(&count[i].int_tree,0,0,-1,(qsort_cmp2) compare_tree,0, NULL, - NULL); + init_tree(&count[i].int_tree,0,0,-1,(qsort_cmp2) compare_tree, NULL, + NULL, 0); if (records && type != FIELD_BLOB && type != FIELD_VARCHAR) count[i].tree_pos=count[i].tree_buff = my_malloc(count[i].field_length > 1 ? tree_buff_length : 2, diff --git a/storage/maria/unittest/sequence_storage.c b/storage/maria/unittest/sequence_storage.c index d5db20d31ca..6a39cca5055 100644 --- a/storage/maria/unittest/sequence_storage.c +++ b/storage/maria/unittest/sequence_storage.c @@ -33,7 +33,7 @@ my_bool seq_storage_reader_init(SEQ_STORAGE *seq, const char *file) seq->pos= 0; if ((fd= my_fopen(file, O_RDONLY, MYF(MY_WME))) == NULL) return 1; - if (my_init_dynamic_array(&seq->seq, sizeof(ulong), 10, 10)) + if (my_init_dynamic_array(&seq->seq, sizeof(ulong), 10, 10, 0)) return 1; for(;;) diff --git a/storage/myisam/ft_boolean_search.c b/storage/myisam/ft_boolean_search.c index 8b61e1dc4f2..1b31b4b1da3 100644 --- a/storage/myisam/ft_boolean_search.c +++ b/storage/myisam/ft_boolean_search.c @@ -550,7 +550,7 @@ static void _ftb_init_index_search(FT_INFO *ftb) /* 4 */ if (!is_tree_inited(& ftb->no_dupes)) init_tree(& ftb->no_dupes,0,0,sizeof(my_off_t), - _ftb_no_dupes_cmp,0,0,0); + _ftb_no_dupes_cmp,0,0,0); else reset_tree(& ftb->no_dupes); } @@ -583,7 +583,7 @@ FT_INFO * ft_init_boolean_search(MI_INFO *info, uint keynr, uchar *query, bzero(& ftb->no_dupes, sizeof(TREE)); ftb->last_word= 0; - init_alloc_root(&ftb->mem_root, 1024, 1024); + init_alloc_root(&ftb->mem_root, 1024, 1024, 0); ftb->queue.max_elements= 0; if (!(ftbe=(FTB_EXPR *)alloc_root(&ftb->mem_root, sizeof(FTB_EXPR)))) goto err; diff --git a/storage/myisam/ft_nlq_search.c b/storage/myisam/ft_nlq_search.c index bafa7064e28..e7e27870762 100644 --- a/storage/myisam/ft_nlq_search.c +++ b/storage/myisam/ft_nlq_search.c @@ -248,8 +248,8 @@ FT_INFO *ft_init_nlq_search(MI_INFO *info, uint keynr, uchar *query, bzero(&wtree,sizeof(wtree)); - init_tree(&aio.dtree,0,0,sizeof(FT_SUPERDOC),(qsort_cmp2)&FT_SUPERDOC_cmp,0, - NULL, NULL); + init_tree(&aio.dtree,0,0,sizeof(FT_SUPERDOC),(qsort_cmp2)&FT_SUPERDOC_cmp, + NULL, NULL, 0); ft_parse_init(&wtree, aio.charset); ftparser_param->flags= 0; diff --git a/storage/myisam/ft_parser.c b/storage/myisam/ft_parser.c index c534a9a060b..5d271f4d361 100644 --- a/storage/myisam/ft_parser.c +++ b/storage/myisam/ft_parser.c @@ -249,7 +249,8 @@ void ft_parse_init(TREE *wtree, CHARSET_INFO *cs) { DBUG_ENTER("ft_parse_init"); if (!is_tree_inited(wtree)) - init_tree(wtree,0,0,sizeof(FT_WORD),(qsort_cmp2)&FT_WORD_cmp,0,0,(void*)cs); + init_tree(wtree, 0, 0, sizeof(FT_WORD), (qsort_cmp2)&FT_WORD_cmp, 0, + (void*)cs, 0); DBUG_VOID_RETURN; } @@ -341,7 +342,7 @@ MYSQL_FTPARSER_PARAM* ftparser_alloc_param(MI_INFO *info) info->ftparser_param= (MYSQL_FTPARSER_PARAM *) my_malloc(MAX_PARAM_NR * sizeof(MYSQL_FTPARSER_PARAM) * info->s->ftkeys, MYF(MY_WME | MY_ZEROFILL)); - init_alloc_root(&info->ft_memroot, FTPARSER_MEMROOT_ALLOC_SIZE, 0); + init_alloc_root(&info->ft_memroot, FTPARSER_MEMROOT_ALLOC_SIZE, 0, 0); } return info->ftparser_param; } diff --git a/storage/myisam/ft_stopwords.c b/storage/myisam/ft_stopwords.c index 8f6f9308d3c..84eda800f6a 100644 --- a/storage/myisam/ft_stopwords.c +++ b/storage/myisam/ft_stopwords.c @@ -61,9 +61,8 @@ int ft_init_stopwords() if (!(stopwords3=(TREE *)my_malloc(sizeof(TREE),MYF(0)))) DBUG_RETURN(-1); init_tree(stopwords3,0,0,sizeof(FT_STOPWORD),(qsort_cmp2)&FT_STOPWORD_cmp, - 0, (ft_stopword_file ? (tree_element_free)&FT_STOPWORD_free : 0), - NULL); + NULL, 0); /* Stopword engine currently does not support tricky character sets UCS2, UTF16, UTF32. diff --git a/storage/myisam/mi_check.c b/storage/myisam/mi_check.c index ef3a6bc2864..29b513b1451 100644 --- a/storage/myisam/mi_check.c +++ b/storage/myisam/mi_check.c @@ -2299,7 +2299,8 @@ int mi_repair_by_sort(HA_CHECK *param, register MI_INFO *info, mysql_file_seek(param->read_cache.file, 0L, MY_SEEK_END, MYF(0)); sort_param.wordlist=NULL; - init_alloc_root(&sort_param.wordroot, FTPARSER_MEMROOT_ALLOC_SIZE, 0); + init_alloc_root(&sort_param.wordroot, FTPARSER_MEMROOT_ALLOC_SIZE, 0, + param->malloc_flags); if (share->data_file_type == DYNAMIC_RECORD) length=max(share->base.min_pack_length+1,share->base.min_block_length); @@ -2869,7 +2870,8 @@ int mi_repair_parallel(HA_CHECK *param, register MI_INFO *info, uint ft_max_word_len_for_sort=FT_MAX_WORD_LEN_FOR_SORT* sort_param[i].keyinfo->seg->charset->mbmaxlen; sort_param[i].key_length+=ft_max_word_len_for_sort-HA_FT_MAXBYTELEN; - init_alloc_root(&sort_param[i].wordroot, FTPARSER_MEMROOT_ALLOC_SIZE, 0); + init_alloc_root(&sort_param[i].wordroot, FTPARSER_MEMROOT_ALLOC_SIZE, 0, + param->malloc_flags); } } sort_info.total_keys=i; diff --git a/storage/myisam/mi_write.c b/storage/myisam/mi_write.c index 70cc96d0cba..5d218ecf0d2 100644 --- a/storage/myisam/mi_write.c +++ b/storage/myisam/mi_write.c @@ -544,7 +544,7 @@ int _mi_insert(register MI_INFO *info, register MI_KEYDEF *keyinfo, /* yup. converting */ info->ft1_to_ft2=(DYNAMIC_ARRAY *) my_malloc(sizeof(DYNAMIC_ARRAY), MYF(MY_WME)); - my_init_dynamic_array(info->ft1_to_ft2, ft2len, 300, 50); + my_init_dynamic_array(info->ft1_to_ft2, ft2len, 300, 50, 0); /* now, adding all keys from the page to dynarray @@ -1013,8 +1013,8 @@ int mi_init_bulk_insert(MI_INFO *info, ulong cache_size, ha_rows rows) init_tree(&info->bulk_insert[i], cache_size * key[i].maxlength, cache_size * key[i].maxlength, 0, - (qsort_cmp2)keys_compare, 0, - (tree_element_free) keys_free, (void *)params++); + (qsort_cmp2)keys_compare, + (tree_element_free) keys_free, (void *)params++, 0); } else info->bulk_insert[i].root=0; diff --git a/storage/myisam/myisamlog.c b/storage/myisam/myisamlog.c index 3314f1b94ac..1624213851b 100644 --- a/storage/myisam/myisamlog.c +++ b/storage/myisam/myisamlog.c @@ -329,8 +329,9 @@ static int examine_log(char * file_name, char **table_names) init_io_cache(&cache,file,0,READ_CACHE,start_offset,0,MYF(0)); bzero((uchar*) com_count,sizeof(com_count)); - init_tree(&tree,0,0,sizeof(file_info),(qsort_cmp2) file_info_compare,1, - (tree_element_free) file_info_free, NULL); + init_tree(&tree,0,0,sizeof(file_info),(qsort_cmp2) file_info_compare, + (tree_element_free) file_info_free, NULL, + MYF(MY_TREE_WITH_DELETE)); (void) init_key_cache(dflt_key_cache,KEY_CACHE_BLOCK_SIZE,KEY_CACHE_SIZE, 0, 0, 0); diff --git a/storage/myisam/myisampack.c b/storage/myisam/myisampack.c index 5d6b03ff4b8..c1a2cd496e5 100644 --- a/storage/myisam/myisampack.c +++ b/storage/myisam/myisampack.c @@ -816,8 +816,8 @@ static HUFF_COUNTS *init_huff_count(MI_INFO *info,my_off_t records) 'tree_pos'. It's keys are implemented by pointers into 'tree_buff'. This is accomplished by '-1' as the element size. */ - init_tree(&count[i].int_tree,0,0,-1,(qsort_cmp2) compare_tree,0, NULL, - NULL); + init_tree(&count[i].int_tree,0,0,-1,(qsort_cmp2) compare_tree, NULL, + NULL, 0); if (records && type != FIELD_BLOB && type != FIELD_VARCHAR) count[i].tree_pos=count[i].tree_buff = my_malloc(count[i].field_length > 1 ? tree_buff_length : 2, diff --git a/storage/myisam/sort.c b/storage/myisam/sort.c index 2c4639b3143..f5c0f04d877 100644 --- a/storage/myisam/sort.c +++ b/storage/myisam/sort.c @@ -165,7 +165,7 @@ int _create_index_by_sort(MI_SORT_PARAM *info,my_bool no_messages, HA_FT_MAXBYTELEN, MYF(0)))) { if (my_init_dynamic_array(&buffpek, sizeof(BUFFPEK), maxbuffer, - maxbuffer/2)) + maxbuffer/2, 0)) { my_free(sort_keys); sort_keys= 0; @@ -389,7 +389,7 @@ pthread_handler_t thr_find_all_keys(void *arg) HA_FT_MAXBYTELEN : 0), MYF(0)))) { if (my_init_dynamic_array(&sort_param->buffpek, sizeof(BUFFPEK), - maxbuffer, maxbuffer/2)) + maxbuffer, maxbuffer/2, 0)) { my_free(sort_keys); sort_keys= (uchar **) NULL; /* for err: label */ diff --git a/storage/myisammrg/ha_myisammrg.cc b/storage/myisammrg/ha_myisammrg.cc index c124d5cc690..e930007af02 100644 --- a/storage/myisammrg/ha_myisammrg.cc +++ b/storage/myisammrg/ha_myisammrg.cc @@ -120,7 +120,7 @@ ha_myisammrg::ha_myisammrg(handlerton *hton, TABLE_SHARE *table_arg) :handler(hton, table_arg), file(0), is_cloned(0) { init_sql_alloc(&children_mem_root, - FN_REFLEN + ALLOC_ROOT_MIN_BLOCK_SIZE, 0); + FN_REFLEN + ALLOC_ROOT_MIN_BLOCK_SIZE, 0, 0); } diff --git a/storage/perfschema/pfs_check.cc b/storage/perfschema/pfs_check.cc index c52be6f0da2..2ab54ab1a4a 100644 --- a/storage/perfschema/pfs_check.cc +++ b/storage/perfschema/pfs_check.cc @@ -56,6 +56,8 @@ void check_performance_schema() PFS_engine_table_share::check_all_tables(thd); delete thd; + /* Remember that we don't have a THD */ + set_current_thd(0); DBUG_VOID_RETURN; } diff --git a/storage/perfschema/pfs_instr.cc b/storage/perfschema/pfs_instr.cc index 8da1a9862e1..c9c0a0b1d80 100644 --- a/storage/perfschema/pfs_instr.cc +++ b/storage/perfschema/pfs_instr.cc @@ -821,8 +821,6 @@ const char *sanitize_file_name(const char *unsafe) */ void destroy_thread(PFS_thread *pfs) { - DBUG_ENTER("destroy_thread"); - DBUG_ASSERT(pfs != NULL); if (pfs->m_filename_hash_pins) { @@ -835,7 +833,6 @@ void destroy_thread(PFS_thread *pfs) pfs->m_table_share_hash_pins= NULL; } pfs->m_lock.allocated_to_free(); - DBUG_VOID_RETURN; } /** diff --git a/support-files/compiler_warnings.supp b/support-files/compiler_warnings.supp index 110c1f08263..008ad0870c0 100644 --- a/support-files/compiler_warnings.supp +++ b/support-files/compiler_warnings.supp @@ -195,7 +195,9 @@ ma_packrec\.c : .*result of 32-bit shift implicitly converted to 64 bits.* : 550 .* : .*no matching operator delete found; memory will not be freed if initialization throws an exception.* ctype-simple\.c : .*unary minus operator applied to unsigned type, result still unsigned.* sql/sys_vars\.cc : invalid access to non-static data member -sql/sys_vars\.cc : perhaps the 'offsetof' macro was used incorrectly +sql/sys_vars\.cc : perhaps the .*offsetof.* macro was used incorrectly +string3\.h : memset used with constant zero length parameter + # Wrong warning due to GCC bug: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=29478 regexec\.c : passing argument 3 of.*matcher.* discards qualifiers from pointer target type |