Merge lp:~akopytov/percona-server/bug1162085-5.1 into lp:percona-server/5.1

Proposed by Alexey Kopytov on 2013-04-01
Status: Merged
Approved by: Laurynas Biveinis on 2013-04-02
Approved revision: 535
Merged at revision: 547
Proposed branch: lp:~akopytov/percona-server/bug1162085-5.1
Merge into: lp:percona-server/5.1
Diff against target: 70 lines (+41/-3)
3 files modified
Percona-Server/mysql-test/suite/binlog/r/percona_bug1162085.result (+6/-0)
Percona-Server/mysql-test/suite/binlog/t/percona_bug1162085.test (+30/-0)
Percona-Server/mysys/mf_cache.c (+5/-3)
To merge this branch: bzr merge lp:~akopytov/percona-server/bug1162085-5.1
Reviewer Review Type Date Requested Status
Laurynas Biveinis (community) 2013-04-01 Approve on 2013-04-02
Review via email: mp+156355@code.launchpad.net

Description of the change

    Bug #1162085: Percona server 5.5.30-rel30.1.465 reproducable hang

    The fix for bug #1070856 that the underlying binlog cache file is always
    larger then the offset passed to truncate_cached_file(). Which is not
    always the case, because a part of the data which has already been
    written may be in the IO_CACHE buffer, but not yet on disk.

    What happened in the test case was that the server wrote ~48K data into
    the binlog cache with 32K written to disk and the remaining part
    residing in the IO_CACHE buffer. On the ROLLBACK TO statement the server
    called truncate_cached_file() with the 48K offset, in which case
    my_chsize() actually increased the underlying file by appending 16K worth
    of zero bytes. When the remaining 16K bytes were eventually flushed to
    disk on COMMIT, my_b_flush_io_cache() appended them again to the file,
    resulting in the 64K total file size. This in turn led to
    MYSQL_BIN_LOG::write_cache() hanging when reading bogus zero bytes due
    to nonsensical zero offsets in the binlog cache.

    Fixed truncate_cached_file() to only call my_chsize() when the
    underlying cache file is larger than the passed offset.

http://jenkins.percona.com/view/PS%205.1/job/percona-server-5.1-param/530/

To post a comment you must log in.
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added file 'Percona-Server/mysql-test/suite/binlog/r/percona_bug1162085.result'
2--- Percona-Server/mysql-test/suite/binlog/r/percona_bug1162085.result 1970-01-01 00:00:00 +0000
3+++ Percona-Server/mysql-test/suite/binlog/r/percona_bug1162085.result 2013-04-01 14:18:23 +0000
4@@ -0,0 +1,6 @@
5+CREATE TABLE t1 (data LONGBLOB) ENGINE=InnoDB;
6+START TRANSACTION;
7+SAVEPOINT savepoint_1;
8+ROLLBACK TO SAVEPOINT_1;
9+COMMIT;
10+DROP TABLE t1;
11
12=== added file 'Percona-Server/mysql-test/suite/binlog/t/percona_bug1162085.test'
13--- Percona-Server/mysql-test/suite/binlog/t/percona_bug1162085.test 1970-01-01 00:00:00 +0000
14+++ Percona-Server/mysql-test/suite/binlog/t/percona_bug1162085.test 2013-04-01 14:18:23 +0000
15@@ -0,0 +1,30 @@
16+########################################################################
17+# Bug #1162085: Percona server 5.5.30-rel30.1.465 reproducable hang
18+########################################################################
19+
20+-- source include/have_log_bin.inc
21+-- source include/have_innodb.inc
22+
23+CREATE TABLE t1 (data LONGBLOB) ENGINE=InnoDB;
24+
25+START TRANSACTION;
26+
27+--disable_query_log
28+let $i=1024;
29+while($i)
30+{
31+ # Don't use REPEAT() here so we generate long enough writes to the
32+ # binlog cache in both stmt and row-based mode
33+
34+ INSERT INTO t1 (data) VALUES ('XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX');
35+ dec $i;
36+}
37+--enable_query_log
38+
39+SAVEPOINT savepoint_1;
40+
41+ROLLBACK TO SAVEPOINT_1;
42+
43+COMMIT;
44+
45+DROP TABLE t1;
46
47=== modified file 'Percona-Server/mysys/mf_cache.c'
48--- Percona-Server/mysys/mf_cache.c 2012-10-25 17:55:07 +0000
49+++ Percona-Server/mysys/mf_cache.c 2013-04-01 14:18:23 +0000
50@@ -121,15 +121,17 @@
51 }
52
53 /*
54- Truncate the cached file to a given offset. The cache must be reinitialized
55- with reinit_io_cache() after this call.
56+ Truncate the cached file to a given offset, if the current size is greater
57+ than the offset. The cache must be reinitialized with reinit_io_cache() after
58+ this call.
59 */
60
61 my_bool truncate_cached_file(IO_CACHE *cache, my_off_t pos)
62 {
63 DBUG_ENTER("truncate_cached_file");
64
65- if (my_b_inited(cache) && cache->file > -1)
66+ if (my_b_inited(cache) && cache->file > -1 &&
67+ my_seek(cache->file, 0L, MY_SEEK_END, MYF(MY_WME + MY_FAE)) > pos)
68 {
69 if (my_chsize(cache->file, pos, 0, MYF(MY_WME)))
70 DBUG_RETURN(TRUE);

Subscribers

People subscribed via source and target branches