~ubuntu-branches/ubuntu/trusty/drizzle/trusty

« back to all changes in this revision

Viewing changes to plugin/innobase/buf/buf0rea.c

  • Committer: Bazaar Package Importer
  • Author(s): Monty Taylor
  • Date: 2010-03-18 12:12:31 UTC
  • Revision ID: james.westby@ubuntu.com-20100318121231-k6g1xe6cshbwa0f8
Tags: upstream-2010.03.1347
ImportĀ upstreamĀ versionĀ 2010.03.1347

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*****************************************************************************
 
2
 
 
3
Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
 
4
 
 
5
This program is free software; you can redistribute it and/or modify it under
 
6
the terms of the GNU General Public License as published by the Free Software
 
7
Foundation; version 2 of the License.
 
8
 
 
9
This program is distributed in the hope that it will be useful, but WITHOUT
 
10
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 
11
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 
12
 
 
13
You should have received a copy of the GNU General Public License along with
 
14
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
 
15
Place, Suite 330, Boston, MA 02111-1307 USA
 
16
 
 
17
*****************************************************************************/
 
18
 
 
19
/**************************************************//**
 
20
@file buf/buf0rea.c
 
21
The database buffer read
 
22
 
 
23
Created 11/5/1995 Heikki Tuuri
 
24
*******************************************************/
 
25
 
 
26
#include "buf0rea.h"
 
27
 
 
28
#include "fil0fil.h"
 
29
#include "mtr0mtr.h"
 
30
 
 
31
#include "buf0buf.h"
 
32
#include "buf0flu.h"
 
33
#include "buf0lru.h"
 
34
#include "ibuf0ibuf.h"
 
35
#include "log0recv.h"
 
36
#include "trx0sys.h"
 
37
#include "os0file.h"
 
38
#include "srv0start.h"
 
39
#include "srv0srv.h"
 
40
 
 
41
/** The size in blocks of the area where the random read-ahead algorithm counts
 
42
the accessed pages when deciding whether to read-ahead */
 
43
#define BUF_READ_AHEAD_RANDOM_AREA      BUF_READ_AHEAD_AREA
 
44
 
 
45
/** There must be at least this many pages in buf_pool in the area to start
 
46
a random read-ahead */
 
47
#define BUF_READ_AHEAD_RANDOM_THRESHOLD (1 + BUF_READ_AHEAD_RANDOM_AREA / 2)
 
48
 
 
49
/** The linear read-ahead area size */
 
50
#define BUF_READ_AHEAD_LINEAR_AREA      BUF_READ_AHEAD_AREA
 
51
 
 
52
/** If there are buf_pool->curr_size per the number below pending reads, then
 
53
read-ahead is not done: this is to prevent flooding the buffer pool with
 
54
i/o-fixed buffer blocks */
 
55
#define BUF_READ_AHEAD_PEND_LIMIT       2
 
56
 
 
57
/********************************************************************//**
 
58
Low-level function which reads a page asynchronously from a file to the
 
59
buffer buf_pool if it is not already there, in which case does nothing.
 
60
Sets the io_fix flag and sets an exclusive lock on the buffer frame. The
 
61
flag is cleared and the x-lock released by an i/o-handler thread.
 
62
@return 1 if a read request was queued, 0 if the page already resided
 
63
in buf_pool, or if the page is in the doublewrite buffer blocks in
 
64
which case it is never read into the pool, or if the tablespace does
 
65
not exist or is being dropped */
 
66
static
 
67
ulint
 
68
buf_read_page_low(
 
69
/*==============*/
 
70
        ulint*  err,    /*!< out: DB_SUCCESS or DB_TABLESPACE_DELETED if we are
 
71
                        trying to read from a non-existent tablespace, or a
 
72
                        tablespace which is just now being dropped */
 
73
        ibool   sync,   /*!< in: TRUE if synchronous aio is desired */
 
74
        ulint   mode,   /*!< in: BUF_READ_IBUF_PAGES_ONLY, ...,
 
75
                        ORed to OS_AIO_SIMULATED_WAKE_LATER (see below
 
76
                        at read-ahead functions) */
 
77
        ulint   space,  /*!< in: space id */
 
78
        ulint   zip_size,/*!< in: compressed page size, or 0 */
 
79
        ibool   unzip,  /*!< in: TRUE=request uncompressed page */
 
80
        ib_int64_t tablespace_version, /*!< in: if the space memory object has
 
81
                        this timestamp different from what we are giving here,
 
82
                        treat the tablespace as dropped; this is a timestamp we
 
83
                        use to stop dangling page reads from a tablespace
 
84
                        which we have DISCARDed + IMPORTed back */
 
85
        ulint   offset) /*!< in: page number */
 
86
{
 
87
        buf_page_t*     bpage;
 
88
        ulint           wake_later;
 
89
 
 
90
        *err = DB_SUCCESS;
 
91
 
 
92
        wake_later = mode & OS_AIO_SIMULATED_WAKE_LATER;
 
93
        mode = mode & ~OS_AIO_SIMULATED_WAKE_LATER;
 
94
 
 
95
        if (trx_doublewrite && space == TRX_SYS_SPACE
 
96
            && (   (offset >= trx_doublewrite->block1
 
97
                    && offset < trx_doublewrite->block1
 
98
                    + TRX_SYS_DOUBLEWRITE_BLOCK_SIZE)
 
99
                   || (offset >= trx_doublewrite->block2
 
100
                       && offset < trx_doublewrite->block2
 
101
                       + TRX_SYS_DOUBLEWRITE_BLOCK_SIZE))) {
 
102
                ut_print_timestamp(stderr);
 
103
                fprintf(stderr,
 
104
                        "  InnoDB: Warning: trying to read"
 
105
                        " doublewrite buffer page %lu\n",
 
106
                        (ulong) offset);
 
107
 
 
108
                return(0);
 
109
        }
 
110
 
 
111
        if (ibuf_bitmap_page(zip_size, offset)
 
112
            || trx_sys_hdr_page(space, offset)) {
 
113
 
 
114
                /* Trx sys header is so low in the latching order that we play
 
115
                safe and do not leave the i/o-completion to an asynchronous
 
116
                i/o-thread. Ibuf bitmap pages must always be read with
 
117
                syncronous i/o, to make sure they do not get involved in
 
118
                thread deadlocks. */
 
119
 
 
120
                sync = TRUE;
 
121
        }
 
122
 
 
123
        /* The following call will also check if the tablespace does not exist
 
124
        or is being dropped; if we succeed in initing the page in the buffer
 
125
        pool for read, then DISCARD cannot proceed until the read has
 
126
        completed */
 
127
        bpage = buf_page_init_for_read(err, mode, space, zip_size, unzip,
 
128
                                       tablespace_version, offset);
 
129
        if (bpage == NULL) {
 
130
 
 
131
                return(0);
 
132
        }
 
133
 
 
134
#ifdef UNIV_DEBUG
 
135
        if (buf_debug_prints) {
 
136
                fprintf(stderr,
 
137
                        "Posting read request for page %lu, sync %lu\n",
 
138
                        (ulong) offset,
 
139
                        (ulong) sync);
 
140
        }
 
141
#endif
 
142
 
 
143
        ut_ad(buf_page_in_file(bpage));
 
144
 
 
145
        if (zip_size) {
 
146
                *err = fil_io(OS_FILE_READ | wake_later,
 
147
                              sync, space, zip_size, offset, 0, zip_size,
 
148
                              bpage->zip.data, bpage);
 
149
        } else {
 
150
                ut_a(buf_page_get_state(bpage) == BUF_BLOCK_FILE_PAGE);
 
151
 
 
152
                *err = fil_io(OS_FILE_READ | wake_later,
 
153
                              sync, space, 0, offset, 0, UNIV_PAGE_SIZE,
 
154
                              ((buf_block_t*) bpage)->frame, bpage);
 
155
        }
 
156
        ut_a(*err == DB_SUCCESS);
 
157
 
 
158
        if (sync) {
 
159
                /* The i/o is already completed when we arrive from
 
160
                fil_read */
 
161
                buf_page_io_complete(bpage);
 
162
        }
 
163
 
 
164
        return(1);
 
165
}
 
166
 
 
167
/********************************************************************//**
 
168
Applies a random read-ahead in buf_pool if there are at least a threshold
 
169
value of accessed pages from the random read-ahead area. Does not read any
 
170
page, not even the one at the position (space, offset), if the read-ahead
 
171
mechanism is not activated. NOTE 1: the calling thread may own latches on
 
172
pages: to avoid deadlocks this function must be written such that it cannot
 
173
end up waiting for these latches! NOTE 2: the calling thread must want
 
174
access to the page given: this rule is set to prevent unintended read-aheads
 
175
performed by ibuf routines, a situation which could result in a deadlock if
 
176
the OS does not support asynchronous i/o.
 
177
@return number of page read requests issued; NOTE that if we read ibuf
 
178
pages, it may happen that the page at the given page number does not
 
179
get read even if we return a positive value! */
 
180
static
 
181
ulint
 
182
buf_read_ahead_random(
 
183
/*==================*/
 
184
        ulint   space,  /*!< in: space id */
 
185
        ulint   zip_size,/*!< in: compressed page size in bytes, or 0 */
 
186
        ulint   offset) /*!< in: page number of a page which the current thread
 
187
                        wants to access */
 
188
{
 
189
        (void)space;
 
190
        (void)zip_size;
 
191
        (void)offset;
 
192
        /* We have currently disabled random readahead */
 
193
        return(0);
 
194
 
 
195
}
 
196
 
 
197
/********************************************************************//**
 
198
High-level function which reads a page asynchronously from a file to the
 
199
buffer buf_pool if it is not already there. Sets the io_fix flag and sets
 
200
an exclusive lock on the buffer frame. The flag is cleared and the x-lock
 
201
released by the i/o-handler thread. Does a random read-ahead if it seems
 
202
sensible.
 
203
@return number of page read requests issued: this can be greater than
 
204
1 if read-ahead occurred */
 
205
UNIV_INTERN
 
206
ulint
 
207
buf_read_page(
 
208
/*==========*/
 
209
        ulint   space,  /*!< in: space id */
 
210
        ulint   zip_size,/*!< in: compressed page size in bytes, or 0 */
 
211
        ulint   offset) /*!< in: page number */
 
212
{
 
213
        ib_int64_t      tablespace_version;
 
214
        ulint           count;
 
215
        ulint           count2;
 
216
        ulint           err;
 
217
 
 
218
        tablespace_version = fil_space_get_version(space);
 
219
 
 
220
        count = buf_read_ahead_random(space, zip_size, offset);
 
221
 
 
222
        /* We do the i/o in the synchronous aio mode to save thread
 
223
        switches: hence TRUE */
 
224
 
 
225
        count2 = buf_read_page_low(&err, TRUE, BUF_READ_ANY_PAGE, space,
 
226
                                   zip_size, FALSE,
 
227
                                   tablespace_version, offset);
 
228
        srv_buf_pool_reads+= count2;
 
229
        if (err == DB_TABLESPACE_DELETED) {
 
230
                ut_print_timestamp(stderr);
 
231
                fprintf(stderr,
 
232
                        "  InnoDB: Error: trying to access"
 
233
                        " tablespace %lu page no. %lu,\n"
 
234
                        "InnoDB: but the tablespace does not exist"
 
235
                        " or is just being dropped.\n",
 
236
                        (ulong) space, (ulong) offset);
 
237
        }
 
238
 
 
239
        /* Flush pages from the end of the LRU list if necessary */
 
240
        buf_flush_free_margin();
 
241
 
 
242
        /* Increment number of I/O operations used for LRU policy. */
 
243
        buf_LRU_stat_inc_io();
 
244
 
 
245
        return(count + count2);
 
246
}
 
247
 
 
248
/********************************************************************//**
 
249
Applies linear read-ahead if in the buf_pool the page is a border page of
 
250
a linear read-ahead area and all the pages in the area have been accessed.
 
251
Does not read any page if the read-ahead mechanism is not activated. Note
 
252
that the the algorithm looks at the 'natural' adjacent successor and
 
253
predecessor of the page, which on the leaf level of a B-tree are the next
 
254
and previous page in the chain of leaves. To know these, the page specified
 
255
in (space, offset) must already be present in the buf_pool. Thus, the
 
256
natural way to use this function is to call it when a page in the buf_pool
 
257
is accessed the first time, calling this function just after it has been
 
258
bufferfixed.
 
259
NOTE 1: as this function looks at the natural predecessor and successor
 
260
fields on the page, what happens, if these are not initialized to any
 
261
sensible value? No problem, before applying read-ahead we check that the
 
262
area to read is within the span of the space, if not, read-ahead is not
 
263
applied. An uninitialized value may result in a useless read operation, but
 
264
only very improbably.
 
265
NOTE 2: the calling thread may own latches on pages: to avoid deadlocks this
 
266
function must be written such that it cannot end up waiting for these
 
267
latches!
 
268
NOTE 3: the calling thread must want access to the page given: this rule is
 
269
set to prevent unintended read-aheads performed by ibuf routines, a situation
 
270
which could result in a deadlock if the OS does not support asynchronous io.
 
271
@return number of page read requests issued */
 
272
UNIV_INTERN
 
273
ulint
 
274
buf_read_ahead_linear(
 
275
/*==================*/
 
276
        ulint   space,  /*!< in: space id */
 
277
        ulint   zip_size,/*!< in: compressed page size in bytes, or 0 */
 
278
        ulint   offset) /*!< in: page number of a page; NOTE: the current thread
 
279
                        must want access to this page (see NOTE 3 above) */
 
280
{
 
281
        ib_int64_t      tablespace_version;
 
282
        buf_page_t*     bpage;
 
283
        buf_frame_t*    frame;
 
284
        buf_page_t*     pred_bpage      = NULL;
 
285
        ulint           pred_offset;
 
286
        ulint           succ_offset;
 
287
        ulint           count;
 
288
        int             asc_or_desc;
 
289
        ulint           new_offset;
 
290
        ulint           fail_count;
 
291
        ulint           ibuf_mode;
 
292
        ulint           low, high;
 
293
        ulint           err;
 
294
        ulint           i;
 
295
        const ulint     buf_read_ahead_linear_area
 
296
                = BUF_READ_AHEAD_LINEAR_AREA;
 
297
        ulint           threshold;
 
298
 
 
299
        if (UNIV_UNLIKELY(srv_startup_is_before_trx_rollback_phase)) {
 
300
                /* No read-ahead to avoid thread deadlocks */
 
301
                return(0);
 
302
        }
 
303
 
 
304
        low  = (offset / buf_read_ahead_linear_area)
 
305
                * buf_read_ahead_linear_area;
 
306
        high = (offset / buf_read_ahead_linear_area + 1)
 
307
                * buf_read_ahead_linear_area;
 
308
 
 
309
        if ((offset != low) && (offset != high - 1)) {
 
310
                /* This is not a border page of the area: return */
 
311
 
 
312
                return(0);
 
313
        }
 
314
 
 
315
        if (ibuf_bitmap_page(zip_size, offset)
 
316
            || trx_sys_hdr_page(space, offset)) {
 
317
 
 
318
                /* If it is an ibuf bitmap page or trx sys hdr, we do
 
319
                no read-ahead, as that could break the ibuf page access
 
320
                order */
 
321
 
 
322
                return(0);
 
323
        }
 
324
 
 
325
        /* Remember the tablespace version before we ask te tablespace size
 
326
        below: if DISCARD + IMPORT changes the actual .ibd file meanwhile, we
 
327
        do not try to read outside the bounds of the tablespace! */
 
328
 
 
329
        tablespace_version = fil_space_get_version(space);
 
330
 
 
331
        buf_pool_mutex_enter();
 
332
 
 
333
        if (high > fil_space_get_size(space)) {
 
334
                buf_pool_mutex_exit();
 
335
                /* The area is not whole, return */
 
336
 
 
337
                return(0);
 
338
        }
 
339
 
 
340
        if (buf_pool->n_pend_reads
 
341
            > buf_pool->curr_size / BUF_READ_AHEAD_PEND_LIMIT) {
 
342
                buf_pool_mutex_exit();
 
343
 
 
344
                return(0);
 
345
        }
 
346
 
 
347
        /* Check that almost all pages in the area have been accessed; if
 
348
        offset == low, the accesses must be in a descending order, otherwise,
 
349
        in an ascending order. */
 
350
 
 
351
        asc_or_desc = 1;
 
352
 
 
353
        if (offset == low) {
 
354
                asc_or_desc = -1;
 
355
        }
 
356
 
 
357
        /* How many out of order accessed pages can we ignore
 
358
        when working out the access pattern for linear readahead */
 
359
        threshold = ut_min((64 - srv_read_ahead_threshold),
 
360
                           BUF_READ_AHEAD_AREA);
 
361
 
 
362
        fail_count = 0;
 
363
 
 
364
        for (i = low; i < high; i++) {
 
365
                bpage = buf_page_hash_get(space, i);
 
366
 
 
367
                if ((bpage == NULL) || !buf_page_is_accessed(bpage)) {
 
368
                        /* Not accessed */
 
369
                        fail_count++;
 
370
 
 
371
                } else if (pred_bpage) {
 
372
                        int res = (ut_ulint_cmp(
 
373
                                       buf_page_get_LRU_position(bpage),
 
374
                                       buf_page_get_LRU_position(pred_bpage)));
 
375
                        /* Accesses not in the right order */
 
376
                        if (res != 0 && res != asc_or_desc) {
 
377
                                fail_count++;
 
378
                        }
 
379
                }
 
380
 
 
381
                if (fail_count > threshold) {
 
382
                        /* Too many failures: return */
 
383
                        buf_pool_mutex_exit();
 
384
                        return(0);
 
385
                }
 
386
 
 
387
                if (bpage && buf_page_is_accessed(bpage)) {
 
388
                        pred_bpage = bpage;
 
389
                }
 
390
        }
 
391
 
 
392
        /* If we got this far, we know that enough pages in the area have
 
393
        been accessed in the right order: linear read-ahead can be sensible */
 
394
 
 
395
        bpage = buf_page_hash_get(space, offset);
 
396
 
 
397
        if (bpage == NULL) {
 
398
                buf_pool_mutex_exit();
 
399
 
 
400
                return(0);
 
401
        }
 
402
 
 
403
        switch (buf_page_get_state(bpage)) {
 
404
        case BUF_BLOCK_ZIP_PAGE:
 
405
                frame = bpage->zip.data;
 
406
                break;
 
407
        case BUF_BLOCK_FILE_PAGE:
 
408
                frame = ((buf_block_t*) bpage)->frame;
 
409
                break;
 
410
        default:
 
411
                ut_error;
 
412
                break;
 
413
        }
 
414
 
 
415
        /* Read the natural predecessor and successor page addresses from
 
416
        the page; NOTE that because the calling thread may have an x-latch
 
417
        on the page, we do not acquire an s-latch on the page, this is to
 
418
        prevent deadlocks. Even if we read values which are nonsense, the
 
419
        algorithm will work. */
 
420
 
 
421
        pred_offset = fil_page_get_prev(frame);
 
422
        succ_offset = fil_page_get_next(frame);
 
423
 
 
424
        buf_pool_mutex_exit();
 
425
 
 
426
        if ((offset == low) && (succ_offset == offset + 1)) {
 
427
 
 
428
                /* This is ok, we can continue */
 
429
                new_offset = pred_offset;
 
430
 
 
431
        } else if ((offset == high - 1) && (pred_offset == offset - 1)) {
 
432
 
 
433
                /* This is ok, we can continue */
 
434
                new_offset = succ_offset;
 
435
        } else {
 
436
                /* Successor or predecessor not in the right order */
 
437
 
 
438
                return(0);
 
439
        }
 
440
 
 
441
        low  = (new_offset / buf_read_ahead_linear_area)
 
442
                * buf_read_ahead_linear_area;
 
443
        high = (new_offset / buf_read_ahead_linear_area + 1)
 
444
                * buf_read_ahead_linear_area;
 
445
 
 
446
        if ((new_offset != low) && (new_offset != high - 1)) {
 
447
                /* This is not a border page of the area: return */
 
448
 
 
449
                return(0);
 
450
        }
 
451
 
 
452
        if (high > fil_space_get_size(space)) {
 
453
                /* The area is not whole, return */
 
454
 
 
455
                return(0);
 
456
        }
 
457
 
 
458
        /* If we got this far, read-ahead can be sensible: do it */
 
459
 
 
460
        if (ibuf_inside()) {
 
461
                ibuf_mode = BUF_READ_IBUF_PAGES_ONLY;
 
462
        } else {
 
463
                ibuf_mode = BUF_READ_ANY_PAGE;
 
464
        }
 
465
 
 
466
        count = 0;
 
467
 
 
468
        /* Since Windows XP seems to schedule the i/o handler thread
 
469
        very eagerly, and consequently it does not wait for the
 
470
        full read batch to be posted, we use special heuristics here */
 
471
 
 
472
        os_aio_simulated_put_read_threads_to_sleep();
 
473
 
 
474
        for (i = low; i < high; i++) {
 
475
                /* It is only sensible to do read-ahead in the non-sync
 
476
                aio mode: hence FALSE as the first parameter */
 
477
 
 
478
                if (!ibuf_bitmap_page(zip_size, i)) {
 
479
                        count += buf_read_page_low(
 
480
                                &err, FALSE,
 
481
                                ibuf_mode | OS_AIO_SIMULATED_WAKE_LATER,
 
482
                                space, zip_size, FALSE, tablespace_version, i);
 
483
                        if (err == DB_TABLESPACE_DELETED) {
 
484
                                ut_print_timestamp(stderr);
 
485
                                fprintf(stderr,
 
486
                                        "  InnoDB: Warning: in"
 
487
                                        " linear readahead trying to access\n"
 
488
                                        "InnoDB: tablespace %lu page %lu,\n"
 
489
                                        "InnoDB: but the tablespace does not"
 
490
                                        " exist or is just being dropped.\n",
 
491
                                        (ulong) space, (ulong) i);
 
492
                        }
 
493
                }
 
494
        }
 
495
 
 
496
        /* In simulated aio we wake the aio handler threads only after
 
497
        queuing all aio requests, in native aio the following call does
 
498
        nothing: */
 
499
 
 
500
        os_aio_simulated_wake_handler_threads();
 
501
 
 
502
        /* Flush pages from the end of the LRU list if necessary */
 
503
        buf_flush_free_margin();
 
504
 
 
505
#ifdef UNIV_DEBUG
 
506
        if (buf_debug_prints && (count > 0)) {
 
507
                fprintf(stderr,
 
508
                        "LINEAR read-ahead space %lu offset %lu pages %lu\n",
 
509
                        (ulong) space, (ulong) offset, (ulong) count);
 
510
        }
 
511
#endif /* UNIV_DEBUG */
 
512
 
 
513
        /* Read ahead is considered one I/O operation for the purpose of
 
514
        LRU policy decision. */
 
515
        buf_LRU_stat_inc_io();
 
516
 
 
517
        ++srv_read_ahead_seq;
 
518
        return(count);
 
519
}
 
520
 
 
521
/********************************************************************//**
 
522
Issues read requests for pages which the ibuf module wants to read in, in
 
523
order to contract the insert buffer tree. Technically, this function is like
 
524
a read-ahead function. */
 
525
UNIV_INTERN
 
526
void
 
527
buf_read_ibuf_merge_pages(
 
528
/*======================*/
 
529
        ibool           sync,           /*!< in: TRUE if the caller
 
530
                                        wants this function to wait
 
531
                                        for the highest address page
 
532
                                        to get read in, before this
 
533
                                        function returns */
 
534
        const ulint*    space_ids,      /*!< in: array of space ids */
 
535
        const ib_int64_t* space_versions,/*!< in: the spaces must have
 
536
                                        this version number
 
537
                                        (timestamp), otherwise we
 
538
                                        discard the read; we use this
 
539
                                        to cancel reads if DISCARD +
 
540
                                        IMPORT may have changed the
 
541
                                        tablespace size */
 
542
        const ulint*    page_nos,       /*!< in: array of page numbers
 
543
                                        to read, with the highest page
 
544
                                        number the last in the
 
545
                                        array */
 
546
        ulint           n_stored)       /*!< in: number of elements
 
547
                                        in the arrays */
 
548
{
 
549
        ulint   i;
 
550
 
 
551
        ut_ad(!ibuf_inside());
 
552
#ifdef UNIV_IBUF_DEBUG
 
553
        ut_a(n_stored < UNIV_PAGE_SIZE);
 
554
#endif
 
555
        while (buf_pool->n_pend_reads
 
556
               > buf_pool->curr_size / BUF_READ_AHEAD_PEND_LIMIT) {
 
557
                os_thread_sleep(500000);
 
558
        }
 
559
 
 
560
        for (i = 0; i < n_stored; i++) {
 
561
                ulint   zip_size = fil_space_get_zip_size(space_ids[i]);
 
562
                ulint   err;
 
563
 
 
564
                if (UNIV_UNLIKELY(zip_size == ULINT_UNDEFINED)) {
 
565
 
 
566
                        goto tablespace_deleted;
 
567
                }
 
568
 
 
569
                buf_read_page_low(&err, sync && (i + 1 == n_stored),
 
570
                                  BUF_READ_ANY_PAGE, space_ids[i],
 
571
                                  zip_size, TRUE, space_versions[i],
 
572
                                  page_nos[i]);
 
573
 
 
574
                if (UNIV_UNLIKELY(err == DB_TABLESPACE_DELETED)) {
 
575
tablespace_deleted:
 
576
                        /* We have deleted or are deleting the single-table
 
577
                        tablespace: remove the entries for that page */
 
578
 
 
579
                        ibuf_merge_or_delete_for_page(NULL, space_ids[i],
 
580
                                                      page_nos[i],
 
581
                                                      zip_size, FALSE);
 
582
                }
 
583
        }
 
584
 
 
585
        os_aio_simulated_wake_handler_threads();
 
586
 
 
587
        /* Flush pages from the end of the LRU list if necessary */
 
588
        buf_flush_free_margin();
 
589
 
 
590
#ifdef UNIV_DEBUG
 
591
        if (buf_debug_prints) {
 
592
                fprintf(stderr,
 
593
                        "Ibuf merge read-ahead space %lu pages %lu\n",
 
594
                        (ulong) space_ids[0], (ulong) n_stored);
 
595
        }
 
596
#endif /* UNIV_DEBUG */
 
597
}
 
598
 
 
599
/********************************************************************//**
 
600
Issues read requests for pages which recovery wants to read in. */
 
601
UNIV_INTERN
 
602
void
 
603
buf_read_recv_pages(
 
604
/*================*/
 
605
        ibool           sync,           /*!< in: TRUE if the caller
 
606
                                        wants this function to wait
 
607
                                        for the highest address page
 
608
                                        to get read in, before this
 
609
                                        function returns */
 
610
        ulint           space,          /*!< in: space id */
 
611
        ulint           zip_size,       /*!< in: compressed page size in
 
612
                                        bytes, or 0 */
 
613
        const ulint*    page_nos,       /*!< in: array of page numbers
 
614
                                        to read, with the highest page
 
615
                                        number the last in the
 
616
                                        array */
 
617
        ulint           n_stored)       /*!< in: number of page numbers
 
618
                                        in the array */
 
619
{
 
620
        ib_int64_t      tablespace_version;
 
621
        ulint           count;
 
622
        ulint           err;
 
623
        ulint           i;
 
624
 
 
625
        zip_size = fil_space_get_zip_size(space);
 
626
 
 
627
        if (UNIV_UNLIKELY(zip_size == ULINT_UNDEFINED)) {
 
628
                /* It is a single table tablespace and the .ibd file is
 
629
                missing: do nothing */
 
630
 
 
631
                return;
 
632
        }
 
633
 
 
634
        tablespace_version = fil_space_get_version(space);
 
635
 
 
636
        for (i = 0; i < n_stored; i++) {
 
637
 
 
638
                count = 0;
 
639
 
 
640
                os_aio_print_debug = FALSE;
 
641
 
 
642
                while (buf_pool->n_pend_reads >= recv_n_pool_free_frames / 2) {
 
643
 
 
644
                        os_aio_simulated_wake_handler_threads();
 
645
                        os_thread_sleep(500000);
 
646
 
 
647
                        count++;
 
648
 
 
649
                        if (count > 100) {
 
650
                                fprintf(stderr,
 
651
                                        "InnoDB: Error: InnoDB has waited for"
 
652
                                        " 50 seconds for pending\n"
 
653
                                        "InnoDB: reads to the buffer pool to"
 
654
                                        " be finished.\n"
 
655
                                        "InnoDB: Number of pending reads %lu,"
 
656
                                        " pending pread calls %lu\n",
 
657
                                        (ulong) buf_pool->n_pend_reads,
 
658
                                        (ulong)os_file_n_pending_preads);
 
659
 
 
660
                                os_aio_print_debug = TRUE;
 
661
                        }
 
662
                }
 
663
 
 
664
                os_aio_print_debug = FALSE;
 
665
 
 
666
                if ((i + 1 == n_stored) && sync) {
 
667
                        buf_read_page_low(&err, TRUE, BUF_READ_ANY_PAGE, space,
 
668
                                          zip_size, TRUE, tablespace_version,
 
669
                                          page_nos[i]);
 
670
                } else {
 
671
                        buf_read_page_low(&err, FALSE, BUF_READ_ANY_PAGE
 
672
                                          | OS_AIO_SIMULATED_WAKE_LATER,
 
673
                                          space, zip_size, TRUE,
 
674
                                          tablespace_version, page_nos[i]);
 
675
                }
 
676
        }
 
677
 
 
678
        os_aio_simulated_wake_handler_threads();
 
679
 
 
680
        /* Flush pages from the end of the LRU list if necessary */
 
681
        buf_flush_free_margin();
 
682
 
 
683
#ifdef UNIV_DEBUG
 
684
        if (buf_debug_prints) {
 
685
                fprintf(stderr,
 
686
                        "Recovery applies read-ahead pages %lu\n",
 
687
                        (ulong) n_stored);
 
688
        }
 
689
#endif /* UNIV_DEBUG */
 
690
}