diff options
author | Sergey Vojtovich <svoj@sun.com> | 2009-10-27 18:27:27 +0400 |
---|---|---|
committer | Sergey Vojtovich <svoj@sun.com> | 2009-10-27 18:27:27 +0400 |
commit | 578007404d91f96104e14392afb8a82709e6bd2f (patch) | |
tree | 6b118d10ea7262ea4721e82046f46e0da18b2f68 | |
parent | 6ceaf234bb9fa2e521c67568e1bd6f76ac890ee2 (diff) | |
download | mariadb-git-578007404d91f96104e14392afb8a82709e6bd2f.tar.gz |
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.
-rw-r--r-- | include/myisam.h | 4 | ||||
-rw-r--r-- | mysql-test/r/myisam.result | 6 | ||||
-rw-r--r-- | mysql-test/t/myisam.test | 12 | ||||
-rw-r--r-- | storage/myisam/ha_myisam.cc | 8 | ||||
-rw-r--r-- | storage/myisam/mi_check.c | 7 | ||||
-rw-r--r-- | storage/myisam/sort.c | 7 |
6 files changed, 37 insertions, 7 deletions
diff --git a/include/myisam.h b/include/myisam.h index 02251eeacb4..19b35538c65 100644 --- a/include/myisam.h +++ b/include/myisam.h @@ -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 diff --git a/mysql-test/r/myisam.result b/mysql-test/r/myisam.result index f5050ccf1c0..95fdc4fb93d 100644 --- a/mysql-test/r/myisam.result +++ b/mysql-test/r/myisam.result @@ -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 diff --git a/mysql-test/t/myisam.test b/mysql-test/t/myisam.test index e4ea939f348..56fe103adc9 100644 --- a/mysql-test/t/myisam.test +++ b/mysql-test/t/myisam.test @@ -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 diff --git a/storage/myisam/ha_myisam.cc b/storage/myisam/ha_myisam.cc index fce0e3325af..9c913b4f14d 100644 --- a/storage/myisam/ha_myisam.cc +++ b/storage/myisam/ha_myisam.cc @@ -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(¶m->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(¶m->print_msg_mutex); +#endif return; } diff --git a/storage/myisam/mi_check.c b/storage/myisam/mi_check.c index 8f7b1399aa2..c10cfdd0c9b 100644 --- a/storage/myisam/mi_check.c +++ b/storage/myisam/mi_check.c @@ -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(¶m->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 @@ err: pthread_cond_destroy (&sort_info.cond); pthread_mutex_destroy(&sort_info.mutex); + pthread_mutex_destroy(¶m->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)); diff --git a/storage/myisam/sort.c b/storage/myisam/sort.c index fb16af9cddf..b450d27de66 100644 --- a/storage/myisam/sort.c +++ b/storage/myisam/sort.c @@ -466,8 +466,12 @@ 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. + 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 @@ cleanup: 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; |