summaryrefslogtreecommitdiff
path: root/mysys
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-10-21 17:50:19 +0300
commit5b735e8f09c81a2533c30cdd62d60dffa8226cd4 (patch)
tree75f55cacb66addb1331d046a4d4557581f34044b /mysys
parent2a576f71c5d3c7aacef564e5b1251f83bde48f51 (diff)
downloadmariadb-git-5b735e8f09c81a2533c30cdd62d60dffa8226cd4.tar.gz
MDEV-17133 dump thread reads from a past position
According to logs analysis the Dump thread attempted to read again data which was already sent. The reason of regressed read turns out in an _my_b_cache_read() early exit branch which missed to distinguish between total zero size read (e.g ineffective read when Count argument is zero) from a case when the requested amount of data is fully read out by sole accessing the cache's file. In the latter case such then *effective* reading was not reflected in the cache's state to screw the cache's state. Fixed with a check introduced of whether the file reading was effective prior to early exit. When this is the case conduct standard cache state change to account the actual read size. Notice the bug can show up also as an error to read binlog event e.g through BINLOG_GTID_POS() (of MDEV-16886).
Diffstat (limited to 'mysys')
-rw-r--r--mysys/mf_iocache.c7
1 files changed, 5 insertions, 2 deletions
diff --git a/mysys/mf_iocache.c b/mysys/mf_iocache.c
index 56b1ae3fc6e..79893d6f7c1 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,10 @@ int _my_b_cache_read(IO_CACHE *info, uchar *Buffer, size_t Count)
else
{
info->error= 0;
- DBUG_RETURN(0); /* EOF */
+ if (length == 0) /* nothing was read */
+ DBUG_RETURN(0); /* EOF */
+
+ length= 0; /* non-zero size read was done */
}
}
else if ((length= mysql_file_read(info->file,info->buffer, max_length,