Bug #42547 buf_read_ibuf_merge_pages calls os_aio_simulated_wake_handler threads too late
Submitted: 2 Feb 2009 16:23 Modified: 16 Feb 2009 15:17
Reporter: Mark Callaghan Email Updates:
Status: Not a Bug Impact on me:
None 
Category:MySQL Server: InnoDB storage engine Severity:S5 (Performance)
Version:5.0,5.1 OS:Any
Assigned to: CPU Architecture:Any
Tags: innodb, performance

[2 Feb 2009 16:23] Mark Callaghan
Description:
buf_read_ibuf_merge_pages is called with sync=TRUE for ibuf_contract_for_n_pages(). It submits IO requests in a loop and blocks on the completion of the last IO request when sync===TRUE. After the loop is done (and the last IO is done when sync==TRUE) os_aio_simulated_wake_handler_threads() is called. When sync==true, that should be called before blocking on the last IO request.

How to repeat:
Read the source

Suggested fix:
call the function before blocking
[3 Feb 2009 15:59] Heikki Tuuri
Mark,

yes, you have found a performance bug!

buf_read_page_low(&err, sync && (i + 1 == n_stored),
                                  BUF_READ_ANY_PAGE, space_ids[i],
                                  zip_size, TRUE, space_versions[i],
                                  page_nos[i]);

It starts to wait for the last page BEFORE it calls os_aio_simulated_wake_handler_threads();
That does not make sense. It should call it before.

--Heikki
[3 Feb 2009 17:26] Inaam Rana
Mark,

It is a little obscure but this is not a bug. When calling buf_read_page_low() we do not pass OS_AIO_SIMULATED_WAKE_LATER flag in the mode. Because of this, in lower level routine os_aio() we end up calling os_aio_simulated_wake_handler_thread(). I do agree though that it would be cleaner to call os_aio_simulated_wake_handler_thread() in buf_read_ibuf_merge_pages().

I am going to close this a !bug.

regards,
inaam
[16 Feb 2009 15:17] Mark Callaghan
Then why is the call to os_aio_simulated_wake_handler_threads() needed at all?

Also, the call to buf_flush_free_margin() is only needed when block read requests have been made. This code ignores the return value from buf_read_page_low so it cannot determine that.