summaryrefslogtreecommitdiff
path: root/storage
diff options
context:
space:
mode:
authorunknown <guilhem@gbichot4.local>2007-08-07 18:23:49 +0200
committerunknown <guilhem@gbichot4.local>2007-08-07 18:23:49 +0200
commit1ad3a05dd7353cc7106d57de1acf777cbd0368c0 (patch)
tree137b548a8ed9b72170bf679c1130f88d4eafe384 /storage
parent72c3c369e4e86c89bc98bb9346fd4cd38ead4064 (diff)
downloadmariadb-git-1ad3a05dd7353cc7106d57de1acf777cbd0368c0.tar.gz
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.
Diffstat (limited to 'storage')
-rw-r--r--storage/maria/ma_check.c27
1 files changed, 18 insertions, 9 deletions
diff --git a/storage/maria/ma_check.c b/storage/maria/ma_check.c
index b7298abeaa0..3832b6f6fdd 100644
--- a/storage/maria/ma_check.c
+++ b/storage/maria/ma_check.c
@@ -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);
}