diff options
author | Nayuta Yanagisawa <nayuta.yanagisawa@hey.com> | 2021-10-13 22:45:26 +0900 |
---|---|---|
committer | Nayuta Yanagisawa <nayuta.yanagisawa@hey.com> | 2022-06-29 22:40:56 +0900 |
commit | 0bc343ad201431923615b2dbf8fc1f6fcf887299 (patch) | |
tree | 1e2a96118ba6545198b0c37b093f95bf21741e5d | |
parent | f339ef3f9793d5de8f825f1ec6489550b98e7e9a (diff) | |
download | mariadb-git-bb-10.3-mdev-26544_3.tar.gz |
MDEV-26544 Assertion `part_share->auto_inc_initialized' failed in ha_partition::get_auto_increment on INSERTbb-10.3-mdev-26544_3
The partition storage engine ignores return (error) values of
handler::info(). As a result, a query that should be aborted is
not aborted and then the server violates the assertion.
-rw-r--r-- | sql/ha_partition.cc | 38 | ||||
-rw-r--r-- | sql/ha_partition.h | 2 | ||||
-rw-r--r-- | storage/spider/mysql-test/spider/bugfix/r/mdev_26544.result | 23 | ||||
-rw-r--r-- | storage/spider/mysql-test/spider/bugfix/t/mdev_26544.cnf | 2 | ||||
-rw-r--r-- | storage/spider/mysql-test/spider/bugfix/t/mdev_26544.test | 32 |
5 files changed, 82 insertions, 15 deletions
diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index 5c08c934dde..fd52fc42904 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -4339,7 +4339,7 @@ void ha_partition::try_semi_consistent_read(bool yes) int ha_partition::write_row(uchar * buf) { uint32 part_id; - int error; + int error= 0; longlong func_value; bool have_auto_increment= table->next_number_field && buf == table->record[0]; MY_BITMAP *old_map; @@ -4356,15 +4356,15 @@ int ha_partition::write_row(uchar * buf) if (have_auto_increment) { if (!table_share->next_number_keypart) - update_next_auto_inc_val(); - error= update_auto_increment(); + if (unlikely(error= update_next_auto_inc_val())) + goto exit; /* If we have failed to set the auto-increment value for this row, it is highly likely that we will not be able to insert it into the correct partition. We must check and fail if necessary. */ - if (unlikely(error)) + if (unlikely(error= update_auto_increment())) goto exit; /* @@ -8304,6 +8304,7 @@ int ha_partition::compare_number_of_records(ha_partition *me, int ha_partition::info(uint flag) { + int error= 0; uint no_lock_flag= flag & HA_STATUS_NO_LOCK; uint extra_var_flag= flag & HA_STATUS_VARIABLE_EXTRA; DBUG_ENTER("ha_partition::info"); @@ -8356,7 +8357,11 @@ int ha_partition::info(uint flag) break; } file= *file_array; - file->info(HA_STATUS_AUTO | no_lock_flag); + if ((error= file->info(HA_STATUS_AUTO | no_lock_flag))) + { + unlock_auto_increment(); + DBUG_RETURN(error); + } set_if_bigger(auto_increment_value, file->stats.auto_increment_value); } while (*(++file_array)); @@ -8412,7 +8417,8 @@ int ha_partition::info(uint flag) i= bitmap_get_next_set(&m_part_info->read_partitions, i)) { file= m_file[i]; - file->info(HA_STATUS_VARIABLE | no_lock_flag | extra_var_flag); + if ((error= file->info(HA_STATUS_VARIABLE | no_lock_flag | extra_var_flag))) + DBUG_RETURN(error); stats.records+= file->stats.records; stats.deleted+= file->stats.deleted; stats.data_file_length+= file->stats.data_file_length; @@ -8497,7 +8503,8 @@ int ha_partition::info(uint flag) if (!(flag & HA_STATUS_VARIABLE) || !bitmap_is_set(&(m_part_info->read_partitions), (uint) (file_array - m_file))) - file->info(HA_STATUS_VARIABLE | no_lock_flag | extra_var_flag); + if ((error= file->info(HA_STATUS_VARIABLE | no_lock_flag | extra_var_flag))) + DBUG_RETURN(error); if (file->stats.records > max_records || !handler_instance_set) { handler_instance_set= 1; @@ -8518,7 +8525,8 @@ int ha_partition::info(uint flag) this); file= m_file[handler_instance]; - file->info(HA_STATUS_CONST | no_lock_flag); + if ((error= file->info(HA_STATUS_CONST | no_lock_flag))) + DBUG_RETURN(error); stats.block_size= file->stats.block_size; stats.create_time= file->stats.create_time; ref_length= m_ref_length; @@ -8534,7 +8542,8 @@ int ha_partition::info(uint flag) Note: all engines does not support HA_STATUS_ERRKEY, so set errkey. */ file->errkey= errkey; - file->info(HA_STATUS_ERRKEY | no_lock_flag); + if ((error= file->info(HA_STATUS_ERRKEY | no_lock_flag))) + DBUG_RETURN(error); errkey= file->errkey; } if (flag & HA_STATUS_TIME) @@ -8551,7 +8560,8 @@ int ha_partition::info(uint flag) do { file= *file_array; - file->info(HA_STATUS_TIME | no_lock_flag); + if ((error= file->info(HA_STATUS_TIME | no_lock_flag))) + DBUG_RETURN(error); if (file->stats.update_time > stats.update_time) stats.update_time= file->stats.update_time; } while (*(++file_array)); @@ -10526,11 +10536,11 @@ int ha_partition::cmp_ref(const uchar *ref1, const uchar *ref2) the underlying partitions require that the value should be re-calculated */ -void ha_partition::update_next_auto_inc_val() +int ha_partition::update_next_auto_inc_val() { - if (!part_share->auto_inc_initialized || - need_info_for_auto_inc()) - info(HA_STATUS_AUTO); + if (!part_share->auto_inc_initialized || need_info_for_auto_inc()) + return info(HA_STATUS_AUTO); + return 0; } diff --git a/sql/ha_partition.h b/sql/ha_partition.h index 6c0e4ef6cf2..590ec73cc69 100644 --- a/sql/ha_partition.h +++ b/sql/ha_partition.h @@ -1361,7 +1361,7 @@ public: virtual void release_auto_increment(); private: virtual int reset_auto_increment(ulonglong value); - void update_next_auto_inc_val(); + int update_next_auto_inc_val(); virtual void lock_auto_increment() { /* lock already taken */ diff --git a/storage/spider/mysql-test/spider/bugfix/r/mdev_26544.result b/storage/spider/mysql-test/spider/bugfix/r/mdev_26544.result new file mode 100644 index 00000000000..b3d5facc202 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_26544.result @@ -0,0 +1,23 @@ +# +# MDEV-26544 Assertion `part_share->auto_inc_initialized' failed in ha_partition::get_auto_increment on INSERT +# +for master_1 +for child2 +for child3 +connection master_1; +CREATE DATABASE auto_test_remote; +USE auto_test_remote; +CREATE TABLE `tbl_a` ( +`a` INT AUTO_INCREMENT, KEY(`a`) +) ENGINE=Spider DEFAULT CHARSET=utf8 +PARTITION BY LIST COLUMNS (`a`) ( +PARTITION `pt1` DEFAULT +); +INSERT INTO tbl_a (a) VALUES (0); +ERROR HY000: Unable to connect to foreign data source: localhost +INSERT INTO tbl_a () VALUES (); +ERROR HY000: Unable to connect to foreign data source: localhost +DROP DATABASE IF EXISTS auto_test_remote; +for master_1 +for child2 +for child3 diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_26544.cnf b/storage/spider/mysql-test/spider/bugfix/t/mdev_26544.cnf new file mode 100644 index 00000000000..b0853e32654 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_26544.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_26544.test b/storage/spider/mysql-test/spider/bugfix/t/mdev_26544.test new file mode 100644 index 00000000000..ac2b68988c0 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_26544.test @@ -0,0 +1,32 @@ +--echo # +--echo # MDEV-26544 Assertion `part_share->auto_inc_initialized' failed in ha_partition::get_auto_increment on INSERT +--echo # + +--disable_query_log +--disable_result_log +--source ../../t/test_init.inc +--enable_result_log +--enable_query_log + +--connection master_1 +CREATE DATABASE auto_test_remote; +USE auto_test_remote; + +eval CREATE TABLE `tbl_a` ( + `a` INT AUTO_INCREMENT, KEY(`a`) +) $MASTER_1_ENGINE $MASTER_1_CHARSET +PARTITION BY LIST COLUMNS (`a`) ( + PARTITION `pt1` DEFAULT +); +--error ER_CONNECT_TO_FOREIGN_DATA_SOURCE +INSERT INTO tbl_a (a) VALUES (0); +--error ER_CONNECT_TO_FOREIGN_DATA_SOURCE +INSERT INTO tbl_a () VALUES (); + +DROP DATABASE IF EXISTS auto_test_remote; + +--disable_query_log +--disable_result_log +--source ../../t/test_deinit.inc +--enable_result_log +--enable_query_log |