Skip to content

Commit ac8d205

Browse files
committed
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.
1 parent fdf8797 commit ac8d205

File tree

6 files changed

+320
-29
lines changed

6 files changed

+320
-29
lines changed

sql/ha_partition.cc

Lines changed: 56 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -11148,7 +11148,7 @@ TABLE_LIST *ha_partition::get_next_global_for_child()
1114811148

1114911149
const COND *ha_partition::cond_push(const COND *cond)
1115011150
{
11151-
handler **file= m_file;
11151+
uint i;
1115211152
COND *res_cond= NULL;
1115311153
DBUG_ENTER("ha_partition::cond_push");
1115411154

@@ -11158,26 +11158,35 @@ const COND *ha_partition::cond_push(const COND *cond)
1115811158
We want to do this in a separate loop to not come into a situation
1115911159
where we have only done cond_push() to some of the tables
1116011160
*/
11161-
do
11161+
for (i= bitmap_get_first_set(&m_partitions_to_reset);
11162+
i < m_tot_parts;
11163+
i= bitmap_get_next_set(&m_partitions_to_reset, i))
1116211164
{
11163-
if (((*file)->set_top_table_and_fields(top_table,
11164-
top_table_field,
11165-
top_table_fields)))
11166-
DBUG_RETURN(cond); // Abort cond push, no error
11167-
} while (*(++file));
11168-
file= m_file;
11165+
if (bitmap_is_set(&m_opened_partitions, i))
11166+
{
11167+
if ((m_file[i]->set_top_table_and_fields(top_table,
11168+
top_table_field,
11169+
top_table_fields)))
11170+
DBUG_RETURN(cond); // Abort cond push, no error
11171+
}
11172+
}
1116911173
}
1117011174

11171-
do
11175+
for (i= bitmap_get_first_set(&m_partitions_to_reset);
11176+
i < m_tot_parts;
11177+
i= bitmap_get_next_set(&m_partitions_to_reset, i))
1117211178
{
11173-
if ((*file)->pushed_cond != cond)
11179+
if (bitmap_is_set(&m_opened_partitions, i))
1117411180
{
11175-
if ((*file)->cond_push(cond))
11176-
res_cond= (COND *) cond;
11177-
else
11178-
(*file)->pushed_cond= cond;
11181+
if (m_file[i]->pushed_cond != cond)
11182+
{
11183+
if (m_file[i]->cond_push(cond))
11184+
res_cond= (COND *) cond;
11185+
else
11186+
m_file[i]->pushed_cond= cond;
11187+
}
1117911188
}
11180-
} while (*(++file));
11189+
}
1118111190
DBUG_RETURN(res_cond);
1118211191
}
1118311192

@@ -11189,13 +11198,18 @@ const COND *ha_partition::cond_push(const COND *cond)
1118911198

1119011199
void ha_partition::cond_pop()
1119111200
{
11192-
handler **file= m_file;
11201+
uint i;
1119311202
DBUG_ENTER("ha_partition::cond_pop");
1119411203

11195-
do
11204+
for (i= bitmap_get_first_set(&m_partitions_to_reset);
11205+
i < m_tot_parts;
11206+
i= bitmap_get_next_set(&m_partitions_to_reset, i))
1119611207
{
11197-
(*file)->cond_pop();
11198-
} while (*(++file));
11208+
if (bitmap_is_set(&m_opened_partitions, i))
11209+
{
11210+
m_file[i]->cond_pop();
11211+
}
11212+
}
1119911213
DBUG_VOID_RETURN;
1120011214
}
1120111215

@@ -11779,23 +11793,29 @@ int ha_partition::pre_direct_delete_rows()
1177911793

1178011794
int ha_partition::info_push(uint info_type, void *info)
1178111795
{
11782-
int error= 0;
11783-
handler **file= m_file;
11796+
int error= 0, tmp;
11797+
uint i;
1178411798
DBUG_ENTER("ha_partition::info_push");
1178511799

11786-
do
11800+
for (i= bitmap_get_first_set(&m_partitions_to_reset);
11801+
i < m_tot_parts;
11802+
i= bitmap_get_next_set(&m_partitions_to_reset, i))
1178711803
{
11788-
int tmp;
11789-
if ((tmp= (*file)->info_push(info_type, info)))
11790-
error= tmp;
11791-
} while (*(++file));
11804+
if (bitmap_is_set(&m_opened_partitions, i))
11805+
{
11806+
if ((tmp= m_file[i]->info_push(info_type, info)))
11807+
{
11808+
error= tmp;
11809+
}
11810+
}
11811+
}
1179211812
DBUG_RETURN(error);
1179311813
}
1179411814

1179511815

1179611816
void ha_partition::clear_top_table_fields()
1179711817
{
11798-
handler **file;
11818+
uint i;
1179911819
DBUG_ENTER("ha_partition::clear_top_table_fields");
1180011820

1180111821
if (set_top_table_fields)
@@ -11804,8 +11824,15 @@ void ha_partition::clear_top_table_fields()
1180411824
top_table= NULL;
1180511825
top_table_field= NULL;
1180611826
top_table_fields= 0;
11807-
for (file= m_file; *file; file++)
11808-
(*file)->clear_top_table_fields();
11827+
for (i= bitmap_get_first_set(&m_partitions_to_reset);
11828+
i < m_tot_parts;
11829+
i= bitmap_get_next_set(&m_partitions_to_reset, i))
11830+
{
11831+
if (bitmap_is_set(&m_opened_partitions, i))
11832+
{
11833+
m_file[i]->clear_top_table_fields();
11834+
}
11835+
}
1180911836
}
1181011837
DBUG_VOID_RETURN;
1181111838
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
--let $MASTER_1_COMMENT_P_2_1= $MASTER_1_COMMENT_P_2_1_BACKUP
2+
--let $CHILD2_1_DROP_TABLES= $CHILD2_1_DROP_TABLES_BACKUP
3+
--let $CHILD2_1_CREATE_TABLES= $CHILD2_1_CREATE_TABLES_BACKUP
4+
--let $CHILD2_1_SELECT_TABLES= $CHILD2_1_SELECT_TABLES_BACKUP
5+
--disable_warnings
6+
--disable_query_log
7+
--disable_result_log
8+
--source ../t/test_deinit.inc
9+
--enable_result_log
10+
--enable_query_log
11+
--enable_warnings
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
--disable_warnings
2+
--disable_query_log
3+
--disable_result_log
4+
--source ../t/test_init.inc
5+
--enable_result_log
6+
--enable_query_log
7+
--enable_warnings
8+
--let $MASTER_1_COMMENT_P_2_1_BACKUP= $MASTER_1_COMMENT_P_2_1
9+
let $MASTER_1_COMMENT_P_2_1=
10+
PARTITION BY RANGE(a) (
11+
PARTITION pt1 VALUES LESS THAN (5) COMMENT='srv "s_2_1", table "ta_r2"',
12+
PARTITION pt2 VALUES LESS THAN (10) COMMENT='srv "s_2_1", table "ta_r3"',
13+
PARTITION pt3 VALUES LESS THAN MAXVALUE COMMENT='srv "s_2_1", table "ta_r4"'
14+
);
15+
--let $CHILD2_1_DROP_TABLES_BACKUP= $CHILD2_1_DROP_TABLES
16+
let $CHILD2_1_DROP_TABLES=
17+
DROP TABLE IF EXISTS ta_r2 $STR_SEMICOLON
18+
DROP TABLE IF EXISTS ta_r3 $STR_SEMICOLON
19+
DROP TABLE IF EXISTS ta_r4;
20+
--let $CHILD2_1_CREATE_TABLES_BACKUP= $CHILD2_1_CREATE_TABLES
21+
let $CHILD2_1_CREATE_TABLES=
22+
CREATE TABLE ta_r2 (
23+
a INT,
24+
b CHAR(1),
25+
c DATETIME,
26+
PRIMARY KEY(a)
27+
) $CHILD2_1_ENGINE $CHILD2_1_CHARSET $STR_SEMICOLON
28+
CREATE TABLE ta_r3 (
29+
a INT,
30+
b CHAR(1),
31+
c DATETIME,
32+
PRIMARY KEY(a)
33+
) $CHILD2_1_ENGINE $CHILD2_1_CHARSET $STR_SEMICOLON
34+
CREATE TABLE ta_r4 (
35+
a INT,
36+
b CHAR(1),
37+
c DATETIME,
38+
PRIMARY KEY(a)
39+
) $CHILD2_1_ENGINE $CHILD2_1_CHARSET;
40+
--let $CHILD2_1_SELECT_TABLES_BACKUP= $CHILD2_1_SELECT_TABLES
41+
let $CHILD2_1_SELECT_TABLES=
42+
SELECT a, b, c FROM ta_r2 ORDER BY a $STR_SEMICOLON
43+
SELECT a, b, c FROM ta_r3 ORDER BY a $STR_SEMICOLON
44+
SELECT a, b, c FROM ta_r4 ORDER BY a;
45+
let $CHILD2_1_SELECT_ARGUMENT1=
46+
SELECT argument FROM mysql.general_log WHERE argument LIKE '%select %';
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
for master_1
2+
for child2
3+
child2_1
4+
child2_2
5+
child2_3
6+
for child3
7+
8+
this test is for MDEV-20100
9+
10+
drop and create databases
11+
connection master_1;
12+
CREATE DATABASE auto_test_local;
13+
USE auto_test_local;
14+
connection child2_1;
15+
SET @old_log_output = @@global.log_output;
16+
SET GLOBAL log_output = 'TABLE,FILE';
17+
CREATE DATABASE auto_test_remote;
18+
USE auto_test_remote;
19+
20+
create table and insert
21+
connection child2_1;
22+
CHILD2_1_CREATE_TABLES
23+
TRUNCATE TABLE mysql.general_log;
24+
connection master_1;
25+
CREATE TABLE tbl_a (
26+
a INT,
27+
b CHAR(1),
28+
c DATETIME,
29+
PRIMARY KEY(a)
30+
) ENGINE=Spider PARTITION BY RANGE(a) (
31+
PARTITION pt1 VALUES LESS THAN (5) COMMENT='srv "s_2_1", table "ta_r2"',
32+
PARTITION pt2 VALUES LESS THAN (10) COMMENT='srv "s_2_1", table "ta_r3"',
33+
PARTITION pt3 VALUES LESS THAN MAXVALUE COMMENT='srv "s_2_1", table "ta_r4"'
34+
)
35+
INSERT INTO tbl_a (a, b, c) VALUES
36+
(1, 'a', '2008-08-01 10:21:39'),
37+
(2, 'b', '2000-01-01 00:00:00'),
38+
(3, 'e', '2007-06-04 20:03:11'),
39+
(4, 'd', '2003-11-30 05:01:03'),
40+
(5, 'c', '2001-12-31 23:59:59');
41+
42+
test 1
43+
connection child2_1;
44+
TRUNCATE TABLE mysql.general_log;
45+
connection master_1;
46+
SELECT a, b, c FROM tbl_a PARTITION (pt2) WHERE b = 'c';
47+
a b c
48+
5 c 2001-12-31 23:59:59
49+
SELECT a, b, c FROM tbl_a PARTITION (pt1,pt2);
50+
a b c
51+
1 a 2008-08-01 10:21:39
52+
2 b 2000-01-01 00:00:00
53+
3 e 2007-06-04 20:03:11
54+
4 d 2003-11-30 05:01:03
55+
5 c 2001-12-31 23:59:59
56+
SELECT a, b, c FROM tbl_a PARTITION (pt3) WHERE b = 'c';
57+
a b c
58+
SELECT a, b, c FROM tbl_a PARTITION (pt1,pt2);
59+
a b c
60+
1 a 2008-08-01 10:21:39
61+
2 b 2000-01-01 00:00:00
62+
3 e 2007-06-04 20:03:11
63+
4 d 2003-11-30 05:01:03
64+
5 c 2001-12-31 23:59:59
65+
SELECT a, b, c FROM tbl_a PARTITION (pt1) WHERE b = 'c';
66+
a b c
67+
SELECT a, b, c FROM tbl_a PARTITION (pt1,pt3);
68+
a b c
69+
1 a 2008-08-01 10:21:39
70+
2 b 2000-01-01 00:00:00
71+
3 e 2007-06-04 20:03:11
72+
4 d 2003-11-30 05:01:03
73+
SELECT a, b, c FROM tbl_a PARTITION (pt1) WHERE b = 'c';
74+
a b c
75+
SELECT a, b, c FROM tbl_a PARTITION (pt2,pt3);
76+
a b c
77+
5 c 2001-12-31 23:59:59
78+
connection child2_1;
79+
SELECT argument FROM mysql.general_log WHERE argument LIKE '%select %';
80+
argument
81+
select t0.`a` `a`,t0.`b` `b`,t0.`c` `c` from `auto_test_remote`.`ta_r3` t0 where (t0.`b` = 'c')
82+
select `a`,`b`,`c` from `auto_test_remote`.`ta_r2`
83+
select `a`,`b`,`c` from `auto_test_remote`.`ta_r3`
84+
select t0.`a` `a`,t0.`b` `b`,t0.`c` `c` from `auto_test_remote`.`ta_r4` t0 where (t0.`b` = 'c')
85+
select `a`,`b`,`c` from `auto_test_remote`.`ta_r2`
86+
select `a`,`b`,`c` from `auto_test_remote`.`ta_r3`
87+
select t0.`a` `a`,t0.`b` `b`,t0.`c` `c` from `auto_test_remote`.`ta_r2` t0 where (t0.`b` = 'c')
88+
select `a`,`b`,`c` from `auto_test_remote`.`ta_r2`
89+
select `a`,`b`,`c` from `auto_test_remote`.`ta_r4`
90+
select t0.`a` `a`,t0.`b` `b`,t0.`c` `c` from `auto_test_remote`.`ta_r2` t0 where (t0.`b` = 'c')
91+
select `a`,`b`,`c` from `auto_test_remote`.`ta_r3`
92+
select `a`,`b`,`c` from `auto_test_remote`.`ta_r4`
93+
SELECT argument FROM mysql.general_log WHERE argument LIKE '%select %'
94+
SELECT a, b, c FROM ta_r2 ORDER BY a ;
95+
SELECT a, b, c FROM ta_r3 ORDER BY a ;
96+
SELECT a, b, c FROM ta_r4 ORDER BY a;
97+
a b c
98+
1 a 2008-08-01 10:21:39
99+
2 b 2000-01-01 00:00:00
100+
3 e 2007-06-04 20:03:11
101+
4 d 2003-11-30 05:01:03
102+
a b c
103+
5 c 2001-12-31 23:59:59
104+
a b c
105+
106+
deinit
107+
connection master_1;
108+
DROP DATABASE IF EXISTS auto_test_local;
109+
connection child2_1;
110+
DROP DATABASE IF EXISTS auto_test_remote;
111+
SET GLOBAL log_output = @old_log_output;
112+
for master_1
113+
for child2
114+
child2_1
115+
child2_2
116+
child2_3
117+
for child3
118+
119+
end of test
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
!include include/default_mysqld.cnf
2+
!include ../my_1_1.cnf
3+
!include ../my_2_1.cnf

0 commit comments

Comments
 (0)