summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNayuta Yanagisawa <nayuta.yanagisawa@hey.com>2022-01-11 21:57:11 +0900
committerNayuta Yanagisawa <nayuta.yanagisawa@hey.com>2022-01-13 18:16:25 +0900
commitf51cb16ed3ddddb05d7f02bda34f937d9c8fdb91 (patch)
tree8619d281811c5a0322925aad0eca38338b6f18f3
parent81e00485c3eb4be044bbca398f1a4e479ebcc3ac (diff)
downloadmariadb-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.cc129
-rw-r--r--storage/spider/ha_spider.h3
-rw-r--r--storage/spider/mysql-test/spider/bugfix/r/mdev_27240.result16
-rw-r--r--storage/spider/mysql-test/spider/bugfix/t/mdev_27240.cnf2
-rw-r--r--storage/spider/mysql-test/spider/bugfix/t/mdev_27240.test28
-rw-r--r--storage/spider/spd_include.h15
-rw-r--r--storage/spider/spd_table.cc48
-rw-r--r--storage/spider/spd_table.h2
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))
);