Commit 1ad3a05d authored by unknown's avatar unknown

Fix for errors during:

"./mtr --mysqld=--default-storage-engine=maria mysqldump".
First problem was use of INSERT DELAYED and MERGE tables without
specifying that the tables to create should always be MyISAM.
After fixing this, no rows were returned by the final SELECT of the
"BUG 19025" portion of the test. Simplified problem was:
LOCK TABLES `t1` WRITE;
/*!40000 ALTER TABLE `t1` DISABLE KEYS */;
INSERT INTO `t1` VALUES ('bla',1000),('bla',1001),('bla',1002);
/*!40000 ALTER TABLE `t1` ENABLE KEYS */;
UNLOCK TABLES;
select * from t1;
The SELECT would find no rows. Reason: ENABLE KEYS does a maria_repair();
but data pages are still in the page cache and not on disk (because
they were not flushed because maria_lock_database(F_UNLCK) was
not called at the end of INSERT because under LOCK TABLES).
At start of maria_repair(), sort_info.filelength is set to the
physical size of the data file (=> too small because pages are in
cache and not on disk).
Then in sort_get_next_record(), when seeing end-of-file, this is done:
sort_param->max_pos= sort_info->filelength;
Further in maria_repair(), this is done:
info->state->data_file_length= sort_param.max_pos;
and so data_file_length is smaller (0) than reality (16384).
This makes SELECT think EOF is where it is not, and thus find
no rows.
This is fixed by flushing all data pages at the start of maria_repair()
(no performance problem is introduced as in common cases where
ALTER TABLE is not under LOCK TABLES, the previous statement did
this flush anyway).
Another reason to do this flush is that, if not doing it, old cached
pages might go down onto the repaired data file at a later point
and thus corrupt it (assume a REPAIR non-QUICK).
A similar bug is fixed:
LOCK TABLES WRITE; INSERT; CHECK TABLE;
reports "Size of datafile is: 0         Should be: 16384"
again because the physical size was read without a preliminary
page cache flush.


mysql-test/r/maria.result:
  result update
mysql-test/r/mysqldump.result:
  result update
mysql-test/t/maria.test:
  adding test for fixed bug in LOCK TABLES + CHECK TABLE + block format.
  Disabling portion which hits "incorrect key file" but still
  letting it make the test fail (Monty to fix).
mysql-test/t/mysqldump.test:
  in places where test expects engine to support INSERT DELAYED and
  be includable in a MERGE table, i.e. be MyISAM, we explicitely
  ask for MyISAM.
storage/maria/ma_check.c:
  Before reading the data file's physical size with my_seek(MY_SEEK_END)
  during maria_chk_size() and maria_repair(), we must flush this
  data file, otherwise physical size is misleading and leads to
  - CHECK TABLE finding the table corrupted ("size of datafile should be"
  error)
  - ALTER TABLE ENABLE KEYS losing rows (maria_repair()
  setting data_file_length to a too small value => later SELECT does
  not find rows though they are in the data file).
  This fixes the "mysqldump.test" failure.
  sort_info.filelength contains the physical size, re-using it.
parent 72c3c369
......@@ -1860,3 +1860,15 @@ select count(*) from t1;
count(*)
1
drop table t1;
create table `t1` (
t1_name varchar(255) default null,
t1_id int(10) unsigned not null auto_increment,
key (t1_name),
primary key (t1_id)
) auto_increment = 1000 default charset=latin1;
lock tables t1 write;
INSERT INTO `t1` VALUES ('bla',1000),('bla',1001),('bla',1002);
check table t1;
Table Op Msg_type Msg_text
test.t1 check status OK
unlock tables;
......@@ -660,7 +660,7 @@ DROP TABLE t1;
#
# Test for --insert-ignore
#
CREATE TABLE t1 (a int);
CREATE TABLE t1 (a int) ENGINE=MyISAM;
INSERT INTO t1 VALUES (1),(2),(3);
INSERT INTO t1 VALUES (4),(5),(6);
......@@ -3443,8 +3443,8 @@ CREATE TABLE t1(a int);
INSERT INTO t1 VALUES (1), (2);
mysqldump: Input filename or options too long: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
DROP TABLE t1;
CREATE TABLE t2 (a int);
CREATE TABLE t3 (a int);
CREATE TABLE t2 (a int) ENGINE=MyISAM;
CREATE TABLE t3 (a int) ENGINE=MyISAM;
CREATE TABLE t1 (a int) ENGINE=merge UNION=(t2, t3);
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
......
......@@ -432,6 +432,9 @@ select concat(a,'.') from t1;
drop table t1;
# test again but with dynamic format
echo "Monty please enable the portion below, it gives error message";
if (0)
{
create table t1 ( a text not null, key a (a(20))) row_format=dynamic;
insert into t1 values ('aaa '),('aaa'),('aa');
check table t1;
......@@ -441,6 +444,7 @@ select concat(a,'.') from t1 where binary a='aaa';
update t1 set a='bbb' where a='aaa';
select concat(a,'.') from t1;
drop table t1;
}
#
# More space testing
......@@ -1151,6 +1155,19 @@ select * from t1;
select count(*) from t1;
drop table t1;
# CHECK TABLE was reporting
# "Size of datafile is: 0 Should be: 16384"
create table `t1` (
t1_name varchar(255) default null,
t1_id int(10) unsigned not null auto_increment,
key (t1_name),
primary key (t1_id)
) auto_increment = 1000 default charset=latin1;
lock tables t1 write;
INSERT INTO `t1` VALUES ('bla',1000),('bla',1001),('bla',1002);
check table t1;
unlock tables;
# End of 5.2 tests
--disable_result_log
......
......@@ -199,7 +199,7 @@ DROP TABLE t1;
--echo # Test for --insert-ignore
--echo #
CREATE TABLE t1 (a int);
CREATE TABLE t1 (a int) ENGINE=MyISAM;
INSERT INTO t1 VALUES (1),(2),(3);
INSERT INTO t1 VALUES (4),(5),(6);
--exec $MYSQL_DUMP --skip-comments --insert-ignore test t1
......@@ -1463,8 +1463,8 @@ DROP TABLE t1;
# Bug #25993: crashe with a merge table and -c
#
CREATE TABLE t2 (a int);
CREATE TABLE t3 (a int);
CREATE TABLE t2 (a int) ENGINE=MyISAM;
CREATE TABLE t3 (a int) ENGINE=MyISAM;
CREATE TABLE t1 (a int) ENGINE=merge UNION=(t2, t3);
--exec $MYSQL_DUMP --skip-comments -c test
DROP TABLE t1, t2, t3;
......
......@@ -332,7 +332,7 @@ static int check_k_link(HA_CHECK *param, register MARIA_HA *info,
int maria_chk_size(HA_CHECK *param, register MARIA_HA *info)
{
int error=0;
int error;
register my_off_t skr,size;
char buff[22],buff2[22];
DBUG_ENTER("maria_chk_size");
......@@ -340,9 +340,14 @@ int maria_chk_size(HA_CHECK *param, register MARIA_HA *info)
if (!(param->testflag & T_SILENT))
puts("- check file-size");
/* The following is needed if called externally (not from maria_chk) */
flush_pagecache_blocks(info->s->pagecache,
&info->s->kfile, FLUSH_FORCE_WRITE);
/*
The following is needed if called externally (not from maria_chk).
To get a correct physical size we need to flush them.
*/
if ((error= _ma_flush_table_files(info,
MARIA_FLUSH_DATA | MARIA_FLUSH_INDEX,
FLUSH_FORCE_WRITE, FLUSH_FORCE_WRITE)))
_ma_check_print_error(param, "Failed to flush data or index file");
size= my_seek(info->s->kfile.file, 0L, MY_SEEK_END, MYF(MY_THREADSAFE));
if ((skr=(my_off_t) info->state->key_file_length) != size)
......@@ -1983,6 +1988,14 @@ int maria_repair(HA_CHECK *param, register MARIA_HA *info,
if (info->s->options & (HA_OPTION_CHECKSUM | HA_OPTION_COMPRESS_RECORD))
param->testflag|=T_CALC_CHECKSUM;
/*
The physical size of the data file is sometimes used during repair (see
sort_info.filelength further below); we need to flush to have it exact.
*/
if (_ma_flush_table_files(info, MARIA_FLUSH_DATA, FLUSH_FORCE_WRITE,
FLUSH_KEEP))
goto err;
if (!rep_quick)
{
/* Get real path for data file */
......@@ -3757,11 +3770,7 @@ static int sort_get_next_record(MARIA_SORT_PARAM *sort_param)
Scan on clean table.
It requires a reliable data_file_length so we set it.
*/
my_off_t dfile_len= my_seek(info->dfile.file, 0, SEEK_END,
MYF(MY_WME));
if (dfile_len == MY_FILEPOS_ERROR)
DBUG_RETURN(my_errno);
info->state->data_file_length= dfile_len;
info->state->data_file_length= sort_info->filelength;
flag= _ma_scan_block_record(info, sort_param->record,
info->cur_row.nextpos, 1);
}
......
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