Bug #73583 buf_read_page_async calls buf_read_page_low with sync=true
Submitted: 14 Aug 2014 13:31 Modified: 25 Aug 2014 12:32
Reporter: Rongrong Zhong Email Updates:
Status: Verified Impact on me:
None 
Category:MySQL Server: InnoDB storage engine Severity:S3 (Non-critical)
Version:5.6.12 OS:Any
Assigned to: CPU Architecture:Any

[14 Aug 2014 13:31] Rongrong Zhong
Description:
buf_read_page async in storage/innobase/buf/buf0rea.cc calls buf_read_page_low with second parameter, sync = true, which suggests using synchronous IO.

UNIV_INTERN
ibool
buf_read_page_async(
/*================*/
        ulint   space,  /*!< in: space id */
        ulint   offset) /*!< in: page number */
{
        ulint           zip_size;
        ib_int64_t      tablespace_version;
        ulint           count;
        dberr_t         err;

        zip_size = fil_space_get_zip_size(space);

        if (zip_size == ULINT_UNDEFINED) {
                return(FALSE);
        }

        tablespace_version = fil_space_get_version(space);

        count = buf_read_page_low(&err, true, BUF_READ_ANY_PAGE
                                  | OS_AIO_SIMULATED_WAKE_LATER
                                  | BUF_READ_IGNORE_NONEXISTENT_PAGES,
                                  space, zip_size, FALSE,
                                  tablespace_version, offset, NULL, FALSE);
        srv_stats.buf_pool_reads.add(count);

        /* We do not increment number of I/O operations used for LRU policy
        here (buf_LRU_stat_inc_io()). We use this in heuristics to decide
        about evicting uncompressed version of compressed pages from the
        buffer pool. Since this function is called from buffer pool load
        these IOs are deliberate and are not part of normal workload we can
        ignore these in our heuristics. */

        return(count > 0);
}

How to repeat:
Read the code.

Suggested fix:
actually use async.
[14 Aug 2014 22:48] Sunny Bains
Yes, this is bug introduced in : Bug#16477781 SINGLE PAGE FLUSHING CAUSES FSYNC() OF ALL DATAFILES
[20 Aug 2014 15:42] Daniel Price
Fixed as of the upcoming 5.6.21, 5.7.5 release, and here's the changelog entry:

The "buf_read_page" function, which reads a page asynchronously from a
file to the buffer pool if it is not already there, would call
"buf_read_page_low" with "sync=true" instead of "sync=false".

Thank you for the bug report.
[20 Aug 2014 20:15] Rongrong Zhong
Wait, I thought the fix should be changing sync to false in buf_read_page_async. Isn't buf_read_page supposed to read the page synchronously and buf_read_page_async read it asynchronously?
[21 Aug 2014 13:04] Daniel Price
The changelog entry has been revised as follows:

Fixed as of the upcoming 5.6.21, 5.7.5 release, and here's the changelog entry:

"buf_read_page_low" would be called with "sync=true" instead of
"sync=false". 

Thank you for the bug report.
[25 Aug 2014 12:32] Daniel Price
The patch has been reverted while a related test case failure is investigated.
[3 Nov 2014 17:42] Evgeniy Shishkin
any update?
[1 Apr 2018 5:40] Sergei Turchanov
So, will anyone fix this bug? It affects severily Innodb buffer pool load times at server startup. We have 80GB buffer pool and it takes about 30 minutes to load it. buf_load uses buf_read_page_async to load pages from disk. 
Due to syncronohous IO we have read rate ~ 10MB/s

The original implementation by Percona used truly async io (see: https://github.com/percona/percona-server/blob/1d6035b9f6bd98446ea1600d9535b951dad96bb2/st...). With that implementaion (as of MySQL 5.5) buffer pool were loaded at abount 1000MB/s (we have a RAID).
[1 Apr 2018 6:04] Sergei Turchanov
Corrections: disk read rate is 30MB/s (not 10MB/s) but anyways it is way too low that it were with Percona MySQL 5.5