Bug #67973 Bug in innodb's simulated aio algorithm
Submitted: 25 Dec 2012 10:01 Modified: 7 Jan 2013 23:27
Reporter: jony wang Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server: InnoDB storage engine Severity:S2 (Serious)
Version:5.6.8rc OS:Any
Assigned to: Sunny Bains CPU Architecture:Any
Tags: aio, innodb

[25 Dec 2012 10:01] jony wang
Description:

in the implementation of innodb simulated aio.

we have the following code to judge whether there is consecutive blocks in the aio  slot array;

innobase/os/os0file.c  ---->os_aio_simulated_handle()
=========================================================================
	/* Check if there are several consecutive blocks to read or write */

consecutive_loop:
	for (ulint i = 0; i < n; i++) {
		os_aio_slot_t*	slot;

		slot = os_aio_array_get_nth_slot(array, i + segment * n);

		if (slot->reserved
		    && slot != aio_slot
		    && slot->offset == slot->offset + aio_slot->len
		    && slot->type == aio_slot->type
		    && slot->file == aio_slot->file) {

			/* Found a consecutive i/o request */

			consecutive_ios[n_consecutive] = slot;
			n_consecutive++;

			aio_slot = slot;

			if (n_consecutive < OS_AIO_MERGE_N_CONSECUTIVE) {

				goto consecutive_loop;
			} else {
				break;
			}
		}
	}
==============================================================================
however the result of slot->offset == slot->offset + aio_slot->len 
should never be true.
as a result  you can never merge consecutive io request into one  synchronous io operation.

How to repeat:
just check the code of the function os_aio_simulated_handle in 5.6.8rc or 5.6.9rc

Suggested fix:
slot->offset == aio_slot->offset + aio_slot->len
[25 Dec 2012 16:00] Valeriy Kravchuk
This part of code looks different in current MySQL 5.5 from Launchpad:

...
        slot = consecutive_ios[0];

        /* Check if there are several consecutive blocks to read or write */

consecutive_loop:
        for (i = 0; i < n; i++) {
                slot2 = os_aio_array_get_nth_slot(array, i + segment * n);

                if (slot2->reserved && slot2 != slot
                    && slot2->offset == slot->offset + slot->len
                    /* check that sum does not wrap over */
                    && slot->offset + slot->len > slot->offset
                    && slot2->offset_high == slot->offset_high
                    && slot2->type == slot->type
                    && slot2->file == slot->file) {

                        /* Found a consecutive i/o request */
...

[openxs@centos mysql-5.5]$ bzr version-info
revision-id: dmitry.lenev@oracle.com-20121210060637-fxax09ib1bmqnyu3
date: 2012-12-10 10:06:37 +0400
build-date: 2012-12-25 17:59:40 +0200
revno: 4040
branch-nick: mysql-5.5
[26 Dec 2012 2:22] jony wang
Hi  Valeriy:

I have checked the code of 5.0.51b,5.1.63,5.5.27,5.6.8rc,5.6.9rc.

This problem exists only in 5.6.8rc and 5.6.9rc.

Maybe it was brought in since  5.6;
[7 Jan 2013 23:27] John Russell
Added to changelog for 5.6.11: 

The I/O routines used when the AIO subsystem were made more
efficient, to merge consecutive I/O requests into a single operation.
This fix solves a performance issue introduced during the 5.6
development cycle.