Commit 6dce6aec authored by Alexey Botchkov's avatar Alexey Botchkov

MDEV-18244 Server crashes in ha_innobase::update_thd / ... /...

MDEV-18244 Server crashes in ha_innobase::update_thd / ... / ha_partition::update_next_auto_inc_val.

Partition table with the AUTO_INCREMENT column we ahve to check if the
max value is properly loaded. So we need to open all tables in INSERT
PARTITION statement if necessary. Also we need to check if some
tables are pruned away and not count the max autoincrement in this case.
parent 55b2281a
...@@ -1028,5 +1028,29 @@ COUNT(*) ...@@ -1028,5 +1028,29 @@ COUNT(*)
2 2
DROP TABLE t1; DROP TABLE t1;
# #
# MDEV-18244 Server crashes in ha_innobase::update_thd / ... / ha_partition::update_next_auto_inc_val
#
CREATE TABLE t1 (a INT)
ENGINE=InnoDB
PARTITION BY RANGE (a) (
PARTITION p0 VALUES LESS THAN (6),
PARTITION pn VALUES LESS THAN MAXVALUE
);
INSERT INTO t1 VALUES (4),(5),(6);
ALTER TABLE t1 MODIFY a INT AUTO_INCREMENT PRIMARY KEY;
UPDATE t1 PARTITION (p0) SET a = 3 WHERE a = 5;
INSERT INTO t1 PARTITION(p0) VALUES ();
ERROR HY000: Found a row not matching the given partition set
INSERT INTO t1 PARTITION(p0) VALUES (-1);
INSERT INTO t1 VALUES ();
SELECT * FROM t1;
a
-1
1
3
4
6
DROP TABLE t1;
#
# End of 10.3 tests # End of 10.3 tests
# #
...@@ -1105,6 +1105,26 @@ INSERT INTO t1 VALUES (1, 7, 8, 9), (2, NULL, NULL, NULL), (3, NULL, NULL, NULL) ...@@ -1105,6 +1105,26 @@ INSERT INTO t1 VALUES (1, 7, 8, 9), (2, NULL, NULL, NULL), (3, NULL, NULL, NULL)
SELECT COUNT(*) FROM t1 WHERE x IS NULL AND y IS NULL AND z IS NULL; SELECT COUNT(*) FROM t1 WHERE x IS NULL AND y IS NULL AND z IS NULL;
DROP TABLE t1; DROP TABLE t1;
--echo #
--echo # MDEV-18244 Server crashes in ha_innobase::update_thd / ... / ha_partition::update_next_auto_inc_val
--echo #
CREATE TABLE t1 (a INT)
ENGINE=InnoDB
PARTITION BY RANGE (a) (
PARTITION p0 VALUES LESS THAN (6),
PARTITION pn VALUES LESS THAN MAXVALUE
);
INSERT INTO t1 VALUES (4),(5),(6);
ALTER TABLE t1 MODIFY a INT AUTO_INCREMENT PRIMARY KEY;
UPDATE t1 PARTITION (p0) SET a = 3 WHERE a = 5;
--error ER_ROW_DOES_NOT_MATCH_GIVEN_PARTITION_SET
INSERT INTO t1 PARTITION(p0) VALUES ();
INSERT INTO t1 PARTITION(p0) VALUES (-1);
INSERT INTO t1 VALUES ();
SELECT * FROM t1;
DROP TABLE t1;
--echo # --echo #
--echo # End of 10.3 tests --echo # End of 10.3 tests
--echo # --echo #
...@@ -3459,8 +3459,7 @@ bool ha_partition::init_partition_bitmaps() ...@@ -3459,8 +3459,7 @@ bool ha_partition::init_partition_bitmaps()
/* /*
Open handler object Open handler object
SYNOPSIS
SYNOPSIS
open() open()
name Full path of table name name Full path of table name
mode Open mode flags mode Open mode flags
...@@ -3586,6 +3585,7 @@ int ha_partition::open(const char *name, int mode, uint test_if_locked) ...@@ -3586,6 +3585,7 @@ int ha_partition::open(const char *name, int mode, uint test_if_locked)
} }
else else
{ {
check_insert_autoincrement();
if (unlikely((error= open_read_partitions(name_buff, sizeof(name_buff))))) if (unlikely((error= open_read_partitions(name_buff, sizeof(name_buff)))))
goto err_handler; goto err_handler;
m_num_locks= m_file_sample->lock_count(); m_num_locks= m_file_sample->lock_count();
...@@ -4472,11 +4472,8 @@ int ha_partition::update_row(const uchar *old_data, const uchar *new_data) ...@@ -4472,11 +4472,8 @@ int ha_partition::update_row(const uchar *old_data, const uchar *new_data)
table->found_next_number_field->field_index)) table->found_next_number_field->field_index))
{ {
update_next_auto_inc_val(); update_next_auto_inc_val();
/* if (part_share->auto_inc_initialized)
The following call is safe as part_share->auto_inc_initialized set_auto_increment_if_higher(table->found_next_number_field);
(tested in the call) is guaranteed to be set for update statements.
*/
set_auto_increment_if_higher(table->found_next_number_field);
} }
DBUG_RETURN(error); DBUG_RETURN(error);
} }
...@@ -8144,6 +8141,7 @@ int ha_partition::info(uint flag) ...@@ -8144,6 +8141,7 @@ int ha_partition::info(uint flag)
if (flag & HA_STATUS_AUTO) if (flag & HA_STATUS_AUTO)
{ {
bool auto_inc_is_first_in_idx= (table_share->next_number_keypart == 0); bool auto_inc_is_first_in_idx= (table_share->next_number_keypart == 0);
bool all_parts_opened= true;
DBUG_PRINT("info", ("HA_STATUS_AUTO")); DBUG_PRINT("info", ("HA_STATUS_AUTO"));
if (!table->found_next_number_field) if (!table->found_next_number_field)
stats.auto_increment_value= 0; stats.auto_increment_value= 0;
...@@ -8174,6 +8172,15 @@ int ha_partition::info(uint flag) ...@@ -8174,6 +8172,15 @@ int ha_partition::info(uint flag)
("checking all partitions for auto_increment_value")); ("checking all partitions for auto_increment_value"));
do do
{ {
if (!bitmap_is_set(&m_opened_partitions, (uint)(file_array - m_file)))
{
/*
Some partitions aren't opened.
So we can't calculate the autoincrement.
*/
all_parts_opened= false;
break;
}
file= *file_array; file= *file_array;
file->info(HA_STATUS_AUTO | no_lock_flag); file->info(HA_STATUS_AUTO | no_lock_flag);
set_if_bigger(auto_increment_value, set_if_bigger(auto_increment_value,
...@@ -8182,7 +8189,7 @@ int ha_partition::info(uint flag) ...@@ -8182,7 +8189,7 @@ int ha_partition::info(uint flag)
DBUG_ASSERT(auto_increment_value); DBUG_ASSERT(auto_increment_value);
stats.auto_increment_value= auto_increment_value; stats.auto_increment_value= auto_increment_value;
if (auto_inc_is_first_in_idx) if (all_parts_opened && auto_inc_is_first_in_idx)
{ {
set_if_bigger(part_share->next_auto_inc_val, set_if_bigger(part_share->next_auto_inc_val,
auto_increment_value); auto_increment_value);
...@@ -8485,6 +8492,7 @@ int ha_partition::change_partitions_to_open(List<String> *partition_names) ...@@ -8485,6 +8492,7 @@ int ha_partition::change_partitions_to_open(List<String> *partition_names)
return 0; return 0;
} }
check_insert_autoincrement();
if (bitmap_cmp(&m_opened_partitions, &m_part_info->read_partitions) != 0) if (bitmap_cmp(&m_opened_partitions, &m_part_info->read_partitions) != 0)
return 0; return 0;
......
...@@ -1329,6 +1329,19 @@ class ha_partition :public handler ...@@ -1329,6 +1329,19 @@ class ha_partition :public handler
unlock_auto_increment(); unlock_auto_increment();
} }
void check_insert_autoincrement()
{
/*
If we INSERT into the table having the AUTO_INCREMENT column,
we have to read all partitions for the next autoincrement value
unless we already did it.
*/
if (!part_share->auto_inc_initialized &&
ha_thd()->lex->sql_command == SQLCOM_INSERT &&
table->found_next_number_field)
bitmap_set_all(&m_part_info->read_partitions);
}
public: public:
/* /*
......
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