Merge lp:~laurynas-biveinis/percona-server/bug1263087-5.5 into lp:percona-server/5.5

Proposed by Laurynas Biveinis
Status: Merged
Approved by: George Ormond Lorch III
Approved revision: no longer in the source branch.
Merged at revision: 613
Proposed branch: lp:~laurynas-biveinis/percona-server/bug1263087-5.5
Merge into: lp:percona-server/5.5
Diff against target: 54 lines (+38/-0)
1 file modified
Percona-Server/storage/innobase/os/os0file.c (+38/-0)
To merge this branch: bzr merge lp:~laurynas-biveinis/percona-server/bug1263087-5.5
Reviewer Review Type Date Requested Status
George Ormond Lorch III (community) g2 Approve
Alexey Kopytov Pending
Review via email: mp+199953@code.launchpad.net

Description of the change

Fix bug 1263087.

Fix bug 1263087 (Percona Server 5.5 / 5.6 do not handle partial /
interrupted AIO calls) by backporting the os_aio_linux_handle() bits
of lp:mysql-server revision 4334.

The backport is straightforward with mechanical os_mutex/mutex_t
bool/ibool ib_logf/fprintf changes.

http://jenkins.percona.com/job/percona-server-5.5-param/920/

Some questions arose regarding 5.7 fix:
- whether it is possible to have a partial/interrupted I/O with io_event::res == 0 and io_event::res2 == 0 (i.e. I/O interrupted before the 1st transferred byte);
- likewise for io_event::res > 0 and io_event::res2 != 0 (== EINTR etc.), i.e. whether interrupted I/O may present differently than partial I/O;
- why 5.7 fix restarts the partial I/Os but does not restart failed I/Os for which os_file_handle_error() says to do so.

Since I did not have good answers for these and it's all very much corner cases anyway, I decided to prefer automerge over the handling of hypothetical cases.

To post a comment you must log in.
Revision history for this message
George Ormond Lorch III (gl-az) :
review: Approve (g2)
Revision history for this message
George Ormond Lorch III (gl-az) wrote :

Approved but have a question...This appears to try to re-issue a read/write from where the previous read/write was stopped. Is it possible that the prior read/write was stopped at an unusual (unaligned) position thus causing the newly issued read/write to be submitted on an unaligned position and potentially causing issues for O_DIRECT files?

Revision history for this message
Laurynas Biveinis (laurynas-biveinis) wrote :

It's an interesting observation, I have no idea whether/when it can occur, but I'll guess it's an exceptional case (I'd expect partial I/O to be stopped at block boundary here). I suppose it's possible to address it by rolling back the retries down to the block boundaries, but for now let's treat it as the other questions above, i.e. wait for some evidence of it occurring.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'Percona-Server/storage/innobase/os/os0file.c'
2--- Percona-Server/storage/innobase/os/os0file.c 2013-12-19 15:17:05 +0000
3+++ Percona-Server/storage/innobase/os/os0file.c 2013-12-23 14:21:23 +0000
4@@ -4851,6 +4851,7 @@
5 segment = os_aio_get_array_and_local_segment(&array, global_seg);
6 n = array->n_slots / array->n_segments;
7
8+ wait_for_event:
9 /* Loop until we have found a completed request. */
10 for (;;) {
11 ibool any_reserved = FALSE;
12@@ -4920,6 +4921,43 @@
13 ut_error;
14 }
15 #endif /* UNIV_DO_FLUSH */
16+ } else if ((slot->ret == 0) && (slot->n_bytes > 0)
17+ && (slot->n_bytes < (long) slot->len)) {
18+ /* Partial read or write scenario */
19+ int submit_ret;
20+ struct iocb* iocb;
21+ slot->buf = (byte*)slot->buf + slot->n_bytes;
22+ slot->offset = slot->offset + slot->n_bytes;
23+ slot->len = slot->len - slot->n_bytes;
24+ /* Resetting the bytes read/written */
25+ slot->n_bytes = 0;
26+ slot->io_already_done = FALSE;
27+ iocb = &(slot->control);
28+
29+ if (slot->type == OS_FILE_READ) {
30+ io_prep_pread(&slot->control, slot->file, slot->buf,
31+ slot->len, (off_t) slot->offset);
32+ } else {
33+ ut_a(slot->type == OS_FILE_WRITE);
34+ io_prep_pwrite(&slot->control, slot->file, slot->buf,
35+ slot->len, (off_t) slot->offset);
36+ }
37+ /* Resubmit an I/O request */
38+ submit_ret = io_submit(array->aio_ctx[segment], 1, &iocb);
39+ if (submit_ret < 0 ) {
40+ /* Aborting in case of submit failure */
41+ ut_print_timestamp(stderr);
42+ fprintf(stderr,
43+ "InnoDB: Error: Native Linux AIO interface. "
44+ "io_submit() call failed when resubmitting a "
45+ "partial I/O request on the file %s.",
46+ slot->name);
47+ ut_error;
48+ } else {
49+ ret = FALSE;
50+ os_mutex_exit(array->mutex);
51+ goto wait_for_event;
52+ }
53 } else {
54 errno = -slot->ret;
55

Subscribers

People subscribed via source and target branches