Commit 62933c50 authored by Sergey Vojtovich's avatar Sergey Vojtovich

BUG#49628 - corrupt table after legal SQL, LONGTEXT column

Bulk REPLACE or bulk INSERT ... ON DUPLICATE KEY UPDATE may
break dynamic record MyISAM table.

The problem is limited to bulk REPLACE and INSERT ... ON
DUPLICATE KEY UPDATE, because only these operations may
be done via UPDATE internally and may request write cache.

When flushing write cache, MyISAM may write remaining
cached data at wrong position. Fixed by requesting write
cache to seek to a correct position.

mysql-test/r/myisam.result:
  A test case for BUG#49628.
mysql-test/t/myisam.test:
  A test case for BUG#49628.
storage/myisam/mi_dynrec.c:
  delete_dynamic_record() may change data file position.
  IO cache must be notified as it may still have cached
  data, which has to be flushed later.
parent 3ad5d21e
...@@ -2313,4 +2313,17 @@ CHECK TABLE t1; ...@@ -2313,4 +2313,17 @@ CHECK TABLE t1;
Table Op Msg_type Msg_text Table Op Msg_type Msg_text
test.t1 check status OK test.t1 check status OK
DROP TABLE t1; DROP TABLE t1;
#
# BUG#49628 - corrupt table after legal SQL, LONGTEXT column
#
CREATE TABLE t1(a INT, b LONGTEXT, UNIQUE(a));
REPLACE INTO t1 VALUES
(1, REPEAT('a', 129015)),(1, NULL),
(2, NULL),(3, NULL),(4, NULL),(5, NULL),(6, NULL),(7, NULL),
(1, REPEAT('b', 129016)),(1, NULL),
(1, REPEAT('c', 129015)),(1, REPEAT('d', 129015));
CHECK TABLE t1;
Table Op Msg_type Msg_text
test.t1 check status OK
DROP TABLE t1;
End of 5.1 tests End of 5.1 tests
...@@ -1563,5 +1563,18 @@ SET myisam_sort_buffer_size=@@global.myisam_sort_buffer_size; ...@@ -1563,5 +1563,18 @@ SET myisam_sort_buffer_size=@@global.myisam_sort_buffer_size;
CHECK TABLE t1; CHECK TABLE t1;
DROP TABLE t1; DROP TABLE t1;
--echo #
--echo # BUG#49628 - corrupt table after legal SQL, LONGTEXT column
--echo #
CREATE TABLE t1(a INT, b LONGTEXT, UNIQUE(a));
REPLACE INTO t1 VALUES
(1, REPEAT('a', 129015)),(1, NULL),
(2, NULL),(3, NULL),(4, NULL),(5, NULL),(6, NULL),(7, NULL),
(1, REPEAT('b', 129016)),(1, NULL),
(1, REPEAT('c', 129015)),(1, REPEAT('d', 129015));
CHECK TABLE t1;
DROP TABLE t1;
--echo End of 5.1 tests --echo End of 5.1 tests
...@@ -933,8 +933,16 @@ static int update_dynamic_record(MI_INFO *info, my_off_t filepos, uchar *record, ...@@ -933,8 +933,16 @@ static int update_dynamic_record(MI_INFO *info, my_off_t filepos, uchar *record,
} }
if (block_info.next_filepos != HA_OFFSET_ERROR) if (block_info.next_filepos != HA_OFFSET_ERROR)
{
/*
delete_dynamic_record() may change data file position.
IO cache must be notified as it may still have cached
data, which has to be flushed later.
*/
info->rec_cache.seek_not_done= 1;
if (delete_dynamic_record(info,block_info.next_filepos,1)) if (delete_dynamic_record(info,block_info.next_filepos,1))
goto err; goto err;
}
DBUG_RETURN(0); DBUG_RETURN(0);
err: err:
DBUG_RETURN(1); DBUG_RETURN(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