diff options
author | Kentoku SHIBA <kentokushiba@gmail.com> | 2020-04-16 00:44:20 +0900 |
---|---|---|
committer | Kentoku SHIBA <kentokushiba@gmail.com> | 2020-10-20 22:32:12 +0900 |
commit | 88d22f0e65192ca1b1e69b46661ce57ce19dbaa4 (patch) | |
tree | c0830441a9a06378f4231687639fbd53ce345284 | |
parent | 9b46d8e5c4108b0c55f8df3aa9abd8dd344d7688 (diff) | |
download | mariadb-git-88d22f0e65192ca1b1e69b46661ce57ce19dbaa4.tar.gz |
MDEV-20100 MariaDB 13.3.9 Crash "[ERROR] mysqld got signal 11 ;"
Some functions on ha_partition call functions on all partitions, but handler->reset() is only called that pruned by m_partitions_to_reset. So Spider didn't clear pointer on unpruned partitions, if the unpruned partitions are used by next query, Spider reference the pointer that is already freed.
6 files changed, 320 insertions, 29 deletions
diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index c742524a236..b11890aaffb 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -11019,7 +11019,7 @@ TABLE_LIST *ha_partition::get_next_global_for_child() const COND *ha_partition::cond_push(const COND *cond) { - handler **file= m_file; + uint i; COND *res_cond= NULL; DBUG_ENTER("ha_partition::cond_push"); @@ -11029,26 +11029,35 @@ const COND *ha_partition::cond_push(const COND *cond) We want to do this in a separate loop to not come into a situation where we have only done cond_push() to some of the tables */ - do + for (i= bitmap_get_first_set(&m_partitions_to_reset); + i < m_tot_parts; + i= bitmap_get_next_set(&m_partitions_to_reset, i)) { - if (((*file)->set_top_table_and_fields(top_table, - top_table_field, - top_table_fields))) - DBUG_RETURN(cond); // Abort cond push, no error - } while (*(++file)); - file= m_file; + if (bitmap_is_set(&m_opened_partitions, i)) + { + if ((m_file[i]->set_top_table_and_fields(top_table, + top_table_field, + top_table_fields))) + DBUG_RETURN(cond); // Abort cond push, no error + } + } } - do + for (i= bitmap_get_first_set(&m_partitions_to_reset); + i < m_tot_parts; + i= bitmap_get_next_set(&m_partitions_to_reset, i)) { - if ((*file)->pushed_cond != cond) + if (bitmap_is_set(&m_opened_partitions, i)) { - if ((*file)->cond_push(cond)) - res_cond= (COND *) cond; - else - (*file)->pushed_cond= cond; + if (m_file[i]->pushed_cond != cond) + { + if (m_file[i]->cond_push(cond)) + res_cond= (COND *) cond; + else + m_file[i]->pushed_cond= cond; + } } - } while (*(++file)); + } DBUG_RETURN(res_cond); } @@ -11060,13 +11069,18 @@ const COND *ha_partition::cond_push(const COND *cond) void ha_partition::cond_pop() { - handler **file= m_file; + uint i; DBUG_ENTER("ha_partition::cond_pop"); - do + for (i= bitmap_get_first_set(&m_partitions_to_reset); + i < m_tot_parts; + i= bitmap_get_next_set(&m_partitions_to_reset, i)) { - (*file)->cond_pop(); - } while (*(++file)); + if (bitmap_is_set(&m_opened_partitions, i)) + { + m_file[i]->cond_pop(); + } + } DBUG_VOID_RETURN; } @@ -11642,23 +11656,29 @@ int ha_partition::pre_direct_delete_rows() int ha_partition::info_push(uint info_type, void *info) { - int error= 0; - handler **file= m_file; + int error= 0, tmp; + uint i; DBUG_ENTER("ha_partition::info_push"); - do + for (i= bitmap_get_first_set(&m_partitions_to_reset); + i < m_tot_parts; + i= bitmap_get_next_set(&m_partitions_to_reset, i)) { - int tmp; - if ((tmp= (*file)->info_push(info_type, info))) - error= tmp; - } while (*(++file)); + if (bitmap_is_set(&m_opened_partitions, i)) + { + if ((tmp= m_file[i]->info_push(info_type, info))) + { + error= tmp; + } + } + } DBUG_RETURN(error); } void ha_partition::clear_top_table_fields() { - handler **file; + uint i; DBUG_ENTER("ha_partition::clear_top_table_fields"); if (set_top_table_fields) @@ -11667,8 +11687,15 @@ void ha_partition::clear_top_table_fields() top_table= NULL; top_table_field= NULL; top_table_fields= 0; - for (file= m_file; *file; file++) - (*file)->clear_top_table_fields(); + for (i= bitmap_get_first_set(&m_partitions_to_reset); + i < m_tot_parts; + i= bitmap_get_next_set(&m_partitions_to_reset, i)) + { + if (bitmap_is_set(&m_opened_partitions, i)) + { + m_file[i]->clear_top_table_fields(); + } + } } DBUG_VOID_RETURN; } diff --git a/storage/spider/mysql-test/spider/bugfix/include/mdev_20100_deinit.inc b/storage/spider/mysql-test/spider/bugfix/include/mdev_20100_deinit.inc new file mode 100644 index 00000000000..1880a1c7bba --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/include/mdev_20100_deinit.inc @@ -0,0 +1,11 @@ +--let $MASTER_1_COMMENT_P_2_1= $MASTER_1_COMMENT_P_2_1_BACKUP +--let $CHILD2_1_DROP_TABLES= $CHILD2_1_DROP_TABLES_BACKUP +--let $CHILD2_1_CREATE_TABLES= $CHILD2_1_CREATE_TABLES_BACKUP +--let $CHILD2_1_SELECT_TABLES= $CHILD2_1_SELECT_TABLES_BACKUP +--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/mysql-test/spider/bugfix/include/mdev_20100_init.inc b/storage/spider/mysql-test/spider/bugfix/include/mdev_20100_init.inc new file mode 100644 index 00000000000..ed6e27962d2 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/include/mdev_20100_init.inc @@ -0,0 +1,46 @@ +--disable_warnings +--disable_query_log +--disable_result_log +--source ../t/test_init.inc +--enable_result_log +--enable_query_log +--enable_warnings +--let $MASTER_1_COMMENT_P_2_1_BACKUP= $MASTER_1_COMMENT_P_2_1 +let $MASTER_1_COMMENT_P_2_1= + PARTITION BY RANGE(a) ( + PARTITION pt1 VALUES LESS THAN (5) COMMENT='srv "s_2_1", table "ta_r2"', + PARTITION pt2 VALUES LESS THAN (10) COMMENT='srv "s_2_1", table "ta_r3"', + PARTITION pt3 VALUES LESS THAN MAXVALUE COMMENT='srv "s_2_1", table "ta_r4"' + ); +--let $CHILD2_1_DROP_TABLES_BACKUP= $CHILD2_1_DROP_TABLES +let $CHILD2_1_DROP_TABLES= + DROP TABLE IF EXISTS ta_r2 $STR_SEMICOLON + DROP TABLE IF EXISTS ta_r3 $STR_SEMICOLON + DROP TABLE IF EXISTS ta_r4; +--let $CHILD2_1_CREATE_TABLES_BACKUP= $CHILD2_1_CREATE_TABLES +let $CHILD2_1_CREATE_TABLES= + CREATE TABLE ta_r2 ( + a INT, + b CHAR(1), + c DATETIME, + PRIMARY KEY(a) + ) $CHILD2_1_ENGINE $CHILD2_1_CHARSET $STR_SEMICOLON + CREATE TABLE ta_r3 ( + a INT, + b CHAR(1), + c DATETIME, + PRIMARY KEY(a) + ) $CHILD2_1_ENGINE $CHILD2_1_CHARSET $STR_SEMICOLON + CREATE TABLE ta_r4 ( + a INT, + b CHAR(1), + c DATETIME, + PRIMARY KEY(a) + ) $CHILD2_1_ENGINE $CHILD2_1_CHARSET; +--let $CHILD2_1_SELECT_TABLES_BACKUP= $CHILD2_1_SELECT_TABLES +let $CHILD2_1_SELECT_TABLES= + SELECT a, b, c FROM ta_r2 ORDER BY a $STR_SEMICOLON + SELECT a, b, c FROM ta_r3 ORDER BY a $STR_SEMICOLON + SELECT a, b, c FROM ta_r4 ORDER BY a; +let $CHILD2_1_SELECT_ARGUMENT1= + SELECT argument FROM mysql.general_log WHERE argument LIKE '%select %'; diff --git a/storage/spider/mysql-test/spider/bugfix/r/mdev_20100.result b/storage/spider/mysql-test/spider/bugfix/r/mdev_20100.result new file mode 100644 index 00000000000..fc4fb02d72f --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_20100.result @@ -0,0 +1,119 @@ +for master_1 +for child2 +child2_1 +child2_2 +child2_3 +for child3 + +this test is for MDEV-20100 + +drop and create databases +connection master_1; +CREATE DATABASE auto_test_local; +USE auto_test_local; +connection child2_1; +SET @old_log_output = @@global.log_output; +SET GLOBAL log_output = 'TABLE,FILE'; +CREATE DATABASE auto_test_remote; +USE auto_test_remote; + +create table and insert +connection child2_1; +CHILD2_1_CREATE_TABLES +TRUNCATE TABLE mysql.general_log; +connection master_1; +CREATE TABLE tbl_a ( +a INT, +b CHAR(1), +c DATETIME, +PRIMARY KEY(a) +) ENGINE=Spider PARTITION BY RANGE(a) ( +PARTITION pt1 VALUES LESS THAN (5) COMMENT='srv "s_2_1", table "ta_r2"', +PARTITION pt2 VALUES LESS THAN (10) COMMENT='srv "s_2_1", table "ta_r3"', +PARTITION pt3 VALUES LESS THAN MAXVALUE COMMENT='srv "s_2_1", table "ta_r4"' + ) +INSERT INTO tbl_a (a, b, c) VALUES +(1, 'a', '2008-08-01 10:21:39'), +(2, 'b', '2000-01-01 00:00:00'), +(3, 'e', '2007-06-04 20:03:11'), +(4, 'd', '2003-11-30 05:01:03'), +(5, 'c', '2001-12-31 23:59:59'); + +test 1 +connection child2_1; +TRUNCATE TABLE mysql.general_log; +connection master_1; +SELECT a, b, c FROM tbl_a PARTITION (pt2) WHERE b = 'c'; +a b c +5 c 2001-12-31 23:59:59 +SELECT a, b, c FROM tbl_a PARTITION (pt1,pt2); +a b c +1 a 2008-08-01 10:21:39 +2 b 2000-01-01 00:00:00 +3 e 2007-06-04 20:03:11 +4 d 2003-11-30 05:01:03 +5 c 2001-12-31 23:59:59 +SELECT a, b, c FROM tbl_a PARTITION (pt3) WHERE b = 'c'; +a b c +SELECT a, b, c FROM tbl_a PARTITION (pt1,pt2); +a b c +1 a 2008-08-01 10:21:39 +2 b 2000-01-01 00:00:00 +3 e 2007-06-04 20:03:11 +4 d 2003-11-30 05:01:03 +5 c 2001-12-31 23:59:59 +SELECT a, b, c FROM tbl_a PARTITION (pt1) WHERE b = 'c'; +a b c +SELECT a, b, c FROM tbl_a PARTITION (pt1,pt3); +a b c +1 a 2008-08-01 10:21:39 +2 b 2000-01-01 00:00:00 +3 e 2007-06-04 20:03:11 +4 d 2003-11-30 05:01:03 +SELECT a, b, c FROM tbl_a PARTITION (pt1) WHERE b = 'c'; +a b c +SELECT a, b, c FROM tbl_a PARTITION (pt2,pt3); +a b c +5 c 2001-12-31 23:59:59 +connection child2_1; +SELECT argument FROM mysql.general_log WHERE argument LIKE '%select %'; +argument +select `a`,`b`,`c` from `auto_test_remote`.`ta_r3` where (`b` = 'c') +select `a`,`b`,`c` from `auto_test_remote`.`ta_r2` +select `a`,`b`,`c` from `auto_test_remote`.`ta_r3` +select `a`,`b`,`c` from `auto_test_remote`.`ta_r4` where (`b` = 'c') +select `a`,`b`,`c` from `auto_test_remote`.`ta_r2` +select `a`,`b`,`c` from `auto_test_remote`.`ta_r3` +select `a`,`b`,`c` from `auto_test_remote`.`ta_r2` where (`b` = 'c') +select `a`,`b`,`c` from `auto_test_remote`.`ta_r2` +select `a`,`b`,`c` from `auto_test_remote`.`ta_r4` +select `a`,`b`,`c` from `auto_test_remote`.`ta_r2` where (`b` = 'c') +select `a`,`b`,`c` from `auto_test_remote`.`ta_r3` +select `a`,`b`,`c` from `auto_test_remote`.`ta_r4` +SELECT argument FROM mysql.general_log WHERE argument LIKE '%select %' +SELECT a, b, c FROM ta_r2 ORDER BY a ; +SELECT a, b, c FROM ta_r3 ORDER BY a ; +SELECT a, b, c FROM ta_r4 ORDER BY a; +a b c +1 a 2008-08-01 10:21:39 +2 b 2000-01-01 00:00:00 +3 e 2007-06-04 20:03:11 +4 d 2003-11-30 05:01:03 +a b c +5 c 2001-12-31 23:59:59 +a b c + +deinit +connection master_1; +DROP DATABASE IF EXISTS auto_test_local; +connection child2_1; +DROP DATABASE IF EXISTS auto_test_remote; +SET GLOBAL log_output = @old_log_output; +for master_1 +for child2 +child2_1 +child2_2 +child2_3 +for child3 + +end of test diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_20100.cnf b/storage/spider/mysql-test/spider/bugfix/t/mdev_20100.cnf new file mode 100644 index 00000000000..05dfd8a0bce --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_20100.cnf @@ -0,0 +1,3 @@ +!include include/default_mysqld.cnf +!include ../my_1_1.cnf +!include ../my_2_1.cnf diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_20100.test b/storage/spider/mysql-test/spider/bugfix/t/mdev_20100.test new file mode 100644 index 00000000000..b72facd11a6 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_20100.test @@ -0,0 +1,85 @@ +--source ../include/mdev_20100_init.inc +--echo +--echo this test is for MDEV-20100 +--echo +--echo drop and create databases + +--connection master_1 +--disable_warnings +CREATE DATABASE auto_test_local; +USE auto_test_local; + +--connection child2_1 +SET @old_log_output = @@global.log_output; +SET GLOBAL log_output = 'TABLE,FILE'; +CREATE DATABASE auto_test_remote; +USE auto_test_remote; +--enable_warnings + +--echo +--echo create table and insert + +--connection child2_1 +--disable_query_log +echo CHILD2_1_CREATE_TABLES; +eval $CHILD2_1_CREATE_TABLES; +--enable_query_log +TRUNCATE TABLE mysql.general_log; + +--connection master_1 +--disable_query_log +echo CREATE TABLE tbl_a ( + a INT, + b CHAR(1), + c DATETIME, + PRIMARY KEY(a) +) $MASTER_1_ENGINE $MASTER_1_COMMENT_P_2_1; +eval CREATE TABLE tbl_a ( + a INT, + b CHAR(1), + c DATETIME, + PRIMARY KEY(a) +) $MASTER_1_ENGINE $MASTER_1_COMMENT_P_2_1; +--enable_query_log +INSERT INTO tbl_a (a, b, c) VALUES + (1, 'a', '2008-08-01 10:21:39'), + (2, 'b', '2000-01-01 00:00:00'), + (3, 'e', '2007-06-04 20:03:11'), + (4, 'd', '2003-11-30 05:01:03'), + (5, 'c', '2001-12-31 23:59:59'); + +--echo +--echo test 1 + +--connection child2_1 +TRUNCATE TABLE mysql.general_log; + +--connection master_1 +SELECT a, b, c FROM tbl_a PARTITION (pt2) WHERE b = 'c'; +SELECT a, b, c FROM tbl_a PARTITION (pt1,pt2); +SELECT a, b, c FROM tbl_a PARTITION (pt3) WHERE b = 'c'; +SELECT a, b, c FROM tbl_a PARTITION (pt1,pt2); +SELECT a, b, c FROM tbl_a PARTITION (pt1) WHERE b = 'c'; +SELECT a, b, c FROM tbl_a PARTITION (pt1,pt3); +SELECT a, b, c FROM tbl_a PARTITION (pt1) WHERE b = 'c'; +SELECT a, b, c FROM tbl_a PARTITION (pt2,pt3); + +--connection child2_1 +eval $CHILD2_1_SELECT_ARGUMENT1; +eval $CHILD2_1_SELECT_TABLES; + +--echo +--echo deinit +--disable_warnings + +--connection master_1 +DROP DATABASE IF EXISTS auto_test_local; + +--connection child2_1 +DROP DATABASE IF EXISTS auto_test_remote; +SET GLOBAL log_output = @old_log_output; + +--enable_warnings +--source ../include/mdev_20100_deinit.inc +--echo +--echo end of test |