Commit db54eba3 authored by Sergey Vojtovich's avatar Sergey Vojtovich

A follow-up to fix for

BUG#47073 - valgrind errs, corruption,failed repair of partition,
            low myisam_sort_buffer_size

Fixed race conditions discovered with the provided test case and
stabilized test case.

include/myisam.h:
  Serialize submission of messages from multi-threaded REPAIR.
mysql-test/r/myisam.result:
  REPAIR output highly depend on threads activity. Disabled
  result log to make test case deterministic.
mysql-test/t/myisam.test:
  REPAIR output highly depend on threads activity. Disabled
  result log to make test case deterministic.
storage/myisam/ha_myisam.cc:
  Serialize submission of messages from multi-threaded REPAIR.
storage/myisam/mi_check.c:
  Serialize submission of messages from multi-threaded REPAIR.
storage/myisam/sort.c:
  Only master thread is allowed to detach write cache from
  the share.
parent 2b80974c
......@@ -432,6 +432,10 @@ typedef struct st_mi_check_param
const char *db_name, *table_name;
const char *op_name;
enum_mi_stats_method stats_method;
#ifdef THREAD
pthread_mutex_t print_msg_mutex;
my_bool need_print_msg_lock;
#endif
} MI_CHECK;
typedef struct st_sort_ft_buf
......
......@@ -2290,6 +2290,12 @@ Table Op Msg_type Msg_text
test.t1 repair error myisam_sort_buffer_size is too small
test.t1 repair warning Number of rows changed from 0 to 7168
test.t1 repair status OK
SET myisam_repair_threads=2;
REPAIR TABLE t1;
SET myisam_repair_threads=@@global.myisam_repair_threads;
SET myisam_sort_buffer_size=@@global.myisam_sort_buffer_size;
CHECK TABLE t1;
Table Op Msg_type Msg_text
test.t1 check status OK
DROP TABLE t1;
End of 5.1 tests
......@@ -1539,14 +1539,14 @@ INSERT INTO t1 SELECT a+5120,b FROM t1;
SET myisam_sort_buffer_size=4;
REPAIR TABLE t1;
# !!! Disabled until additional fix for BUG#47073 is pushed.
#SET myisam_repair_threads=2;
SET myisam_repair_threads=2;
# May report different values depending on threads activity.
#--replace_regex /changed from [0-9]+/changed from #/
#REPAIR TABLE t1;
#SET myisam_repair_threads=@@global.myisam_repair_threads;
--disable_result_log
REPAIR TABLE t1;
--enable_result_log
SET myisam_repair_threads=@@global.myisam_repair_threads;
SET myisam_sort_buffer_size=@@global.myisam_sort_buffer_size;
CHECK TABLE t1;
DROP TABLE t1;
--echo End of 5.1 tests
......
......@@ -115,6 +115,10 @@ static void mi_check_print_msg(MI_CHECK *param, const char* msg_type,
Also we likely need to lock mutex here (in both cases with protocol and
push_warning).
*/
#ifdef THREAD
if (param->need_print_msg_lock)
pthread_mutex_lock(&param->print_msg_mutex);
#endif
protocol->prepare_for_resend();
protocol->store(name, length, system_charset_info);
protocol->store(param->op_name, system_charset_info);
......@@ -123,6 +127,10 @@ static void mi_check_print_msg(MI_CHECK *param, const char* msg_type,
if (protocol->write())
sql_print_error("Failed on my_net_write, writing to stderr instead: %s\n",
msgbuf);
#ifdef THREAD
if (param->need_print_msg_lock)
pthread_mutex_unlock(&param->print_msg_mutex);
#endif
return;
}
......
......@@ -104,6 +104,9 @@ void myisamchk_init(MI_CHECK *param)
param->max_record_length= LONGLONG_MAX;
param->key_cache_block_size= KEY_CACHE_BLOCK_SIZE;
param->stats_method= MI_STATS_METHOD_NULLS_NOT_EQUAL;
#ifdef THREAD
param->need_print_msg_lock= 0;
#endif
}
/* Check the status flags for the table */
......@@ -2703,6 +2706,8 @@ int mi_repair_parallel(MI_CHECK *param, register MI_INFO *info,
/* Initialize pthread structures before goto err. */
pthread_mutex_init(&sort_info.mutex, MY_MUTEX_INIT_FAST);
pthread_cond_init(&sort_info.cond, 0);
pthread_mutex_init(&param->print_msg_mutex, MY_MUTEX_INIT_FAST);
param->need_print_msg_lock= 1;
if (!(sort_info.key_block=
alloc_key_blocks(param, (uint) param->sort_key_blocks,
......@@ -3108,6 +3113,8 @@ int mi_repair_parallel(MI_CHECK *param, register MI_INFO *info,
pthread_cond_destroy (&sort_info.cond);
pthread_mutex_destroy(&sort_info.mutex);
pthread_mutex_destroy(&param->print_msg_mutex);
param->need_print_msg_lock= 0;
my_free((uchar*) sort_info.ft_buf, MYF(MY_ALLOW_ZERO_PTR));
my_free((uchar*) sort_info.key_block,MYF(MY_ALLOW_ZERO_PTR));
......
......@@ -466,8 +466,12 @@ pthread_handler_t thr_find_all_keys(void *arg)
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.
That means that a writer always gets here first and readers -
only when they see EOF. But if a reader finishes prematurely
because of an error it may reach this earlier - don't allow it
to detach the writer thread.
*/
if (sort_param->sort_info->info->rec_cache.share)
if (sort_param->master && 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. */
......@@ -789,6 +793,7 @@ static int NEAR_F merge_many_buff(MI_SORT_PARAM *info, uint keys,
close_cached_file(to_file); /* This holds old result */
if (to_file == t_file)
{
DBUG_ASSERT(t_file2.type == WRITE_CACHE);
*t_file=t_file2; /* Copy result file */
t_file->current_pos= &t_file->write_pos;
t_file->current_end= &t_file->write_end;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment