summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrei Elkin <andrei.elkin@mariadb.com>2018-09-17 21:40:23 +0300
committerAndrei Elkin <andrei.elkin@mariadb.com>2018-09-18 23:21:18 +0300
commit7ce7184cf0e354a1c9114bb31df1fb63b1fbbcc7 (patch)
tree05bea8150f383b49a1e3608acc6882f9245fbde8
parentd3a8b5aa9cee24a6397662e30df2e915f45460e0 (diff)
downloadmariadb-git-bb-10.1-MDEV-17133.tar.gz
MDEV-17133 dump thread reads from a past positionbb-10.1-MDEV-17133
-rw-r--r--mysys/mf_iocache.c8
-rw-r--r--unittest/sql/mf_iocache-t.cc74
2 files changed, 79 insertions, 3 deletions
diff --git a/mysys/mf_iocache.c b/mysys/mf_iocache.c
index 56b1ae3fc6e..8f829a8c9c2 100644
--- a/mysys/mf_iocache.c
+++ b/mysys/mf_iocache.c
@@ -563,7 +563,7 @@ int _my_b_write(IO_CACHE *info, const uchar *Buffer, size_t Count)
int _my_b_cache_read(IO_CACHE *info, uchar *Buffer, size_t Count)
{
- size_t length, diff_length, left_length= 0, max_length;
+ size_t length= 0, diff_length, left_length= 0, max_length;
my_off_t pos_in_file;
DBUG_ENTER("_my_b_cache_read");
@@ -668,7 +668,11 @@ int _my_b_cache_read(IO_CACHE *info, uchar *Buffer, size_t Count)
else
{
info->error= 0;
- DBUG_RETURN(0); /* EOF */
+ if (length == 0)
+ {
+ DBUG_RETURN(0); // EOF
+ }
+ length= 0;
}
}
else if ((length= mysql_file_read(info->file,info->buffer, max_length,
diff --git a/unittest/sql/mf_iocache-t.cc b/unittest/sql/mf_iocache-t.cc
index 8f97745f0fc..3de80ab83f9 100644
--- a/unittest/sql/mf_iocache-t.cc
+++ b/unittest/sql/mf_iocache-t.cc
@@ -285,11 +285,82 @@ void mdev14014()
close_cached_file(&info);
}
+void mdev17133()
+{
+ int res, eof_iter=16, read_iter= 16;
+ uchar buf_i[1024*256]; // read
+ uchar buf_o[sizeof(buf_i)]; // write
+ const size_t eof_block_size= sizeof(buf_o) / eof_iter;
+ const size_t read_size= eof_block_size / read_iter;
+ size_t total;
+
+ memset(buf_i, 0, sizeof( buf_i));
+ memset(buf_o, FILL, sizeof(buf_o));
+
+ diag("MDEV-17133 Dump thread reads from the past");
+
+ init_io_cache_encryption();
+
+ res= open_cached_file(&info, 0, 0, CACHE_SIZE, 0);
+ ok(res == 0, "open_cached_file" INFO_TAIL);
+
+ res= my_b_write(&info, buf_o, sizeof(buf_o));
+ ok(res == 0, "buffer is written" INFO_TAIL);
+ res= my_b_tell(&info);
+ ok(res == sizeof(buf_o), "cache size as expected");
+
+ res= my_b_flush_io_cache(&info, 1);
+ ok(res == 0, "flush" INFO_TAIL);
+ res= reinit_io_cache(&info, READ_CACHE, 0, 0, 0);
+ ok(res == 0, "reinit READ_CACHE" INFO_TAIL);
+
+ // read by chunks of variable size eof_iter times
+ for (info.end_of_file=0, total= 0; eof_iter; eof_iter--)
+ {
+ int i;
+ size_t curr_read_size;
+ info.end_of_file=
+ eof_iter == 1 ? sizeof(buf_o) :
+ MY_MIN(sizeof(buf_o),
+ info.end_of_file + eof_block_size +
+ // plus 10% of randomization to the average
+ (eof_block_size/10 - rand() % (eof_block_size/5)));
+
+ // read a chunk by blocks of variable size read_iter times
+ for (i= 0; i < read_iter; i++, total += curr_read_size)
+ {
+ curr_read_size=
+ i == read_iter - 1 ? info.end_of_file - total :
+ MY_MIN(info.end_of_file - total,
+ read_size + read_size/10 - rand() % (read_size/5));
+
+ res= my_b_read(&info, buf_i + total, MY_MIN(19, curr_read_size));
+ ok(res == 0, "read of 19");
+ // TODO: mark read bytes in the used part of the cache buffer
+
+ // random size 2nd read
+ res= my_b_read(&info, buf_i + total + MY_MIN(19, curr_read_size),
+ 19 >= curr_read_size ? 0 : curr_read_size - 19);
+ ok(res == 0, "rest of read");
+ // TODO: Check that no marked bytes are in the read buffer
+ // TODO: mark read bytes in the used part of the cache buffer
+
+ }
+ ok(info.pos_in_file + (info.read_end - info.buffer) == info.end_of_file,
+ "cache is read up to eof");
+ ok(total == info.end_of_file, "total matches eof");
+ }
+ ok(total == sizeof(buf_i), "read total size match");
+ ok(buf_i[sizeof(buf_i) - 1] == FILL, "data read correctly");
+
+ close_cached_file(&info);
+}
+
int main(int argc __attribute__((unused)),char *argv[])
{
MY_INIT(argv[0]);
- plan(51);
+ plan(602);
/* temp files with and without encryption */
encrypt_tmp_files= 1;
@@ -306,6 +377,7 @@ int main(int argc __attribute__((unused)),char *argv[])
encrypt_tmp_files= 0;
mdev14014();
+ mdev17133();
my_end(0);
return exit_status();