buf0rea.c
上传用户:romrleung
上传日期:2022-05-23
资源大小:18897k
文件大小:21k
源码类别:

MySQL数据库

开发平台:

Visual C++

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