~drizzle-trunk/drizzle/development

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