diff options
author | Andrei Elkin <andrei.elkin@mariadb.com> | 2018-03-18 21:01:41 +0200 |
---|---|---|
committer | Sergei Golubchik <serg@mariadb.org> | 2018-06-28 12:38:58 +0200 |
commit | 00ccff48af17d82c815909aaee170c59c9439675 (patch) | |
tree | 39cff161a6fd690e53c73f47f154684c5e8f1550 /unittest/sql | |
parent | 52a25d7b674464013b7749a366b0879929985a1e (diff) | |
download | mariadb-git-00ccff48af17d82c815909aaee170c59c9439675.tar.gz |
MDEV-14014 Multi-Slave Replication Fail: bogus data in log event
MDEV-7257 made a dump thread to read from binlog concurrently with
writers as long as the read bytes are below a water-mark
(MYSQL_BIN_LOG::binlog_end_pos). However it appeared to be possible a
dump thread reader reach out for bytes past the water mark through a
feature of IO_CACHE that fills in the internal buffer and while doing
so it could read what the reader is not supposed to see (the bytes
above MYSQL_BIN_LOG::binlog_end_pos).
The issue is fixed with constraining the IO_CACHE buffer fill to respect
the watermark.
An added unit test proves reading from file is bound to an external
parameter
passed to {IO_CACHE::end_of_file} cache member.
Diffstat (limited to 'unittest/sql')
-rw-r--r-- | unittest/sql/mf_iocache-t.cc | 37 |
1 files changed, 36 insertions, 1 deletions
diff --git a/unittest/sql/mf_iocache-t.cc b/unittest/sql/mf_iocache-t.cc index 9f2e4b1b303..34717f04e33 100644 --- a/unittest/sql/mf_iocache-t.cc +++ b/unittest/sql/mf_iocache-t.cc @@ -253,10 +253,43 @@ void mdev10259() } +void mdev14014() +{ + int res; + uchar buf_o[200]; + uchar buf_i[200]; + memset(buf_i, 0, sizeof( buf_i)); + memset(buf_o, FILL, sizeof(buf_o)); + + diag("MDEV-14014 Dump thread reads past last 'officially' written byte"); + + 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_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); + + info.end_of_file= 100; + res= my_b_read(&info, buf_i, sizeof(buf_i)); + ok(res == 1 && buf_i[100] == 0 && buf_i[200-1] == 0, + "short read leaves buf_i[100..200-1] == 0"); + + close_cached_file(&info); +} + + int main(int argc __attribute__((unused)),char *argv[]) { MY_INIT(argv[0]); - plan(46); + plan(51); /* temp files with and without encryption */ encrypt_tmp_files= 1; @@ -272,6 +305,8 @@ int main(int argc __attribute__((unused)),char *argv[]) mdev10259(); encrypt_tmp_files= 0; + mdev14014(); + my_end(0); return exit_status(); } |