diff options
author | Nayuta Yanagisawa <nayuta.yanagisawa@hey.com> | 2022-01-11 21:57:11 +0900 |
---|---|---|
committer | Nayuta Yanagisawa <nayuta.yanagisawa@hey.com> | 2022-01-13 18:16:25 +0900 |
commit | f51cb16ed3ddddb05d7f02bda34f937d9c8fdb91 (patch) | |
tree | 8619d281811c5a0322925aad0eca38338b6f18f3 | |
parent | 81e00485c3eb4be044bbca398f1a4e479ebcc3ac (diff) | |
download | mariadb-git-bb-10.5-MDEV-27240-2.tar.gz |
MDEV-27240 SIGSEGV in ha_spider::store_lock on LOCK TABLEbb-10.5-MDEV-27240-2
The commit e954d9de gave different lifetime to wide_share and
partition_handler_share. This introduced the possibility that
partition_handler_share could be accessed even after it was freed.
We stop sharing partitoiin_handler_share and make it belongs to
a single wide_handler to fix the problem.
-rw-r--r-- | storage/spider/ha_spider.cc | 129 | ||||
-rw-r--r-- | storage/spider/ha_spider.h | 3 | ||||
-rw-r--r-- | storage/spider/mysql-test/spider/bugfix/r/mdev_27240.result | 16 | ||||
-rw-r--r-- | storage/spider/mysql-test/spider/bugfix/t/mdev_27240.cnf | 2 | ||||
-rw-r--r-- | storage/spider/mysql-test/spider/bugfix/t/mdev_27240.test | 28 | ||||
-rw-r--r-- | storage/spider/spd_include.h | 15 | ||||
-rw-r--r-- | storage/spider/spd_table.cc | 48 | ||||
-rw-r--r-- | storage/spider/spd_table.h | 2 |
8 files changed, 76 insertions, 167 deletions
diff --git a/storage/spider/ha_spider.cc b/storage/spider/ha_spider.cc index bbbe76cec74..f40fb2a34cc 100644 --- a/storage/spider/ha_spider.cc +++ b/storage/spider/ha_spider.cc @@ -89,7 +89,6 @@ ha_spider::ha_spider( search_link_query_id = 0; #ifdef WITH_PARTITION_STORAGE_ENGINE partition_handler_share = NULL; - pt_handler_share_owner = FALSE; #endif #ifdef HA_MRR_USE_DEFAULT_IMPL multi_range_keys = NULL; @@ -193,7 +192,6 @@ ha_spider::ha_spider( search_link_query_id = 0; #ifdef WITH_PARTITION_STORAGE_ENGINE partition_handler_share = NULL; - pt_handler_share_owner = FALSE; #endif #ifdef HA_MRR_USE_DEFAULT_IMPL multi_range_keys = NULL; @@ -280,11 +278,6 @@ ha_spider::~ha_spider() DBUG_ENTER("ha_spider::~ha_spider"); DBUG_PRINT("info",("spider this=%p", this)); #ifdef WITH_PARTITION_STORAGE_ENGINE - if (pt_handler_share_owner) - { - spider_free(spider_current_trx, partition_handler_share, MYF(0)); - pt_handler_share_owner = FALSE; - } partition_handler_share = NULL; #endif if (wide_handler_owner) @@ -343,13 +336,8 @@ int ha_spider::open( #ifdef WITH_PARTITION_STORAGE_ENGINE uint part_num; bool pt_handler_share_alloc = FALSE; - bool pt_handler_mutex = FALSE; ha_spider **pt_handler_share_handlers = NULL; ha_partition *clone_source; - ha_spider *pt_handler_share_key; -#ifdef SPIDER_HAS_HASH_VALUE_TYPE - my_hash_value_type hash_value; -#endif #endif DBUG_ENTER("ha_spider::open"); DBUG_PRINT("info",("spider this=%p", this)); @@ -367,11 +355,7 @@ int ha_spider::open( clone_source = ((ha_partition *) table->file)->get_clone_source(); if (clone_source) { - pt_handler_share_key = (ha_spider *) - clone_source->get_child_handlers()[0]; is_clone = TRUE; - } else { - pt_handler_share_key = spider; } } else { #endif @@ -379,7 +363,6 @@ int ha_spider::open( owner = this; #ifdef WITH_PARTITION_STORAGE_ENGINE clone_source = NULL; - pt_handler_share_key = this; } #endif if (!spider->wide_handler) @@ -408,6 +391,10 @@ int ha_spider::open( (uint) sizeof(uchar) * no_bytes_in_map(table->read_set), &rnd_write_bitmap, (uint) sizeof(uchar) * no_bytes_in_map(table->read_set), +#ifdef WITH_PARTITION_STORAGE_ENGINE + &partition_handler_share, + (uint) sizeof(SPIDER_PARTITION_HANDLER), +#endif NullS)) ) { error_num = HA_ERR_OUT_OF_MEM; @@ -422,6 +409,9 @@ int ha_spider::open( wide_handler->idx_write_bitmap = idx_write_bitmap; wide_handler->rnd_read_bitmap = rnd_read_bitmap; wide_handler->rnd_write_bitmap = rnd_write_bitmap; +#ifdef WITH_PARTITION_STORAGE_ENGINE + wide_handler->partition_handler_share= partition_handler_share; +#endif wide_handler->owner = owner; if (table_share->tmp_table == NO_TMP_TABLE) wide_handler->top_share = table->s; @@ -431,81 +421,39 @@ int ha_spider::open( memset(wide_handler->searched_bitmap, 0, no_bytes_in_map(table->read_set)); wide_handler_alloc = TRUE; - } else { - wide_handler = spider->wide_handler; - } + if (!share && !spider_get_share(name, table, thd, this, &error_num)) goto error_get_share; wide_share = share->wide_share; - if (wide_handler_alloc) - { - thr_lock_data_init(&wide_share->lock, &wide_handler->lock, NULL); - } #ifdef WITH_PARTITION_STORAGE_ENGINE - if (!wide_handler->partition_handler_share) - { - pt_handler_mutex = TRUE; - pthread_mutex_lock(&wide_share->pt_handler_mutex); -#ifdef SPIDER_HAS_HASH_VALUE_TYPE - hash_value = my_calc_hash(&wide_share->pt_handler_hash, - (uchar*) pt_handler_share_key, sizeof(ha_spider *)); - if (!(partition_handler_share = (SPIDER_PARTITION_HANDLER_SHARE*) - my_hash_search_using_hash_value(&wide_share->pt_handler_hash, - hash_value, (uchar*) pt_handler_share_key, sizeof(ha_spider *)))) -#else - if (!(partition_handler_share = (SPIDER_PARTITION_HANDLER_SHARE*) - my_hash_search(&wide_share->pt_handler_hash, - (uchar*) pt_handler_share_key, sizeof(ha_spider *)))) -#endif - { - if (!(partition_handler_share = (SPIDER_PARTITION_HANDLER_SHARE *) - spider_bulk_malloc(spider_current_trx, 15, MYF(MY_WME | MY_ZEROFILL), - &partition_handler_share, sizeof(SPIDER_PARTITION_HANDLER_SHARE), - NullS)) - ) { - error_num = HA_ERR_OUT_OF_MEM; - goto error_partition_handler_share_alloc; - } + DBUG_PRINT("info",("spider create partition_handler_share")); DBUG_PRINT("info",("spider table=%p", table)); partition_handler_share->table = table; - partition_handler_share->table_hash_value = hash_value; partition_handler_share->no_parts = part_num; partition_handler_share->owner = owner; partition_handler_share->parallel_search_query_id = 0; spider->partition_handler_share = partition_handler_share; owner->partition_handler_share = partition_handler_share; - owner->pt_handler_share_owner = TRUE; partition_handler_share->handlers = pt_handler_share_handlers; - uint old_elements = wide_share->pt_handler_hash.array.max_element; -#ifdef HASH_UPDATE_WITH_HASH_VALUE - if (my_hash_insert_with_hash_value(&wide_share->pt_handler_hash, - hash_value, (uchar*) partition_handler_share)) -#else - if (my_hash_insert(&wide_share->pt_handler_hash, - (uchar*) partition_handler_share)) -#endif - { - error_num = HA_ERR_OUT_OF_MEM; - goto error_hash_insert; - } - if (wide_share->pt_handler_hash.array.max_element > old_elements) - { - spider_alloc_calc_mem(spider_current_trx, - wide_share->pt_handler_hash, - (wide_share->pt_handler_hash.array.max_element - - old_elements) * - wide_share->pt_handler_hash.array.size_of_element); - } - } - pthread_mutex_unlock(&wide_share->pt_handler_mutex); - pt_handler_mutex = FALSE; + pt_handler_share_alloc = TRUE; } else { + wide_handler= spider->wide_handler; partition_handler_share = wide_handler->partition_handler_share; + + if (!share && !spider_get_share(name, table, thd, this, &error_num)) + goto error_get_share; + + wide_share= share->wide_share; } + if (wide_handler_alloc) + { + thr_lock_data_init(&wide_share->lock, &wide_handler->lock, NULL); + } + #endif init_sql_alloc_size = spider_param_init_sql_alloc_size(thd, share->init_sql_alloc_size); @@ -623,30 +571,12 @@ error_reset: error_init_blob_buff: error_init_result_list: #ifdef WITH_PARTITION_STORAGE_ENGINE -error_hash_insert: if (pt_handler_share_alloc) { wide_share = share->wide_share; - if (!pt_handler_mutex) - pthread_mutex_lock(&wide_share->pt_handler_mutex); -#ifdef HASH_UPDATE_WITH_HASH_VALUE - my_hash_delete_with_hash_value(&wide_share->pt_handler_hash, - partition_handler_share->table_hash_value, - (uchar*) partition_handler_share); -#else - my_hash_delete(&wide_share->pt_handler_hash, - (uchar*) partition_handler_share); -#endif - pthread_mutex_unlock(&wide_share->pt_handler_mutex); - pt_handler_mutex = FALSE; - spider_free(spider_current_trx, partition_handler_share, MYF(0)); spider->partition_handler_share = NULL; owner->partition_handler_share = NULL; - owner->pt_handler_share_owner = FALSE; } -error_partition_handler_share_alloc: - if (pt_handler_mutex) - pthread_mutex_unlock(&wide_share->pt_handler_mutex); partition_handler_share = NULL; #endif spider_free_share(share); @@ -679,7 +609,6 @@ int ha_spider::close() { int error_num = 0, roop_count, error_num2; THD *thd = ha_thd(); - SPIDER_WIDE_SHARE *wide_share; backup_error_status(); DBUG_ENTER("ha_spider::close"); DBUG_PRINT("info",("spider this=%p", this)); @@ -769,22 +698,6 @@ int ha_spider::close() conn_keys = NULL; } #ifdef WITH_PARTITION_STORAGE_ENGINE - if (pt_handler_share_owner) - { - wide_share = share->wide_share; - pthread_mutex_lock(&wide_share->pt_handler_mutex); -#ifdef HASH_UPDATE_WITH_HASH_VALUE - my_hash_delete_with_hash_value(&wide_share->pt_handler_hash, - partition_handler_share->table_hash_value, - (uchar*) partition_handler_share); -#else - my_hash_delete(&wide_share->pt_handler_hash, - (uchar*) partition_handler_share); -#endif - pthread_mutex_unlock(&wide_share->pt_handler_mutex); - spider_free(spider_current_trx, partition_handler_share, MYF(0)); - pt_handler_share_owner = FALSE; - } partition_handler_share = NULL; #endif if (wide_handler_owner) diff --git a/storage/spider/ha_spider.h b/storage/spider/ha_spider.h index 5bc58397f28..9e46b13f00d 100644 --- a/storage/spider/ha_spider.h +++ b/storage/spider/ha_spider.h @@ -92,8 +92,7 @@ public: SPIDER_POSITION *pushed_pos; SPIDER_POSITION pushed_pos_buf; #ifdef WITH_PARTITION_STORAGE_ENGINE - bool pt_handler_share_owner = FALSE; - SPIDER_PARTITION_HANDLER_SHARE *partition_handler_share; + SPIDER_PARTITION_HANDLER *partition_handler_share; #endif bool wide_handler_owner = FALSE; SPIDER_WIDE_HANDLER *wide_handler = NULL; diff --git a/storage/spider/mysql-test/spider/bugfix/r/mdev_27240.result b/storage/spider/mysql-test/spider/bugfix/r/mdev_27240.result new file mode 100644 index 00000000000..9dd247337ee --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_27240.result @@ -0,0 +1,16 @@ +for master_1 +for child2 +for child3 +CREATE DATABASE auto_test_local; +USE auto_test_local; +CREATE TABLE tbl_a (a INT KEY) ENGINE=SPIDER; +SELECT a.z FROM tbl_a AS a,tbl_a b WHERE a.z=b.z; +ERROR 42S22: Unknown column 'a.z' in 'field list' +ALTER TABLE tbl_a CHANGE c c INT; +ERROR 42S22: Unknown column 'c' in 'tbl_a' +LOCK TABLE tbl_a READ; +ERROR HY000: Unable to connect to foreign data source: localhost +DROP DATABASE auto_test_local; +for master_1 +for child2 +for child3 diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_27240.cnf b/storage/spider/mysql-test/spider/bugfix/t/mdev_27240.cnf new file mode 100644 index 00000000000..b0853e32654 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_27240.cnf @@ -0,0 +1,2 @@ +!include include/default_mysqld.cnf +!include ../my_1_1.cnf diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_27240.test b/storage/spider/mysql-test/spider/bugfix/t/mdev_27240.test new file mode 100644 index 00000000000..552ce3aa6de --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_27240.test @@ -0,0 +1,28 @@ +--disable_warnings +--disable_query_log +--disable_result_log +--source ../../t/test_init.inc +--enable_result_log +--enable_query_log +--enable_warnings + +CREATE DATABASE auto_test_local; +USE auto_test_local; + +CREATE TABLE tbl_a (a INT KEY) ENGINE=SPIDER; +--error ER_BAD_FIELD_ERROR +SELECT a.z FROM tbl_a AS a,tbl_a b WHERE a.z=b.z; +--error ER_BAD_FIELD_ERROR +ALTER TABLE tbl_a CHANGE c c INT; +--error ER_CONNECT_TO_FOREIGN_DATA_SOURCE +LOCK TABLE tbl_a READ; + +DROP DATABASE auto_test_local; + +--disable_warnings +--disable_query_log +--disable_result_log +--source ../../t/test_deinit.inc +--enable_result_log +--enable_query_log +--enable_warnings diff --git a/storage/spider/spd_include.h b/storage/spider/spd_include.h index bf6c415b745..6d24e3d1908 100644 --- a/storage/spider/spd_include.h +++ b/storage/spider/spd_include.h @@ -676,18 +676,15 @@ typedef struct st_spider_lgtm_tblhnd_share } SPIDER_LGTM_TBLHND_SHARE; #ifdef WITH_PARTITION_STORAGE_ENGINE -typedef struct st_spider_patition_handler_share +typedef struct st_spider_patition_handler { bool clone_bitmap_init; -#ifdef SPIDER_HAS_HASH_VALUE_TYPE - my_hash_value_type table_hash_value; -#endif query_id_t parallel_search_query_id; uint no_parts; TABLE *table; ha_spider *owner; ha_spider **handlers; -} SPIDER_PARTITION_HANDLER_SHARE; +} SPIDER_PARTITION_HANDLER; #endif typedef struct st_spider_wide_share @@ -701,12 +698,6 @@ typedef struct st_spider_wide_share THR_LOCK lock; pthread_mutex_t sts_mutex; pthread_mutex_t crd_mutex; - pthread_mutex_t pt_handler_mutex; - HASH pt_handler_hash; - uint pt_handler_hash_id; - const char *pt_handler_hash_func_name; - const char *pt_handler_hash_file_name; - ulong pt_handler_hash_line_no; volatile bool sts_init; volatile bool crd_init; @@ -751,7 +742,7 @@ typedef struct st_spider_wide_handler #endif #endif #ifdef WITH_PARTITION_STORAGE_ENGINE - SPIDER_PARTITION_HANDLER_SHARE *partition_handler_share; + SPIDER_PARTITION_HANDLER *partition_handler_share; #endif #ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS List<Item> *direct_update_fields; diff --git a/storage/spider/spd_table.cc b/storage/spider/spd_table.cc index 8efa5d2551d..b3d8e705905 100644 --- a/storage/spider/spd_table.cc +++ b/storage/spider/spd_table.cc @@ -432,7 +432,7 @@ uchar *spider_wide_share_get_key( #ifdef WITH_PARTITION_STORAGE_ENGINE uchar *spider_pt_handler_share_get_key( - SPIDER_PARTITION_HANDLER_SHARE *share, + SPIDER_PARTITION_HANDLER *share, size_t *length, my_bool not_used __attribute__ ((unused)) ) { @@ -6436,34 +6436,8 @@ SPIDER_WIDE_SHARE *spider_get_wide_share( goto error_init_crd_mutex; } -#if MYSQL_VERSION_ID < 50500 - if (pthread_mutex_init(&wide_share->pt_handler_mutex, - MY_MUTEX_INIT_FAST)) -#else - if (mysql_mutex_init(spd_key_mutex_pt_handler, - &wide_share->pt_handler_mutex, MY_MUTEX_INIT_FAST)) -#endif - { - *error_num = HA_ERR_OUT_OF_MEM; - goto error_init_pt_handler_mutex; - } - - if( - my_hash_init(PSI_INSTRUMENT_ME, &wide_share->pt_handler_hash, spd_charset_utf8mb3_bin, - 32, 0, 0, (my_hash_get_key) spider_pt_handler_share_get_key, 0, 0) - ) { - *error_num = HA_ERR_OUT_OF_MEM; - goto error_init_pt_handler_hash; - } - thr_lock_init(&wide_share->lock); - spider_alloc_calc_mem_init(wide_share->pt_handler_hash, 142); - spider_alloc_calc_mem(spider_current_trx, - wide_share->pt_handler_hash, - wide_share->pt_handler_hash.array.max_element * - wide_share->pt_handler_hash.array.size_of_element); - uint old_elements = spider_open_wide_share.array.max_element; #ifdef HASH_UPDATE_WITH_HASH_VALUE if (my_hash_insert_with_hash_value(&spider_open_wide_share, @@ -6491,14 +6465,6 @@ SPIDER_WIDE_SHARE *spider_get_wide_share( DBUG_RETURN(wide_share); error_hash_insert: - spider_free_mem_calc(spider_current_trx, - wide_share->pt_handler_hash_id, - wide_share->pt_handler_hash.array.max_element * - wide_share->pt_handler_hash.array.size_of_element); - my_hash_free(&wide_share->pt_handler_hash); -error_init_pt_handler_hash: - pthread_mutex_destroy(&wide_share->pt_handler_mutex); -error_init_pt_handler_mutex: pthread_mutex_destroy(&wide_share->crd_mutex); error_init_crd_mutex: pthread_mutex_destroy(&wide_share->sts_mutex); @@ -6523,12 +6489,6 @@ int spider_free_wide_share( #else my_hash_delete(&spider_open_wide_share, (uchar*) wide_share); #endif - spider_free_mem_calc(spider_current_trx, - wide_share->pt_handler_hash_id, - wide_share->pt_handler_hash.array.max_element * - wide_share->pt_handler_hash.array.size_of_element); - my_hash_free(&wide_share->pt_handler_hash); - pthread_mutex_destroy(&wide_share->pt_handler_mutex); pthread_mutex_destroy(&wide_share->crd_mutex); pthread_mutex_destroy(&wide_share->sts_mutex); spider_free(spider_current_trx, wide_share, MYF(0)); @@ -8036,7 +7996,7 @@ int spider_get_sts( if (error_num) { #ifdef WITH_PARTITION_STORAGE_ENGINE - SPIDER_PARTITION_HANDLER_SHARE *partition_handler_share = + SPIDER_PARTITION_HANDLER *partition_handler_share = spider->partition_handler_share; if ( !share->wide_share->sts_init && @@ -8187,7 +8147,7 @@ int spider_get_crd( if (error_num) { #ifdef WITH_PARTITION_STORAGE_ENGINE - SPIDER_PARTITION_HANDLER_SHARE *partition_handler_share = + SPIDER_PARTITION_HANDLER *partition_handler_share = spider->partition_handler_share; if ( !share->wide_share->crd_init && @@ -9349,7 +9309,7 @@ int spider_set_direct_limit_offset( if ( spider->partition_handler_share && - !spider->pt_handler_share_owner + !spider->wide_handler_owner ) { if (spider->partition_handler_share->owner-> result_list.direct_limit_offset == TRUE) diff --git a/storage/spider/spd_table.h b/storage/spider/spd_table.h index 2b40fb33d5a..5abf480ca55 100644 --- a/storage/spider/spd_table.h +++ b/storage/spider/spd_table.h @@ -321,7 +321,7 @@ uchar *spider_wide_share_get_key( #ifdef WITH_PARTITION_STORAGE_ENGINE uchar *spider_pt_handler_share_get_key( - SPIDER_PARTITION_HANDLER_SHARE *share, + SPIDER_PARTITION_HANDLER *share, size_t *length, my_bool not_used __attribute__ ((unused)) ); |