summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKonstantin Osipov <kostja@sun.com>2010-07-02 19:21:07 +0400
committerKonstantin Osipov <kostja@sun.com>2010-07-02 19:21:07 +0400
commit1afe6ff03aea2be84b3d060d78a091a040c93496 (patch)
tree95a71247e440a3906787d5e6df3a8e6ef72051a7
parent8e154c93ab1df7a488fea44dee67bab66c107599 (diff)
downloadmariadb-git-1afe6ff03aea2be84b3d060d78a091a040c93496.tar.gz
A test case for Bug#50788 "main.merge fails on HPUX",
and a backport of relevant changes from the 6.0 version of the fix done by Ingo Struewing. The bug itself was fixed by the patch for Bug#54811. MyISAMMRG engine would try to use MMAP on its children even on platforms that don't support it and even if myisam_use_mmap option was off. This lead to an infinite hang in INSERT ... SELECT into a MyISAMMRG table when the destination MyISAM table was also selected from. A bug in duplicate detection fixed by 54811 was essential to the hang - when a duplicate is detected, the optimizer disables the use of memory mapped files, and it wasn't the case. The patch below is also to not turn on MMAP on children tables if myisam_use_mmap is off. A test case is added to cover MyISAMMRG and myisam_use_mmap option. mysql-test/r/merge_mmap.result: Result file - Bug#50788. mysql-test/t/merge_mmap-master.opt: An option file for the test for Bug#50788 -- use mmap. mysql-test/t/merge_mmap.test: Try INSERT ... SELECT into a merge table when myisam_use_mmap is on (Bug#50788). storage/myisam/mi_statrec.c: Fixed misinterpretation of the return value of my_b_read(). storage/myisammrg/ha_myisammrg.cc: Skip HA_EXTRA_MMAP if MyISAM memory mapping is disabled.
-rw-r--r--mysql-test/r/merge_mmap.result64
-rw-r--r--mysql-test/t/merge_mmap-master.opt1
-rw-r--r--mysql-test/t/merge_mmap.test60
-rw-r--r--storage/myisam/mi_statrec.c13
-rw-r--r--storage/myisammrg/ha_myisammrg.cc2
5 files changed, 138 insertions, 2 deletions
diff --git a/mysql-test/r/merge_mmap.result b/mysql-test/r/merge_mmap.result
new file mode 100644
index 00000000000..d975a1be377
--- /dev/null
+++ b/mysql-test/r/merge_mmap.result
@@ -0,0 +1,64 @@
+SET GLOBAL storage_engine = MyISAM;
+SET SESSION storage_engine = MyISAM;
+DROP TABLE IF EXISTS t1, t2, m1, m2;
+CREATE TABLE t1 (c1 INT);
+CREATE TABLE t2 (c1 INT);
+CREATE TABLE m1 (c1 INT) ENGINE=MRG_MyISAM UNION=(t1,t2)
+INSERT_METHOD=LAST;
+CREATE TABLE m2 (c1 INT) ENGINE=MRG_MyISAM UNION=(t1,t2)
+INSERT_METHOD=LAST;
+INSERT INTO t1 VALUES (1);
+INSERT INTO t2 VALUES (2), (3), (4);
+INSERT INTO m2 SELECT * FROM m1;
+SELECT * FROM m2;
+c1
+1
+2
+3
+4
+1
+2
+3
+4
+SELECT * FROM t2;
+c1
+2
+3
+4
+1
+2
+3
+4
+DROP TABLE m2, m1, t2, t1;
+CREATE TABLE t1 (c1 INT);
+CREATE TABLE t2 (c1 INT);
+CREATE TABLE m1 (c1 INT) ENGINE=MRG_MyISAM UNION=(t1,t2)
+INSERT_METHOD=LAST;
+CREATE TABLE m2 (c1 INT) ENGINE=MRG_MyISAM UNION=(t1,t2)
+INSERT_METHOD=LAST;
+LOCK TABLE m1 WRITE, m2 WRITE;
+INSERT INTO t1 VALUES (1);
+INSERT INTO t2 VALUES (2), (3), (4);
+INSERT INTO m2 SELECT * FROM m1;
+SELECT * FROM m2;
+c1
+1
+2
+3
+4
+1
+2
+3
+4
+SELECT * FROM t2;
+c1
+2
+3
+4
+1
+2
+3
+4
+UNLOCK TABLES;
+DROP TABLE m2, m1, t2, t1;
+End of 6.0 tests
diff --git a/mysql-test/t/merge_mmap-master.opt b/mysql-test/t/merge_mmap-master.opt
new file mode 100644
index 00000000000..9606fb57187
--- /dev/null
+++ b/mysql-test/t/merge_mmap-master.opt
@@ -0,0 +1 @@
+--myisam-use-mmap
diff --git a/mysql-test/t/merge_mmap.test b/mysql-test/t/merge_mmap.test
new file mode 100644
index 00000000000..3468702ca45
--- /dev/null
+++ b/mysql-test/t/merge_mmap.test
@@ -0,0 +1,60 @@
+#
+# Test of MERGE TABLES with MyISAM memory mapping enabled (--myisam-use-mmap)
+#
+
+# MERGE tables require MyISAM tables
+--let $default=`SELECT @@global.storage_engine`
+SET GLOBAL storage_engine = MyISAM;
+SET SESSION storage_engine = MyISAM;
+
+# Clean up resources used in this test case.
+--disable_warnings
+DROP TABLE IF EXISTS t1, t2, m1, m2;
+--enable_warnings
+
+####################
+## No locked tables.
+####################
+#
+# INSERT-SELECT with no TEMPORARY table.
+#
+CREATE TABLE t1 (c1 INT);
+CREATE TABLE t2 (c1 INT);
+CREATE TABLE m1 (c1 INT) ENGINE=MRG_MyISAM UNION=(t1,t2)
+ INSERT_METHOD=LAST;
+CREATE TABLE m2 (c1 INT) ENGINE=MRG_MyISAM UNION=(t1,t2)
+ INSERT_METHOD=LAST;
+INSERT INTO t1 VALUES (1);
+INSERT INTO t2 VALUES (2), (3), (4);
+INSERT INTO m2 SELECT * FROM m1;
+SELECT * FROM m2;
+SELECT * FROM t2;
+DROP TABLE m2, m1, t2, t1;
+
+####################
+## With LOCK TABLES.
+####################
+#
+# INSERT-SELECT with no TEMPORARY table.
+#
+CREATE TABLE t1 (c1 INT);
+CREATE TABLE t2 (c1 INT);
+CREATE TABLE m1 (c1 INT) ENGINE=MRG_MyISAM UNION=(t1,t2)
+ INSERT_METHOD=LAST;
+CREATE TABLE m2 (c1 INT) ENGINE=MRG_MyISAM UNION=(t1,t2)
+ INSERT_METHOD=LAST;
+LOCK TABLE m1 WRITE, m2 WRITE;
+INSERT INTO t1 VALUES (1);
+INSERT INTO t2 VALUES (2), (3), (4);
+INSERT INTO m2 SELECT * FROM m1;
+SELECT * FROM m2;
+SELECT * FROM t2;
+UNLOCK TABLES;
+DROP TABLE m2, m1, t2, t1;
+--echo End of 6.0 tests
+
+--disable_result_log
+--disable_query_log
+eval SET GLOBAL storage_engine = $default;
+--enable_result_log
+--enable_query_log
diff --git a/storage/myisam/mi_statrec.c b/storage/myisam/mi_statrec.c
index 7d595916d78..f83afa3c886 100644
--- a/storage/myisam/mi_statrec.c
+++ b/storage/myisam/mi_statrec.c
@@ -298,8 +298,17 @@ int _mi_read_rnd_static_record(MI_INFO *info, uchar *buf,
info->update|= HA_STATE_AKTIV | HA_STATE_KEY_CHANGED;
DBUG_RETURN(0);
}
- /* my_errno should be set if rec_cache.error == -1 */
+ /* error is TRUE. my_errno should be set if rec_cache.error == -1 */
if (info->rec_cache.error != -1 || my_errno == 0)
- my_errno=HA_ERR_WRONG_IN_RECORD;
+ {
+ /*
+ If we could not get a full record, we either have a broken record,
+ or are at end of file.
+ */
+ if (info->rec_cache.error == 0)
+ my_errno= HA_ERR_END_OF_FILE;
+ else
+ my_errno= HA_ERR_WRONG_IN_RECORD;
+ }
DBUG_RETURN(my_errno); /* Something wrong (EOF?) */
}
diff --git a/storage/myisammrg/ha_myisammrg.cc b/storage/myisammrg/ha_myisammrg.cc
index 67b81225b13..1681f062117 100644
--- a/storage/myisammrg/ha_myisammrg.cc
+++ b/storage/myisammrg/ha_myisammrg.cc
@@ -1322,6 +1322,8 @@ int ha_myisammrg::extra(enum ha_extra_function operation)
if (operation == HA_EXTRA_FORCE_REOPEN ||
operation == HA_EXTRA_PREPARE_FOR_DROP)
return 0;
+ if (operation == HA_EXTRA_MMAP && !opt_myisam_use_mmap)
+ return 0;
return myrg_extra(file,operation,0);
}