| 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: | |
| 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 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.


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