Commit 1afe6ff0 authored by Konstantin Osipov's avatar Konstantin Osipov

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.
parent 8e154c93
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
#
# 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
......@@ -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?) */
}
......@@ -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);
}
......
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