From ac54f00f002aaf1fe4f5041583a2cf966e02e38b Mon Sep 17 00:00:00 2001 From: "msvensson@shellback.(none)" <> Date: Mon, 30 Oct 2006 13:08:57 +0100 Subject: [PATCH 1/2] Add an extra block to avoid that DBUG_ENTER declare variables after code --- myisam/sort.c | 262 ++++++++++++++++++++++++++------------------------ 1 file changed, 134 insertions(+), 128 deletions(-) diff --git a/myisam/sort.c b/myisam/sort.c index cb7893b37bc..35a4f15b23c 100644 --- a/myisam/sort.c +++ b/myisam/sort.c @@ -322,159 +322,165 @@ pthread_handler_t thr_find_all_keys(void *arg) if (my_thread_init()) goto err; - DBUG_ENTER("thr_find_all_keys"); - DBUG_PRINT("enter", ("master: %d", sort_param->master)); - if (sort_param->sort_info->got_error) - goto err; - if (sort_param->keyinfo->flag & HA_VAR_LENGTH_KEY) - { - sort_param->write_keys= write_keys_varlen; - sort_param->read_to_buffer= read_to_buffer_varlen; - sort_param->write_key= write_merge_key_varlen; - } - else - { - sort_param->write_keys= write_keys; - sort_param->read_to_buffer= read_to_buffer; - sort_param->write_key= write_merge_key; - } - my_b_clear(&sort_param->tempfile); - my_b_clear(&sort_param->tempfile_for_exceptions); - bzero((char*) &sort_param->buffpek, sizeof(sort_param->buffpek)); - bzero((char*) &sort_param->unique, sizeof(sort_param->unique)); - sort_keys= (uchar **) NULL; + { /* Add extra block since DBUG_ENTER declare variables */ + DBUG_ENTER("thr_find_all_keys"); + DBUG_PRINT("enter", ("master: %d", sort_param->master)); + if (sort_param->sort_info->got_error) + goto err; - memavl= max(sort_param->sortbuff_size, MIN_SORT_MEMORY); - idx= sort_param->sort_info->max_records; - sort_length= sort_param->key_length; - maxbuffer= 1; - - while (memavl >= MIN_SORT_MEMORY) - { - if ((my_off_t) (idx+1)*(sort_length+sizeof(char*)) <= - (my_off_t) memavl) - keys= idx+1; + if (sort_param->keyinfo->flag & HA_VAR_LENGTH_KEY) + { + sort_param->write_keys= write_keys_varlen; + sort_param->read_to_buffer= read_to_buffer_varlen; + sort_param->write_key= write_merge_key_varlen; + } else { - uint skr; - do - { - skr=maxbuffer; - if (memavl < sizeof(BUFFPEK)*maxbuffer || - (keys=(memavl-sizeof(BUFFPEK)*maxbuffer)/ - (sort_length+sizeof(char*))) <= 1 || - keys < (uint) maxbuffer) - { - mi_check_print_error(sort_param->sort_info->param, - "sort_buffer_size is to small"); - goto err; - } - } - while ((maxbuffer= (int) (idx/(keys-1)+1)) != skr); + sort_param->write_keys= write_keys; + sort_param->read_to_buffer= read_to_buffer; + sort_param->write_key= write_merge_key; } - if ((sort_keys= (uchar**) - my_malloc(keys*(sort_length+sizeof(char*))+ - ((sort_param->keyinfo->flag & HA_FULLTEXT) ? - HA_FT_MAXBYTELEN : 0), MYF(0)))) + + my_b_clear(&sort_param->tempfile); + my_b_clear(&sort_param->tempfile_for_exceptions); + bzero((char*) &sort_param->buffpek, sizeof(sort_param->buffpek)); + bzero((char*) &sort_param->unique, sizeof(sort_param->unique)); + sort_keys= (uchar **) NULL; + + memavl= max(sort_param->sortbuff_size, MIN_SORT_MEMORY); + idx= sort_param->sort_info->max_records; + sort_length= sort_param->key_length; + maxbuffer= 1; + + while (memavl >= MIN_SORT_MEMORY) { - if (my_init_dynamic_array(&sort_param->buffpek, sizeof(BUFFPEK), - maxbuffer, maxbuffer/2)) - { - my_free((gptr) sort_keys,MYF(0)); - sort_keys= (uchar **) NULL; /* for err: label */ - } + if ((my_off_t) (idx+1)*(sort_length+sizeof(char*)) <= + (my_off_t) memavl) + keys= idx+1; else - break; + { + uint skr; + do + { + skr= maxbuffer; + if (memavl < sizeof(BUFFPEK)*maxbuffer || + (keys=(memavl-sizeof(BUFFPEK)*maxbuffer)/ + (sort_length+sizeof(char*))) <= 1 || + keys < (uint) maxbuffer) + { + mi_check_print_error(sort_param->sort_info->param, + "sort_buffer_size is to small"); + goto err; + } + } + while ((maxbuffer= (int) (idx/(keys-1)+1)) != skr); + } + if ((sort_keys= (uchar**) + my_malloc(keys*(sort_length+sizeof(char*))+ + ((sort_param->keyinfo->flag & HA_FULLTEXT) ? + HA_FT_MAXBYTELEN : 0), MYF(0)))) + { + if (my_init_dynamic_array(&sort_param->buffpek, sizeof(BUFFPEK), + maxbuffer, maxbuffer/2)) + { + my_free((gptr) sort_keys,MYF(0)); + sort_keys= (uchar **) NULL; /* for err: label */ + } + else + break; + } + old_memavl= memavl; + if ((memavl= memavl/4*3) < MIN_SORT_MEMORY && + old_memavl > MIN_SORT_MEMORY) + memavl= MIN_SORT_MEMORY; } - old_memavl=memavl; - if ((memavl=memavl/4*3) < MIN_SORT_MEMORY && old_memavl > MIN_SORT_MEMORY) - memavl=MIN_SORT_MEMORY; - } - if (memavl < MIN_SORT_MEMORY) - { - mi_check_print_error(sort_param->sort_info->param, "Sort buffer too small"); - goto err; /* purecov: tested */ - } - - if (sort_param->sort_info->param->testflag & T_VERBOSE) - printf("Key %d - Allocating buffer for %d keys\n", - sort_param->key + 1, keys); - sort_param->sort_keys= sort_keys; - - idx=error=0; - sort_keys[0]=(uchar*) (sort_keys+keys); - - DBUG_PRINT("info", ("reading keys")); - while (!(error= sort_param->sort_info->got_error) && - !(error= (*sort_param->key_read)(sort_param, sort_keys[idx]))) - { - if (sort_param->real_key_length > sort_param->key_length) + if (memavl < MIN_SORT_MEMORY) { - if (write_key(sort_param, sort_keys[idx], - &sort_param->tempfile_for_exceptions)) - goto err; - continue; + mi_check_print_error(sort_param->sort_info->param, + "Sort buffer too small"); + goto err; /* purecov: tested */ } - if (++idx == keys) + if (sort_param->sort_info->param->testflag & T_VERBOSE) + printf("Key %d - Allocating buffer for %d keys\n", + sort_param->key + 1, keys); + sort_param->sort_keys= sort_keys; + + idx= error= 0; + sort_keys[0]= (uchar*) (sort_keys+keys); + + DBUG_PRINT("info", ("reading keys")); + while (!(error= sort_param->sort_info->got_error) && + !(error= (*sort_param->key_read)(sort_param, sort_keys[idx]))) { - if (sort_param->write_keys(sort_param, sort_keys, idx - 1, + if (sort_param->real_key_length > sort_param->key_length) + { + if (write_key(sort_param, sort_keys[idx], + &sort_param->tempfile_for_exceptions)) + goto err; + continue; + } + + if (++idx == keys) + { + if (sort_param->write_keys(sort_param, sort_keys, idx - 1, + (BUFFPEK*) alloc_dynamic(&sort_param->buffpek), + &sort_param->tempfile)) + goto err; + sort_keys[0]= (uchar*) (sort_keys+keys); + memcpy(sort_keys[0], sort_keys[idx - 1], (size_t) sort_param->key_length); + idx= 1; + } + sort_keys[idx]= sort_keys[idx - 1] + sort_param->key_length; + } + if (error > 0) + goto err; + if (sort_param->buffpek.elements) + { + if (sort_param->write_keys(sort_param, sort_keys, idx, (BUFFPEK*) alloc_dynamic(&sort_param->buffpek), &sort_param->tempfile)) goto err; - sort_keys[0]=(uchar*) (sort_keys+keys); - memcpy(sort_keys[0], sort_keys[idx - 1], (size_t) sort_param->key_length); - idx=1; + sort_param->keys= (sort_param->buffpek.elements - 1) * (keys - 1) + idx; } - sort_keys[idx]= sort_keys[idx - 1] + sort_param->key_length; - } - if (error > 0) - goto err; - if (sort_param->buffpek.elements) - { - if (sort_param->write_keys(sort_param, sort_keys, idx, - (BUFFPEK*) alloc_dynamic(&sort_param->buffpek), - &sort_param->tempfile)) - goto err; - sort_param->keys= (sort_param->buffpek.elements - 1) * (keys - 1) + idx; - } - else - sort_param->keys= idx; + else + sort_param->keys= idx; - sort_param->sort_keys_length= keys; - goto ok; + sort_param->sort_keys_length= keys; + goto ok; err: - DBUG_PRINT("error", ("got some error")); - sort_param->sort_info->got_error= 1; /* no need to protect with a mutex */ - if (sort_keys) - my_free((gptr) sort_keys,MYF(0)); - sort_param->sort_keys= 0; - delete_dynamic(& sort_param->buffpek); - close_cached_file(&sort_param->tempfile); - close_cached_file(&sort_param->tempfile_for_exceptions); + DBUG_PRINT("error", ("got some error")); + sort_param->sort_info->got_error= 1; /* no need to protect with a mutex */ + if (sort_keys) + my_free((gptr) sort_keys,MYF(0)); + sort_param->sort_keys= 0; + delete_dynamic(& sort_param->buffpek); + close_cached_file(&sort_param->tempfile); + close_cached_file(&sort_param->tempfile_for_exceptions); ok: - /* - Detach from the share if the writer is involved. Avoid others to - be blocked. This includes a flush of the write buffer. This will - also indicate EOF to the readers. - */ - if (sort_param->sort_info->info->rec_cache.share) - remove_io_thread(&sort_param->sort_info->info->rec_cache); + /* + Detach from the share if the writer is involved. Avoid others to + be blocked. This includes a flush of the write buffer. This will + also indicate EOF to the readers. + */ + if (sort_param->sort_info->info->rec_cache.share) + remove_io_thread(&sort_param->sort_info->info->rec_cache); - /* Readers detach from the share if any. Avoid others to be blocked. */ - if (sort_param->read_cache.share) - remove_io_thread(&sort_param->read_cache); + /* Readers detach from the share if any. Avoid others to be blocked. */ + if (sort_param->read_cache.share) + remove_io_thread(&sort_param->read_cache); - pthread_mutex_lock(&sort_param->sort_info->mutex); - if (!--sort_param->sort_info->threads_running) - pthread_cond_signal(&sort_param->sort_info->cond); - pthread_mutex_unlock(&sort_param->sort_info->mutex); + pthread_mutex_lock(&sort_param->sort_info->mutex); + if (!--sort_param->sort_info->threads_running) + pthread_cond_signal(&sort_param->sort_info->cond); + pthread_mutex_unlock(&sort_param->sort_info->mutex); - DBUG_PRINT("exit", ("======== ending thread ========")); + DBUG_PRINT("exit", ("======== ending thread ========")); + } my_thread_end(); return NULL; } From e8c7f19179792e12877f9db5fbefea3bb7a26dce Mon Sep 17 00:00:00 2001 From: "msvensson@shellback.(none)" <> Date: Mon, 30 Oct 2006 13:35:57 +0100 Subject: [PATCH 2/2] Improve comments around FLUSH STATUS It's not possible to flush the global status variables in 5.0 Update test case so it works by recording the value of handle_rollback before and compare it to the value after --- mysql-test/r/innodb_mysql.result | 6 ++---- mysql-test/t/innodb_mysql.test | 9 +++++++-- sql/mysqld.cc | 10 +++++++++- sql/set_var.cc | 2 +- sql/sql_class.cc | 5 ++--- sql/sql_class.h | 9 +++++++-- 6 files changed, 28 insertions(+), 13 deletions(-) diff --git a/mysql-test/r/innodb_mysql.result b/mysql-test/r/innodb_mysql.result index bce5eff5d75..ef67104378c 100644 --- a/mysql-test/r/innodb_mysql.result +++ b/mysql-test/r/innodb_mysql.result @@ -104,14 +104,12 @@ SELECT `id1` FROM `t1` WHERE `id1` NOT IN (SELECT `id1` FROM `t2` WHERE `id2` = id1 2 DROP TABLE t1, t2; -flush status; create table t1 (c1 int) engine=innodb; handler t1 open; handler t1 read first; c1 -show /*!50002 GLOBAL */ status like 'Handler_rollback'; -Variable_name Value -Handler_rollback 0 +Before and after comparison +0 drop table t1; End of 4.1 tests create table t1m (a int) engine=myisam; diff --git a/mysql-test/t/innodb_mysql.test b/mysql-test/t/innodb_mysql.test index ff3089c98cf..73ae4845c06 100644 --- a/mysql-test/t/innodb_mysql.test +++ b/mysql-test/t/innodb_mysql.test @@ -119,7 +119,8 @@ SELECT `id1` FROM `t1` WHERE `id1` NOT IN (SELECT `id1` FROM `t2` WHERE `id2` = DROP TABLE t1, t2; # Bug #22728 - Handler_rollback value is growing # -flush status; + +let $before= `show /*!50002 GLOBAL */ status like 'Handler_rollback'`; create table t1 (c1 int) engine=innodb; connect (con1,localhost,root,,); connect (con2,localhost,root,,); @@ -128,7 +129,11 @@ handler t1 open; handler t1 read first; disconnect con2; connection con1; -show /*!50002 GLOBAL */ status like 'Handler_rollback'; +let $after= `show /*!50002 GLOBAL */ status like 'Handler_rollback'`; +# Compare the before and after value, it should be equal +--disable_query_log +eval select STRCMP("$before", "$after") as "Before and after comparison"; +--enable_query_log connection default; drop table t1; disconnect con1; diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 1dd15398cd1..c84e1f7ee56 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -5997,6 +5997,10 @@ The minimum value for this variable is 4096.", }; +/* + Variables shown by SHOW STATUS in alphabetical order +*/ + struct show_var_st status_vars[]= { {"Aborted_clients", (char*) &aborted_threads, SHOW_LONG}, {"Aborted_connects", (char*) &aborted_connects, SHOW_LONG}, @@ -7466,15 +7470,19 @@ void refresh_status(THD *thd) { pthread_mutex_lock(&LOCK_status); - /* We must update the global status before cleaning up the thread */ + /* Add thread's status variabes to global status */ add_to_status(&global_status_var, &thd->status_var); + + /* Reset thread's status variables */ bzero((char*) &thd->status_var, sizeof(thd->status_var)); + /* Reset some global variables */ for (struct show_var_st *ptr=status_vars; ptr->name; ptr++) { if (ptr->type == SHOW_LONG) *(ulong*) ptr->value= 0; } + /* Reset the counters of all key caches (default and named). */ process_key_caches(reset_key_cache_counters); pthread_mutex_unlock(&LOCK_status); diff --git a/sql/set_var.cc b/sql/set_var.cc index df0c69260e7..55c62a9a5a5 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -804,7 +804,7 @@ sys_var *sys_variables[]= /* - Variables shown by SHOW variables in alphabetical order + Variables shown by SHOW VARIABLES in alphabetical order */ struct show_var_st init_vars[]= { diff --git a/sql/sql_class.cc b/sql/sql_class.cc index f5bab1d17f4..ba2f525a4a4 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -464,14 +464,13 @@ THD::~THD() void add_to_status(STATUS_VAR *to_var, STATUS_VAR *from_var) { - ulong *end= (ulong*) ((byte*) to_var + offsetof(STATUS_VAR, - last_system_status_var) + + ulong *end= (ulong*) ((byte*) to_var + + offsetof(STATUS_VAR, last_system_status_var) + sizeof(ulong)); ulong *to= (ulong*) to_var, *from= (ulong*) from_var; while (to != end) *(to++)+= *(from++); - /* it doesn't make sense to add last_query_cost values */ } diff --git a/sql/sql_class.h b/sql/sql_class.h index 62cfb0119aa..c7bdfbd7ea7 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -646,12 +646,17 @@ typedef struct system_status_var ulong com_stmt_reset; ulong com_stmt_close; + /* + Status variables which it does not make sense to add to + global status variable counter + */ double last_query_cost; } STATUS_VAR; /* - This is used for 'show status'. It must be updated to the last ulong - variable in system_status_var + This is used for 'SHOW STATUS'. It must be updated to the last ulong + variable in system_status_var which is makes sens to add to the global + counter */ #define last_system_status_var com_stmt_close