Commit f6694b62 authored by Jacob Mathew's avatar Jacob Mathew

MDEV-16889: Spider Crash mysqld got exception 0xc0000005

The SELECT with the INNER JOIN is executed with one of the two tables being
optimized as a constant table, which is pre-read.  Spider nevertheless attempts
to push down the join to the data node.  The crash occurs because the constant
table is excluded from the optimized query that Spider attempts to push down.

In order for Spider to be able to push down a join, the following conditions
need to be met:
- All of the tables involved in the join need to be included in the optimized
  query that Spider pushes down.  When any of the tables involved in the join
  is a constant table, it is excluded from the optimized query that Spider
  attempts to push down.
- All fields involved in the query need to be members of tables included in the
  optimized query.

I fixed the problem by preventing Spider from pushing down queries that include
a field that is not a member of a table included in the optimized query.  This
solution fixes the reported problem and also fixes other potential problems.

Author:
  Jacob Mathew.

Reviewer:
  Kentoku Shiba.

Cherry-Picked:
  Commit 4885baf6 on branch bb-10.3-MDEV-16889
parent 6ccd7d2d
...@@ -5,6 +5,46 @@ ...@@ -5,6 +5,46 @@
--enable_result_log --enable_result_log
--enable_query_log --enable_query_log
--enable_warnings --enable_warnings
let $MASTER_1_COMMENT_CONST_TABLE_JOIN=
COMMENT 'table "tbl_person"';
let $MASTER_1_COMMENT_CONST_TABLE_JOIN=
COMMENT 'table "tbl_ncd_cm_person"';
let $MASTER_1_ROW_FORMAT_CONST_TABLE_JOIN=
ROW_FORMAT = Dynamic;
let $MASTER_1_PART_CONST_TABLE_JOIN=
PARTITION BY LIST COLUMNS (region) PARTITIONS 1
(PARTITION pt1 values in (510411)
COMMENT = 'tbl "tbl_person", srv "s_2_1"' MAX_ROWS = 0 MIN_ROWS = 0);
let $MASTER_1_PART_CONST_TABLE2_JOIN=
PARTITION BY LIST COLUMNS (region) PARTITIONS 1
(PARTITION pt1 values in (510411)
COMMENT = 'tbl "tbl_ncd_cm_person", srv "s_2_1"' MAX_ROWS = 0 MIN_ROWS = 0);
let $CHILD2_1_ROW_FORMAT_CONST_TABLE_JOIN=
ROW_FORMAT = Dynamic;
let $CHILD2_1_DROP_CONST_TABLE_JOIN=
DROP TABLE IF EXISTS tbl_person;
let $CHILD2_1_CREATE_CONST_TABLE_JOIN=
CREATE TABLE tbl_person (
id VARCHAR(50) NOT NULL,
hr_status VARCHAR(50) NULL DEFAULT NULL,
region_code VARCHAR(50) NULL DEFAULT NULL,
region INT(11) NOT NULL,
PRIMARY KEY (id, region) USING BTREE
) $CHILD2_1_ENGINE $CHILD2_1_CHARSET $CHILD2_1_ROW_FORMAT_CONST_TABLE_JOIN;
let $CHILD2_1_DROP_CONST_TABLE2_JOIN=
DROP TABLE IF EXISTS tbl_ncd_cm_person;
let $CHILD2_1_CREATE_CONST_TABLE2_JOIN=
CREATE TABLE tbl_ncd_cm_person (
id VARCHAR(50) NOT NULL,
person_id VARCHAR(50) NULL DEFAULT '',
diseaseKind_id VARCHAR(50) NULL DEFAULT NULL,
region INT(11) NOT NULL,
PRIMARY KEY (id, region) USING BTREE
) $CHILD2_1_ENGINE $CHILD2_1_CHARSET $CHILD2_1_ROW_FORMAT_CONST_TABLE_JOIN;
let $CHILD2_1_SELECT_CONST_TABLE_JOIN=
SELECT * FROM tbl_person;
let $CHILD2_1_SELECT_CONST_TABLE2_JOIN=
SELECT * FROM tbl_ncd_cm_person;
let $CHILD2_1_SELECT_ARGUMENT1= let $CHILD2_1_SELECT_ARGUMENT1=
SELECT argument FROM mysql.general_log WHERE argument LIKE '%select %'; SELECT argument FROM mysql.general_log WHERE argument LIKE '%select %';
--let $OUTPUT_CHILD_GROUP2_BACKUP= $OUTPUT_CHILD_GROUP2 --let $OUTPUT_CHILD_GROUP2_BACKUP= $OUTPUT_CHILD_GROUP2
......
...@@ -86,6 +86,98 @@ a b date_format(c, '%Y-%m-%d %H:%i:%s') ...@@ -86,6 +86,98 @@ a b date_format(c, '%Y-%m-%d %H:%i:%s')
4 d 2000-01-04 00:00:00 4 d 2000-01-04 00:00:00
5 e 2000-01-05 00:00:00 5 e 2000-01-05 00:00:00
Test JOIN on a constant table.
Spider should NOT push down the join because the tbl_person table
is optimized as a constant table.
connection child2_1;
CHILD2_1_DROP_CONST_TABLE_JOIN
CHILD2_1_DROP_CONST_TABLE2_JOIN
CHILD2_1_CREATE_CONST_TABLE_JOIN
CHILD2_1_CREATE_CONST_TABLE2_JOIN
TRUNCATE TABLE mysql.general_log;
connection master_1;
DROP TABLE IF EXISTS tbl_person;
DROP TABLE IF EXISTS tbl_ncd_cm_person;
CREATE TABLE tbl_person (
id VARCHAR(50) NOT NULL,
hr_status VARCHAR(50) NULL DEFAULT NULL,
region_code VARCHAR(50) NULL DEFAULT NULL,
region INT(11) NOT NULL,
PRIMARY KEY (id, region) USING BTREE
) MASTER_1_ENGINE MASTER_1_CHARSET MASTER_1_COMMENT_CONST_TABLE_JOIN
MASTER_1_ROW_FORMAT_CONST_TABLE_JOIN MASTER_1_PART_CONST_TABLE_JOIN
SHOW CREATE TABLE tbl_person
Table Create Table
tbl_person CREATE TABLE `tbl_person` (
`id` varchar(50) NOT NULL,
`hr_status` varchar(50) DEFAULT NULL,
`region_code` varchar(50) DEFAULT NULL,
`region` int(11) NOT NULL,
PRIMARY KEY (`id`,`region`) USING BTREE
) ENGINE=SPIDER DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='table "tbl_ncd_cm_person"'
PARTITION BY LIST COLUMNS(`region`)
(PARTITION `pt1` VALUES IN (510411) COMMENT = 'tbl "tbl_person", srv "s_2_1"' ENGINE = SPIDER)
CREATE TABLE tbl_ncd_cm_person (
id VARCHAR(50) NOT NULL,
person_id VARCHAR(50) NULL DEFAULT '',
diseaseKind_id VARCHAR(50) NULL DEFAULT NULL,
region INT(11) NOT NULL,
PRIMARY KEY (id, region) USING BTREE
) MASTER_1_ENGINE MASTER_1_CHARSET MASTER_1_COMMENT_CONST_TABLE2_JOIN
MASTER_1_ROW_FORMAT_CONST_TABLE_JOIN MASTER_1_PART_CONST_TABLE2_JOIN
SHOW CREATE TABLE tbl_ncd_cm_person
Table Create Table
tbl_ncd_cm_person CREATE TABLE `tbl_ncd_cm_person` (
`id` varchar(50) NOT NULL,
`person_id` varchar(50) DEFAULT '',
`diseaseKind_id` varchar(50) DEFAULT NULL,
`region` int(11) NOT NULL,
PRIMARY KEY (`id`,`region`) USING BTREE
) ENGINE=SPIDER DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC
PARTITION BY LIST COLUMNS(`region`)
(PARTITION `pt1` VALUES IN (510411) COMMENT = 'tbl "tbl_ncd_cm_person", srv "s_2_1"' ENGINE = SPIDER)
INSERT INTO tbl_person VALUES ('24FC3F0A5119432BAE13DD65AABAA39C',
'1', '123-51041110620301-321', 510411);
INSERT INTO tbl_person VALUES ('123456789012345678901234567890AB',
'1', '123-51041110620301-321', 510411);
INSERT INTO tbl_ncd_cm_person VALUES ('123456789',
'24FC3F0A5119432BAE13DD65AABAA39C',
'52A0328740914BCE86ED10A4D2521816',
510411);
INSERT INTO tbl_ncd_cm_person VALUES ('123456789AB',
'123456789012345678901234567890AB',
'52A0328740914BCE86ED10A4D2521816',
510411);
DELETE FROM tbl_ncd_cm_person;
INSERT INTO tbl_ncd_cm_person VALUES ('123456789',
'24FC3F0A5119432BAE13DD65AABAA39C',
'52A0328740914BCE86ED10A4D2521816',
510411);
INSERT INTO tbl_ncd_cm_person VALUES ('123456789AB',
'123456789012345678901234567890AB',
'52A0328740914BCE86ED10A4D2521816',
510411);
connection child2_1;
TRUNCATE TABLE mysql.general_log;
connection master_1;
SELECT count(0) FROM tbl_person tp INNER JOIN tbl_ncd_cm_person tncp ON tp.id = tncp.person_id WHERE 1 = 1 AND tp.hr_status != "99" AND tp.hr_status != "2" AND tp.region_code LIKE CONCAT(CONCAT('%', '51041110620301', '%')) AND tp.id = '24FC3F0A5119432BAE13DD65AABAA39C' AND tncp.diseaseKind_id = '52A0328740914BCE86ED10A4D2521816' AND tp.region = 510411;
count(0)
1
connection child2_1;
SELECT argument FROM mysql.general_log WHERE argument LIKE '%select %';
argument
select `id`,`hr_status`,`region_code`,`region` from `auto_test_remote`.`tbl_person` where `id` = '24FC3F0A5119432BAE13DD65AABAA39C' and `region` = 510411
select `person_id`,`diseaseKind_id` from `auto_test_remote`.`tbl_ncd_cm_person` where ((`diseaseKind_id` = '52A0328740914BCE86ED10A4D2521816'))
SELECT argument FROM mysql.general_log WHERE argument LIKE '%select %'
SELECT * FROM tbl_person;
id hr_status region_code region
123456789012345678901234567890AB 1 123-51041110620301-321 510411
24FC3F0A5119432BAE13DD65AABAA39C 1 123-51041110620301-321 510411
SELECT * FROM tbl_ncd_cm_person;
id person_id diseaseKind_id region
123456789 24FC3F0A5119432BAE13DD65AABAA39C 52A0328740914BCE86ED10A4D2521816 510411
123456789AB 123456789012345678901234567890AB 52A0328740914BCE86ED10A4D2521816 510411
deinit deinit
connection master_1; connection master_1;
DROP DATABASE IF EXISTS auto_test_local; DROP DATABASE IF EXISTS auto_test_local;
......
...@@ -177,6 +177,152 @@ if ($USE_CHILD_GROUP2) ...@@ -177,6 +177,152 @@ if ($USE_CHILD_GROUP2)
} }
} }
--echo
--echo Test JOIN on a constant table.
--echo Spider should NOT push down the join because the tbl_person table
--echo is optimized as a constant table.
if ($USE_CHILD_GROUP2)
{
if (!$OUTPUT_CHILD_GROUP2)
{
--disable_query_log
--disable_result_log
}
--connection child2_1
if ($OUTPUT_CHILD_GROUP2)
{
--disable_query_log
echo CHILD2_1_DROP_CONST_TABLE_JOIN;
echo CHILD2_1_DROP_CONST_TABLE2_JOIN;
echo CHILD2_1_CREATE_CONST_TABLE_JOIN;
echo CHILD2_1_CREATE_CONST_TABLE2_JOIN;
}
--disable_warnings
eval $CHILD2_1_DROP_CONST_TABLE_JOIN;
eval $CHILD2_1_DROP_CONST_TABLE2_JOIN;
--enable_warnings
eval $CHILD2_1_CREATE_CONST_TABLE_JOIN;
eval $CHILD2_1_CREATE_CONST_TABLE2_JOIN;
if ($OUTPUT_CHILD_GROUP2)
{
--enable_query_log
}
if ($USE_GENERAL_LOG)
{
TRUNCATE TABLE mysql.general_log;
}
if (!$OUTPUT_CHILD_GROUP2)
{
--enable_query_log
--enable_result_log
}
}
--connection master_1
--disable_warnings
DROP TABLE IF EXISTS tbl_person;
DROP TABLE IF EXISTS tbl_ncd_cm_person;
--enable_warnings
--disable_query_log
echo CREATE TABLE tbl_person (
id VARCHAR(50) NOT NULL,
hr_status VARCHAR(50) NULL DEFAULT NULL,
region_code VARCHAR(50) NULL DEFAULT NULL,
region INT(11) NOT NULL,
PRIMARY KEY (id, region) USING BTREE
) MASTER_1_ENGINE MASTER_1_CHARSET MASTER_1_COMMENT_CONST_TABLE_JOIN
MASTER_1_ROW_FORMAT_CONST_TABLE_JOIN MASTER_1_PART_CONST_TABLE_JOIN;
eval CREATE TABLE tbl_person (
id VARCHAR(50) NOT NULL,
hr_status VARCHAR(50) NULL DEFAULT NULL,
region_code VARCHAR(50) NULL DEFAULT NULL,
region INT(11) NOT NULL,
PRIMARY KEY (id, region) USING BTREE
) $MASTER_1_ENGINE $MASTER_1_CHARSET $MASTER_1_COMMENT_CONST_TABLE_JOIN
$MASTER_1_ROW_FORMAT_CONST_TABLE_JOIN $MASTER_1_PART_CONST_TABLE_JOIN;
echo SHOW CREATE TABLE tbl_person;
SHOW CREATE TABLE tbl_person;
echo CREATE TABLE tbl_ncd_cm_person (
id VARCHAR(50) NOT NULL,
person_id VARCHAR(50) NULL DEFAULT '',
diseaseKind_id VARCHAR(50) NULL DEFAULT NULL,
region INT(11) NOT NULL,
PRIMARY KEY (id, region) USING BTREE
) MASTER_1_ENGINE MASTER_1_CHARSET MASTER_1_COMMENT_CONST_TABLE2_JOIN
MASTER_1_ROW_FORMAT_CONST_TABLE_JOIN MASTER_1_PART_CONST_TABLE2_JOIN;
eval CREATE TABLE tbl_ncd_cm_person (
id VARCHAR(50) NOT NULL,
person_id VARCHAR(50) NULL DEFAULT '',
diseaseKind_id VARCHAR(50) NULL DEFAULT NULL,
region INT(11) NOT NULL,
PRIMARY KEY (id, region) USING BTREE
) $MASTER_1_ENGINE $MASTER_1_CHARSET $MASTER_1_COMMENT_CONST_TABLE2_JOIN
$MASTER_1_ROW_FORMAT_CONST_TABLE_JOIN $MASTER_1_PART_CONST_TABLE2_JOIN;
echo SHOW CREATE TABLE tbl_ncd_cm_person;
SHOW CREATE TABLE tbl_ncd_cm_person;
--enable_query_log
INSERT INTO tbl_person VALUES ('24FC3F0A5119432BAE13DD65AABAA39C',
'1', '123-51041110620301-321', 510411);
INSERT INTO tbl_person VALUES ('123456789012345678901234567890AB',
'1', '123-51041110620301-321', 510411);
INSERT INTO tbl_ncd_cm_person VALUES ('123456789',
'24FC3F0A5119432BAE13DD65AABAA39C',
'52A0328740914BCE86ED10A4D2521816',
510411);
INSERT INTO tbl_ncd_cm_person VALUES ('123456789AB',
'123456789012345678901234567890AB',
'52A0328740914BCE86ED10A4D2521816',
510411);
DELETE FROM tbl_ncd_cm_person;
INSERT INTO tbl_ncd_cm_person VALUES ('123456789',
'24FC3F0A5119432BAE13DD65AABAA39C',
'52A0328740914BCE86ED10A4D2521816',
510411);
INSERT INTO tbl_ncd_cm_person VALUES ('123456789AB',
'123456789012345678901234567890AB',
'52A0328740914BCE86ED10A4D2521816',
510411);
if ($USE_CHILD_GROUP2)
{
if (!$OUTPUT_CHILD_GROUP2)
{
--disable_query_log
--disable_result_log
}
--connection child2_1
if ($USE_GENERAL_LOG)
{
TRUNCATE TABLE mysql.general_log;
}
if (!$OUTPUT_CHILD_GROUP2)
{
--enable_query_log
--enable_result_log
}
}
--connection master_1
SELECT count(0) FROM tbl_person tp INNER JOIN tbl_ncd_cm_person tncp ON tp.id = tncp.person_id WHERE 1 = 1 AND tp.hr_status != "99" AND tp.hr_status != "2" AND tp.region_code LIKE CONCAT(CONCAT('%', '51041110620301', '%')) AND tp.id = '24FC3F0A5119432BAE13DD65AABAA39C' AND tncp.diseaseKind_id = '52A0328740914BCE86ED10A4D2521816' AND tp.region = 510411;
if ($USE_CHILD_GROUP2)
{
if (!$OUTPUT_CHILD_GROUP2)
{
--disable_query_log
--disable_result_log
}
--connection child2_1
if ($USE_GENERAL_LOG)
{
eval $CHILD2_1_SELECT_ARGUMENT1;
}
eval $CHILD2_1_SELECT_CONST_TABLE_JOIN;
eval $CHILD2_1_SELECT_CONST_TABLE2_JOIN;
if (!$OUTPUT_CHILD_GROUP2)
{
--enable_query_log
--enable_result_log
}
}
--echo --echo
--echo deinit --echo deinit
--disable_warnings --disable_warnings
......
...@@ -697,6 +697,7 @@ class spider_fields ...@@ -697,6 +697,7 @@ class spider_fields
SPIDER_TABLE_HOLDER *add_table( SPIDER_TABLE_HOLDER *add_table(
ha_spider *spider_arg ha_spider *spider_arg
); );
bool all_query_fields_are_query_table_members();
int create_table_holder( int create_table_holder(
uint table_count_arg uint table_count_arg
); );
......
...@@ -911,6 +911,35 @@ SPIDER_TABLE_HOLDER *spider_fields::add_table( ...@@ -911,6 +911,35 @@ SPIDER_TABLE_HOLDER *spider_fields::add_table(
DBUG_RETURN(return_table_holder); DBUG_RETURN(return_table_holder);
} }
/**
Verify that all fields in the query are members of tables that are in the
query.
@return TRUE All fields in the query are members of tables
that are in the query.
FALSE At least one field in the query is not a
member of a table that is in the query.
*/
bool spider_fields::all_query_fields_are_query_table_members()
{
SPIDER_FIELD_HOLDER *field_holder;
DBUG_ENTER("spider_fields::all_fields_are_query_table_fields");
DBUG_PRINT("info", ("spider this=%p", this));
set_pos_to_first_field_holder();
while ((field_holder = get_next_field_holder()))
{
if (!field_holder->spider)
{
DBUG_PRINT("info", ("spider field is not a member of a query table"));
DBUG_RETURN(FALSE);
}
}
DBUG_RETURN(TRUE);
}
int spider_fields::create_table_holder( int spider_fields::create_table_holder(
uint table_count_arg uint table_count_arg
) { ) {
...@@ -1997,6 +2026,13 @@ group_by_handler *spider_create_group_by_handler( ...@@ -1997,6 +2026,13 @@ group_by_handler *spider_create_group_by_handler(
} }
} }
if (!fields->all_query_fields_are_query_table_members())
{
DBUG_PRINT("info", ("spider found a query field that is not a query table member"));
delete fields;
DBUG_RETURN(NULL);
}
fields->check_support_dbton(dbton_bitmap); fields->check_support_dbton(dbton_bitmap);
if (!fields->has_conn_holder()) if (!fields->has_conn_holder())
{ {
......
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