summaryrefslogtreecommitdiff
path: root/mysql-test
diff options
context:
space:
mode:
authorSergei Petrunia <psergey@askmonty.org>2019-11-15 23:37:28 +0300
committerSergei Petrunia <psergey@askmonty.org>2019-11-15 23:37:28 +0300
commit86167e908fe5de6f6e9f5076b4ea8041514d0820 (patch)
tree92815b55b229fb7ce4b55eb176e2ebc19e3b8985 /mysql-test
parent3d4a80153345209bad736235d4f66dcaa51a9d51 (diff)
downloadmariadb-git-86167e908fe5de6f6e9f5076b4ea8041514d0820.tar.gz
MDEV-20611: MRR scan over partitioned InnoDB table produces "Out of memory" error
Fix partitioning and DS-MRR to work together - In ha_partition::index_end(): take into account that ha_innobase (and other engines using DS-MRR) will have inited=RND when initialized for DS-MRR scan. - In ha_partition::multi_range_read_next(): if the MRR scan is using HA_MRR_NO_ASSOCIATION mode, it is not guaranteed that the partition's handler will store anything into *range_info. - In DsMrr_impl::choose_mrr_impl(): ha_partition will inquire partitions about how much memory their MRR implementation needs by passing *buffer_size=0. DS-MRR code didn't know about this (actually it used uint for buffer size calculation and would have an under-flow). Returning *buffer_size=0 made ha_partition assume that partitions do not need MRR memory and pass the same buffer to each of them. Now, this is fixed. If DS-MRR gets *buffer_size=0, it will return the amount of buffer space needed, but not more than about @@mrr_buffer_size. * Fix ha_{innobase,maria,myisam}::clone. If ha_partition uses MRR on its partitions, and partition use DS-MRR, the code will call handler->clone with TABLE (*NOT partition*) name as an argument. DS-MRR has no way of knowing the partition name, so the solution was to have the ::clone() function for the affected storage engine to ignore the name argument and get it elsewhere.
Diffstat (limited to 'mysql-test')
-rw-r--r--mysql-test/include/partition_mrr.inc46
-rw-r--r--mysql-test/main/partition_mrr_aria.result79
-rw-r--r--mysql-test/main/partition_mrr_aria.test2
-rw-r--r--mysql-test/main/partition_mrr_innodb.result79
-rw-r--r--mysql-test/main/partition_mrr_innodb.test4
-rw-r--r--mysql-test/main/partition_mrr_myisam.result79
-rw-r--r--mysql-test/main/partition_mrr_myisam.test3
7 files changed, 292 insertions, 0 deletions
diff --git a/mysql-test/include/partition_mrr.inc b/mysql-test/include/partition_mrr.inc
new file mode 100644
index 00000000000..4c285791ec7
--- /dev/null
+++ b/mysql-test/include/partition_mrr.inc
@@ -0,0 +1,46 @@
+--source include/have_partition.inc
+
+--disable_warnings
+drop table if exists t1,t3;
+--enable_warnings
+
+--echo #
+--echo # MDEV-20611: MRR scan over partitioned InnoDB table produces "Out of memory" error
+--echo #
+create table t1(a int);
+insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+
+set @tmp=@@storage_engine;
+eval set storage_engine=$engine_type;
+
+create table t3 (
+ ID bigint(20) NOT NULL AUTO_INCREMENT,
+ part_id int,
+ key_col int,
+ col2 int,
+ key(key_col),
+ PRIMARY KEY (ID,part_id)
+) PARTITION BY RANGE (part_id)
+(PARTITION p1 VALUES LESS THAN (3),
+ PARTITION p2 VALUES LESS THAN (7),
+ PARTITION p3 VALUES LESS THAN (10)
+);
+
+show create table t3;
+set storage_engine= @tmp;
+
+insert into t3 select
+ A.a+10*B.a,
+ A.a,
+ B.a,
+ 123456
+from t1 A, t1 B;
+
+set optimizer_switch='mrr=on';
+--replace_column 9 #
+explain
+select * from t3 force index (key_col) where key_col < 3;
+select * from t3 force index (key_col) where key_col < 3;
+
+drop table t1,t3;
+
diff --git a/mysql-test/main/partition_mrr_aria.result b/mysql-test/main/partition_mrr_aria.result
new file mode 100644
index 00000000000..7a0c35a309e
--- /dev/null
+++ b/mysql-test/main/partition_mrr_aria.result
@@ -0,0 +1,79 @@
+drop table if exists t1,t3;
+#
+# MDEV-20611: MRR scan over partitioned InnoDB table produces "Out of memory" error
+#
+create table t1(a int);
+insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+set @tmp=@@storage_engine;
+set storage_engine=Aria;
+create table t3 (
+ID bigint(20) NOT NULL AUTO_INCREMENT,
+part_id int,
+key_col int,
+col2 int,
+key(key_col),
+PRIMARY KEY (ID,part_id)
+) PARTITION BY RANGE (part_id)
+(PARTITION p1 VALUES LESS THAN (3),
+PARTITION p2 VALUES LESS THAN (7),
+PARTITION p3 VALUES LESS THAN (10)
+);
+show create table t3;
+Table Create Table
+t3 CREATE TABLE `t3` (
+ `ID` bigint(20) NOT NULL AUTO_INCREMENT,
+ `part_id` int(11) NOT NULL,
+ `key_col` int(11) DEFAULT NULL,
+ `col2` int(11) DEFAULT NULL,
+ PRIMARY KEY (`ID`,`part_id`),
+ KEY `key_col` (`key_col`)
+) ENGINE=Aria DEFAULT CHARSET=latin1
+ PARTITION BY RANGE (`part_id`)
+(PARTITION `p1` VALUES LESS THAN (3) ENGINE = Aria,
+ PARTITION `p2` VALUES LESS THAN (7) ENGINE = Aria,
+ PARTITION `p3` VALUES LESS THAN (10) ENGINE = Aria)
+set storage_engine= @tmp;
+insert into t3 select
+A.a+10*B.a,
+A.a,
+B.a,
+123456
+from t1 A, t1 B;
+set optimizer_switch='mrr=on';
+explain
+select * from t3 force index (key_col) where key_col < 3;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t3 range key_col key_col 5 NULL # Using where; Rowid-ordered scan
+select * from t3 force index (key_col) where key_col < 3;
+ID part_id key_col col2
+1 0 0 123456
+1 1 0 123456
+2 2 0 123456
+10 0 1 123456
+11 1 1 123456
+12 2 1 123456
+20 0 2 123456
+21 1 2 123456
+22 2 2 123456
+3 3 0 123456
+4 4 0 123456
+5 5 0 123456
+6 6 0 123456
+13 3 1 123456
+14 4 1 123456
+15 5 1 123456
+16 6 1 123456
+23 3 2 123456
+24 4 2 123456
+25 5 2 123456
+26 6 2 123456
+7 7 0 123456
+8 8 0 123456
+9 9 0 123456
+17 7 1 123456
+18 8 1 123456
+19 9 1 123456
+27 7 2 123456
+28 8 2 123456
+29 9 2 123456
+drop table t1,t3;
diff --git a/mysql-test/main/partition_mrr_aria.test b/mysql-test/main/partition_mrr_aria.test
new file mode 100644
index 00000000000..e3dfe8cd9b5
--- /dev/null
+++ b/mysql-test/main/partition_mrr_aria.test
@@ -0,0 +1,2 @@
+let $engine_type= Aria;
+--source include/partition_mrr.inc
diff --git a/mysql-test/main/partition_mrr_innodb.result b/mysql-test/main/partition_mrr_innodb.result
new file mode 100644
index 00000000000..c188f7e9929
--- /dev/null
+++ b/mysql-test/main/partition_mrr_innodb.result
@@ -0,0 +1,79 @@
+drop table if exists t1,t3;
+#
+# MDEV-20611: MRR scan over partitioned InnoDB table produces "Out of memory" error
+#
+create table t1(a int);
+insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+set @tmp=@@storage_engine;
+set storage_engine=InnoDB;
+create table t3 (
+ID bigint(20) NOT NULL AUTO_INCREMENT,
+part_id int,
+key_col int,
+col2 int,
+key(key_col),
+PRIMARY KEY (ID,part_id)
+) PARTITION BY RANGE (part_id)
+(PARTITION p1 VALUES LESS THAN (3),
+PARTITION p2 VALUES LESS THAN (7),
+PARTITION p3 VALUES LESS THAN (10)
+);
+show create table t3;
+Table Create Table
+t3 CREATE TABLE `t3` (
+ `ID` bigint(20) NOT NULL AUTO_INCREMENT,
+ `part_id` int(11) NOT NULL,
+ `key_col` int(11) DEFAULT NULL,
+ `col2` int(11) DEFAULT NULL,
+ PRIMARY KEY (`ID`,`part_id`),
+ KEY `key_col` (`key_col`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+ PARTITION BY RANGE (`part_id`)
+(PARTITION `p1` VALUES LESS THAN (3) ENGINE = InnoDB,
+ PARTITION `p2` VALUES LESS THAN (7) ENGINE = InnoDB,
+ PARTITION `p3` VALUES LESS THAN (10) ENGINE = InnoDB)
+set storage_engine= @tmp;
+insert into t3 select
+A.a+10*B.a,
+A.a,
+B.a,
+123456
+from t1 A, t1 B;
+set optimizer_switch='mrr=on';
+explain
+select * from t3 force index (key_col) where key_col < 3;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t3 range key_col key_col 5 NULL # Using where; Rowid-ordered scan
+select * from t3 force index (key_col) where key_col < 3;
+ID part_id key_col col2
+1 0 0 123456
+1 1 0 123456
+2 2 0 123456
+10 0 1 123456
+11 1 1 123456
+12 2 1 123456
+20 0 2 123456
+21 1 2 123456
+22 2 2 123456
+3 3 0 123456
+4 4 0 123456
+5 5 0 123456
+6 6 0 123456
+13 3 1 123456
+14 4 1 123456
+15 5 1 123456
+16 6 1 123456
+23 3 2 123456
+24 4 2 123456
+25 5 2 123456
+26 6 2 123456
+7 7 0 123456
+8 8 0 123456
+9 9 0 123456
+17 7 1 123456
+18 8 1 123456
+19 9 1 123456
+27 7 2 123456
+28 8 2 123456
+29 9 2 123456
+drop table t1,t3;
diff --git a/mysql-test/main/partition_mrr_innodb.test b/mysql-test/main/partition_mrr_innodb.test
new file mode 100644
index 00000000000..1eccf070e5c
--- /dev/null
+++ b/mysql-test/main/partition_mrr_innodb.test
@@ -0,0 +1,4 @@
+--source include/have_innodb.inc
+let $engine_type= InnoDB;
+
+--source include/partition_mrr.inc
diff --git a/mysql-test/main/partition_mrr_myisam.result b/mysql-test/main/partition_mrr_myisam.result
new file mode 100644
index 00000000000..1f1cea8e9d6
--- /dev/null
+++ b/mysql-test/main/partition_mrr_myisam.result
@@ -0,0 +1,79 @@
+drop table if exists t1,t3;
+#
+# MDEV-20611: MRR scan over partitioned InnoDB table produces "Out of memory" error
+#
+create table t1(a int);
+insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+set @tmp=@@storage_engine;
+set storage_engine=myisam;
+create table t3 (
+ID bigint(20) NOT NULL AUTO_INCREMENT,
+part_id int,
+key_col int,
+col2 int,
+key(key_col),
+PRIMARY KEY (ID,part_id)
+) PARTITION BY RANGE (part_id)
+(PARTITION p1 VALUES LESS THAN (3),
+PARTITION p2 VALUES LESS THAN (7),
+PARTITION p3 VALUES LESS THAN (10)
+);
+show create table t3;
+Table Create Table
+t3 CREATE TABLE `t3` (
+ `ID` bigint(20) NOT NULL AUTO_INCREMENT,
+ `part_id` int(11) NOT NULL,
+ `key_col` int(11) DEFAULT NULL,
+ `col2` int(11) DEFAULT NULL,
+ PRIMARY KEY (`ID`,`part_id`),
+ KEY `key_col` (`key_col`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+ PARTITION BY RANGE (`part_id`)
+(PARTITION `p1` VALUES LESS THAN (3) ENGINE = MyISAM,
+ PARTITION `p2` VALUES LESS THAN (7) ENGINE = MyISAM,
+ PARTITION `p3` VALUES LESS THAN (10) ENGINE = MyISAM)
+set storage_engine= @tmp;
+insert into t3 select
+A.a+10*B.a,
+A.a,
+B.a,
+123456
+from t1 A, t1 B;
+set optimizer_switch='mrr=on';
+explain
+select * from t3 force index (key_col) where key_col < 3;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t3 range key_col key_col 5 NULL # Using where; Rowid-ordered scan
+select * from t3 force index (key_col) where key_col < 3;
+ID part_id key_col col2
+1 0 0 123456
+1 1 0 123456
+2 2 0 123456
+10 0 1 123456
+11 1 1 123456
+12 2 1 123456
+20 0 2 123456
+21 1 2 123456
+22 2 2 123456
+3 3 0 123456
+4 4 0 123456
+5 5 0 123456
+6 6 0 123456
+13 3 1 123456
+14 4 1 123456
+15 5 1 123456
+16 6 1 123456
+23 3 2 123456
+24 4 2 123456
+25 5 2 123456
+26 6 2 123456
+7 7 0 123456
+8 8 0 123456
+9 9 0 123456
+17 7 1 123456
+18 8 1 123456
+19 9 1 123456
+27 7 2 123456
+28 8 2 123456
+29 9 2 123456
+drop table t1,t3;
diff --git a/mysql-test/main/partition_mrr_myisam.test b/mysql-test/main/partition_mrr_myisam.test
new file mode 100644
index 00000000000..d67a37ab3d2
--- /dev/null
+++ b/mysql-test/main/partition_mrr_myisam.test
@@ -0,0 +1,3 @@
+let $engine_type= myisam;
+
+--source include/partition_mrr.inc