diff options
author | Andrei Elkin <andrei.elkin@mariadb.com> | 2018-09-17 21:40:23 +0300 |
---|---|---|
committer | Andrei Elkin <andrei.elkin@mariadb.com> | 2018-10-21 17:50:19 +0300 |
commit | 5b735e8f09c81a2533c30cdd62d60dffa8226cd4 (patch) | |
tree | 75f55cacb66addb1331d046a4d4557581f34044b /mysys | |
parent | 2a576f71c5d3c7aacef564e5b1251f83bde48f51 (diff) | |
download | mariadb-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.c | 7 |
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, |