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 ...@@ -432,6 +432,10 @@ typedef struct st_mi_check_param
const char *db_name, *table_name; const char *db_name, *table_name;
const char *op_name; const char *op_name;
enum_mi_stats_method stats_method; enum_mi_stats_method stats_method;
#ifdef THREAD
pthread_mutex_t print_msg_mutex;
my_bool need_print_msg_lock;
#endif
} MI_CHECK; } MI_CHECK;
typedef struct st_sort_ft_buf typedef struct st_sort_ft_buf
......
...@@ -2290,6 +2290,12 @@ Table Op Msg_type Msg_text ...@@ -2290,6 +2290,12 @@ Table Op Msg_type Msg_text
test.t1 repair error myisam_sort_buffer_size is too small 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 warning Number of rows changed from 0 to 7168
test.t1 repair status OK 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; 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; DROP TABLE t1;
End of 5.1 tests End of 5.1 tests
...@@ -1539,14 +1539,14 @@ INSERT INTO t1 SELECT a+5120,b FROM t1; ...@@ -1539,14 +1539,14 @@ INSERT INTO t1 SELECT a+5120,b FROM t1;
SET myisam_sort_buffer_size=4; SET myisam_sort_buffer_size=4;
REPAIR TABLE t1; 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. # May report different values depending on threads activity.
#--replace_regex /changed from [0-9]+/changed from #/ --disable_result_log
#REPAIR TABLE t1; REPAIR TABLE t1;
#SET myisam_repair_threads=@@global.myisam_repair_threads; --enable_result_log
SET myisam_repair_threads=@@global.myisam_repair_threads;
SET myisam_sort_buffer_size=@@global.myisam_sort_buffer_size; SET myisam_sort_buffer_size=@@global.myisam_sort_buffer_size;
CHECK TABLE t1;
DROP TABLE t1; DROP TABLE t1;
--echo End of 5.1 tests --echo End of 5.1 tests
......
...@@ -115,6 +115,10 @@ static void mi_check_print_msg(MI_CHECK *param, const char* msg_type, ...@@ -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 Also we likely need to lock mutex here (in both cases with protocol and
push_warning). push_warning).
*/ */
#ifdef THREAD
if (param->need_print_msg_lock)
pthread_mutex_lock(&param->print_msg_mutex);
#endif
protocol->prepare_for_resend(); protocol->prepare_for_resend();
protocol->store(name, length, system_charset_info); protocol->store(name, length, system_charset_info);
protocol->store(param->op_name, 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, ...@@ -123,6 +127,10 @@ static void mi_check_print_msg(MI_CHECK *param, const char* msg_type,
if (protocol->write()) if (protocol->write())
sql_print_error("Failed on my_net_write, writing to stderr instead: %s\n", sql_print_error("Failed on my_net_write, writing to stderr instead: %s\n",
msgbuf); msgbuf);
#ifdef THREAD
if (param->need_print_msg_lock)
pthread_mutex_unlock(&param->print_msg_mutex);
#endif
return; return;
} }
......
...@@ -104,6 +104,9 @@ void myisamchk_init(MI_CHECK *param) ...@@ -104,6 +104,9 @@ void myisamchk_init(MI_CHECK *param)
param->max_record_length= LONGLONG_MAX; param->max_record_length= LONGLONG_MAX;
param->key_cache_block_size= KEY_CACHE_BLOCK_SIZE; param->key_cache_block_size= KEY_CACHE_BLOCK_SIZE;
param->stats_method= MI_STATS_METHOD_NULLS_NOT_EQUAL; 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 */ /* Check the status flags for the table */
...@@ -2703,6 +2706,8 @@ int mi_repair_parallel(MI_CHECK *param, register MI_INFO *info, ...@@ -2703,6 +2706,8 @@ int mi_repair_parallel(MI_CHECK *param, register MI_INFO *info,
/* Initialize pthread structures before goto err. */ /* Initialize pthread structures before goto err. */
pthread_mutex_init(&sort_info.mutex, MY_MUTEX_INIT_FAST); pthread_mutex_init(&sort_info.mutex, MY_MUTEX_INIT_FAST);
pthread_cond_init(&sort_info.cond, 0); 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= if (!(sort_info.key_block=
alloc_key_blocks(param, (uint) param->sort_key_blocks, alloc_key_blocks(param, (uint) param->sort_key_blocks,
...@@ -3108,6 +3113,8 @@ int mi_repair_parallel(MI_CHECK *param, register MI_INFO *info, ...@@ -3108,6 +3113,8 @@ int mi_repair_parallel(MI_CHECK *param, register MI_INFO *info,
pthread_cond_destroy (&sort_info.cond); pthread_cond_destroy (&sort_info.cond);
pthread_mutex_destroy(&sort_info.mutex); 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.ft_buf, MYF(MY_ALLOW_ZERO_PTR));
my_free((uchar*) sort_info.key_block,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) ...@@ -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 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.
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); 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. */
...@@ -789,6 +793,7 @@ static int NEAR_F merge_many_buff(MI_SORT_PARAM *info, uint keys, ...@@ -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 */ close_cached_file(to_file); /* This holds old result */
if (to_file == t_file) if (to_file == t_file)
{ {
DBUG_ASSERT(t_file2.type == WRITE_CACHE);
*t_file=t_file2; /* Copy result file */ *t_file=t_file2; /* Copy result file */
t_file->current_pos= &t_file->write_pos; t_file->current_pos= &t_file->write_pos;
t_file->current_end= &t_file->write_end; 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