Merge shellback.(none):/home/msvensson/mysql/mysql-5.0-maint
into shellback.(none):/home/msvensson/mysql/mysql-5.1-maint mysql-test/mysql-test-run.pl: Auto merged mysql-test/r/innodb_mysql.result: Auto merged mysql-test/t/ctype_utf8.test: Auto merged mysql-test/include/mix1.inc: Auto merged sql/set_var.cc: Auto merged sql/sql_class.cc: Auto merged sql/sql_class.h: Auto merged sql/mysqld.cc: Manual merge storage/myisam/sort.c: Manual merge
This commit is contained in:
commit
2e35e44899
@ -149,7 +149,8 @@ DROP TABLE t1, t2;
|
|||||||
#
|
#
|
||||||
# Bug #22728 - Handler_rollback value is growing
|
# 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;
|
create table t1 (c1 int) engine=innodb;
|
||||||
connect (con1,localhost,root,,);
|
connect (con1,localhost,root,,);
|
||||||
connect (con2,localhost,root,,);
|
connect (con2,localhost,root,,);
|
||||||
@ -158,7 +159,11 @@ handler t1 open;
|
|||||||
handler t1 read first;
|
handler t1 read first;
|
||||||
disconnect con2;
|
disconnect con2;
|
||||||
connection con1;
|
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;
|
connection default;
|
||||||
drop table t1;
|
drop table t1;
|
||||||
disconnect con1;
|
disconnect con1;
|
||||||
|
@ -105,14 +105,12 @@ SELECT `id1` FROM `t1` WHERE `id1` NOT IN (SELECT `id1` FROM `t2` WHERE `id2` =
|
|||||||
id1
|
id1
|
||||||
2
|
2
|
||||||
DROP TABLE t1, t2;
|
DROP TABLE t1, t2;
|
||||||
flush status;
|
|
||||||
create table t1 (c1 int) engine=innodb;
|
create table t1 (c1 int) engine=innodb;
|
||||||
handler t1 open;
|
handler t1 open;
|
||||||
handler t1 read first;
|
handler t1 read first;
|
||||||
c1
|
c1
|
||||||
show /*!50002 GLOBAL */ status like 'Handler_rollback';
|
Before and after comparison
|
||||||
Variable_name Value
|
0
|
||||||
Handler_rollback 0
|
|
||||||
drop table t1;
|
drop table t1;
|
||||||
End of 4.1 tests
|
End of 4.1 tests
|
||||||
create table t1m (a int) engine = MEMORY;
|
create table t1m (a int) engine = MEMORY;
|
||||||
|
@ -6581,6 +6581,10 @@ static int show_ssl_get_cipher_list(THD *thd, SHOW_VAR *var, char *buff)
|
|||||||
#endif /* HAVE_OPENSSL */
|
#endif /* HAVE_OPENSSL */
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Variables shown by SHOW STATUS in alphabetical order
|
||||||
|
*/
|
||||||
|
|
||||||
SHOW_VAR status_vars[]= {
|
SHOW_VAR status_vars[]= {
|
||||||
{"Aborted_clients", (char*) &aborted_threads, SHOW_LONG},
|
{"Aborted_clients", (char*) &aborted_threads, SHOW_LONG},
|
||||||
{"Aborted_connects", (char*) &aborted_connects, SHOW_LONG},
|
{"Aborted_connects", (char*) &aborted_connects, SHOW_LONG},
|
||||||
@ -8088,16 +8092,20 @@ void refresh_status(THD *thd)
|
|||||||
{
|
{
|
||||||
pthread_mutex_lock(&LOCK_status);
|
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);
|
add_to_status(&global_status_var, &thd->status_var);
|
||||||
|
|
||||||
|
/* Reset thread's status variables */
|
||||||
bzero((char*) &thd->status_var, sizeof(thd->status_var));
|
bzero((char*) &thd->status_var, sizeof(thd->status_var));
|
||||||
|
|
||||||
|
/* Reset some global variables */
|
||||||
for (SHOW_VAR *ptr= status_vars; ptr->name; ptr++)
|
for (SHOW_VAR *ptr= status_vars; ptr->name; ptr++)
|
||||||
{
|
{
|
||||||
/* Note that SHOW_LONG_NOFLUSH variables are not reset */
|
/* Note that SHOW_LONG_NOFLUSH variables are not reset */
|
||||||
if (ptr->type == SHOW_LONG)
|
if (ptr->type == SHOW_LONG)
|
||||||
*(ulong*) ptr->value= 0;
|
*(ulong*) ptr->value= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Reset the counters of all key caches (default and named). */
|
/* Reset the counters of all key caches (default and named). */
|
||||||
process_key_caches(reset_key_cache_counters);
|
process_key_caches(reset_key_cache_counters);
|
||||||
pthread_mutex_unlock(&LOCK_status);
|
pthread_mutex_unlock(&LOCK_status);
|
||||||
|
@ -743,7 +743,7 @@ static int show_slave_skip_errors(THD *thd, SHOW_VAR *var, char *buff)
|
|||||||
#endif /* HAVE_REPLICATION */
|
#endif /* HAVE_REPLICATION */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Variables shown by SHOW variables in alphabetical order
|
Variables shown by SHOW VARIABLES in alphabetical order
|
||||||
*/
|
*/
|
||||||
|
|
||||||
SHOW_VAR init_vars[]= {
|
SHOW_VAR init_vars[]= {
|
||||||
|
@ -513,14 +513,13 @@ THD::~THD()
|
|||||||
|
|
||||||
void add_to_status(STATUS_VAR *to_var, STATUS_VAR *from_var)
|
void add_to_status(STATUS_VAR *to_var, STATUS_VAR *from_var)
|
||||||
{
|
{
|
||||||
ulong *end= (ulong*) ((byte*) to_var + offsetof(STATUS_VAR,
|
ulong *end= (ulong*) ((byte*) to_var +
|
||||||
last_system_status_var) +
|
offsetof(STATUS_VAR, last_system_status_var) +
|
||||||
sizeof(ulong));
|
sizeof(ulong));
|
||||||
ulong *to= (ulong*) to_var, *from= (ulong*) from_var;
|
ulong *to= (ulong*) to_var, *from= (ulong*) from_var;
|
||||||
|
|
||||||
while (to != end)
|
while (to != end)
|
||||||
*(to++)+= *(from++);
|
*(to++)+= *(from++);
|
||||||
/* it doesn't make sense to add last_query_cost values */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -337,12 +337,17 @@ typedef struct system_status_var
|
|||||||
ulong com_stmt_reset;
|
ulong com_stmt_reset;
|
||||||
ulong com_stmt_close;
|
ulong com_stmt_close;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Status variables which it does not make sense to add to
|
||||||
|
global status variable counter
|
||||||
|
*/
|
||||||
double last_query_cost;
|
double last_query_cost;
|
||||||
} STATUS_VAR;
|
} STATUS_VAR;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
This is used for 'show status'. It must be updated to the last ulong
|
This is used for 'SHOW STATUS'. It must be updated to the last ulong
|
||||||
variable in system_status_var
|
variable in system_status_var which is makes sens to add to the global
|
||||||
|
counter
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define last_system_status_var com_stmt_close
|
#define last_system_status_var com_stmt_close
|
||||||
|
@ -322,160 +322,165 @@ pthread_handler_t thr_find_all_keys(void *arg)
|
|||||||
|
|
||||||
if (my_thread_init())
|
if (my_thread_init())
|
||||||
goto err;
|
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);
|
{ /* Add extra block since DBUG_ENTER declare variables */
|
||||||
my_b_clear(&sort_param->tempfile_for_exceptions);
|
DBUG_ENTER("thr_find_all_keys");
|
||||||
bzero((char*) &sort_param->buffpek, sizeof(sort_param->buffpek));
|
DBUG_PRINT("enter", ("master: %d", sort_param->master));
|
||||||
bzero((char*) &sort_param->unique, sizeof(sort_param->unique));
|
if (sort_param->sort_info->got_error)
|
||||||
sort_keys= (uchar **) NULL;
|
goto err;
|
||||||
|
|
||||||
memavl= max(sort_param->sortbuff_size, MIN_SORT_MEMORY);
|
if (sort_param->keyinfo->flag & HA_VAR_LENGTH_KEY)
|
||||||
idx= sort_param->sort_info->max_records;
|
{
|
||||||
sort_length= sort_param->key_length;
|
sort_param->write_keys= write_keys_varlen;
|
||||||
maxbuffer= 1;
|
sort_param->read_to_buffer= read_to_buffer_varlen;
|
||||||
|
sort_param->write_key= write_merge_key_varlen;
|
||||||
while (memavl >= MIN_SORT_MEMORY)
|
}
|
||||||
{
|
|
||||||
if ((my_off_t) (idx+1)*(sort_length+sizeof(char*)) <=
|
|
||||||
(my_off_t) memavl)
|
|
||||||
keys= idx+1;
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
uint skr;
|
sort_param->write_keys= write_keys;
|
||||||
do
|
sort_param->read_to_buffer= read_to_buffer;
|
||||||
{
|
sort_param->write_key= write_merge_key;
|
||||||
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*))+
|
my_b_clear(&sort_param->tempfile);
|
||||||
((sort_param->keyinfo->flag & HA_FULLTEXT) ?
|
my_b_clear(&sort_param->tempfile_for_exceptions);
|
||||||
HA_FT_MAXBYTELEN : 0), MYF(0))))
|
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),
|
if ((my_off_t) (idx+1)*(sort_length+sizeof(char*)) <=
|
||||||
maxbuffer, maxbuffer/2))
|
(my_off_t) memavl)
|
||||||
{
|
keys= idx+1;
|
||||||
my_free((gptr) sort_keys,MYF(0));
|
|
||||||
sort_keys= (uchar **) NULL; /* for err: label */
|
|
||||||
}
|
|
||||||
else
|
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 < MIN_SORT_MEMORY)
|
||||||
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 (write_key(sort_param, sort_keys[idx],
|
mi_check_print_error(sort_param->sort_info->param,
|
||||||
&sort_param->tempfile_for_exceptions))
|
"Sort buffer too small");
|
||||||
goto err;
|
goto err; /* purecov: tested */
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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),
|
(BUFFPEK*) alloc_dynamic(&sort_param->buffpek),
|
||||||
&sort_param->tempfile))
|
&sort_param->tempfile))
|
||||||
goto err;
|
goto err;
|
||||||
sort_keys[0]=(uchar*) (sort_keys+keys);
|
sort_param->keys= (sort_param->buffpek.elements - 1) * (keys - 1) + idx;
|
||||||
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;
|
else
|
||||||
}
|
sort_param->keys= idx;
|
||||||
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;
|
|
||||||
|
|
||||||
sort_param->sort_keys_length= keys;
|
sort_param->sort_keys_length= keys;
|
||||||
goto ok;
|
goto ok;
|
||||||
|
|
||||||
err:
|
err:
|
||||||
DBUG_PRINT("error", ("got some error"));
|
DBUG_PRINT("error", ("got some error"));
|
||||||
sort_param->sort_info->got_error= 1; /* no need to protect with a mutex */
|
sort_param->sort_info->got_error= 1; /* no need to protect with a mutex */
|
||||||
if (sort_keys)
|
if (sort_keys)
|
||||||
my_free((gptr) sort_keys,MYF(0));
|
my_free((gptr) sort_keys,MYF(0));
|
||||||
sort_param->sort_keys= 0;
|
sort_param->sort_keys= 0;
|
||||||
delete_dynamic(& sort_param->buffpek);
|
delete_dynamic(& sort_param->buffpek);
|
||||||
close_cached_file(&sort_param->tempfile);
|
close_cached_file(&sort_param->tempfile);
|
||||||
close_cached_file(&sort_param->tempfile_for_exceptions);
|
close_cached_file(&sort_param->tempfile_for_exceptions);
|
||||||
|
|
||||||
ok:
|
ok:
|
||||||
free_root(&sort_param->wordroot, MYF(0));
|
free_root(&sort_param->wordroot, MYF(0));
|
||||||
/*
|
/*
|
||||||
Detach from the share if the writer is involved. Avoid others to
|
Detach from the share if the writer is involved. Avoid others to
|
||||||
be blocked. This includes a flush of the write buffer. This will
|
be blocked. This includes a flush of the write buffer. This will
|
||||||
also indicate EOF to the readers.
|
also indicate EOF to the readers.
|
||||||
*/
|
*/
|
||||||
if (sort_param->sort_info->info->rec_cache.share)
|
if (sort_param->sort_info->info->rec_cache.share)
|
||||||
remove_io_thread(&sort_param->sort_info->info->rec_cache);
|
remove_io_thread(&sort_param->sort_info->info->rec_cache);
|
||||||
|
|
||||||
/* Readers detach from the share if any. Avoid others to be blocked. */
|
/* Readers detach from the share if any. Avoid others to be blocked. */
|
||||||
if (sort_param->read_cache.share)
|
if (sort_param->read_cache.share)
|
||||||
remove_io_thread(&sort_param->read_cache);
|
remove_io_thread(&sort_param->read_cache);
|
||||||
|
|
||||||
pthread_mutex_lock(&sort_param->sort_info->mutex);
|
pthread_mutex_lock(&sort_param->sort_info->mutex);
|
||||||
if (!--sort_param->sort_info->threads_running)
|
if (!--sort_param->sort_info->threads_running)
|
||||||
pthread_cond_signal(&sort_param->sort_info->cond);
|
pthread_cond_signal(&sort_param->sort_info->cond);
|
||||||
pthread_mutex_unlock(&sort_param->sort_info->mutex);
|
pthread_mutex_unlock(&sort_param->sort_info->mutex);
|
||||||
|
DBUG_PRINT("exit", ("======== ending thread ========"));
|
||||||
DBUG_PRINT("exit", ("======== ending thread ========"));
|
}
|
||||||
my_thread_end();
|
my_thread_end();
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user