~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

  • Committer: Patrick Crews
  • Date: 2010-09-14 20:21:03 UTC
  • mto: (1771.1.1 pcrews)
  • mto: This revision was merged to the branch mainline in revision 1772.
  • Revision ID: gleebix@gmail.com-20100914202103-1db2n0bshzafep19
Moved transaction_log tests into updated non-publisher-based tree

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*****************************************************************************
2
2
 
3
 
Copyright (C) 1995, 2010, Innobase Oy. All Rights Reserved.
 
3
Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
4
4
 
5
5
This program is free software; you can redistribute it and/or modify it under
6
6
the terms of the GNU General Public License as published by the Free Software
11
11
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
12
12
 
13
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., 51 Franklin
15
 
St, Fifth Floor, Boston, MA 02110-1301 USA
 
14
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
 
15
Place, Suite 330, Boston, MA 02111-1307 USA
16
16
 
17
17
*****************************************************************************/
18
18
 
38
38
#include "srv0start.h"
39
39
#include "srv0srv.h"
40
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
 
41
49
/** The linear read-ahead area size */
42
50
#define BUF_READ_AHEAD_LINEAR_AREA      BUF_READ_AHEAD_AREA
43
51
 
54
62
@return 1 if a read request was queued, 0 if the page already resided
55
63
in buf_pool, or if the page is in the doublewrite buffer blocks in
56
64
which case it is never read into the pool, or if the tablespace does
57
 
not exist or is being dropped 
58
 
@return 1 if read request is issued. 0 if it is not */
 
65
not exist or is being dropped */
59
66
static
60
67
ulint
61
68
buf_read_page_low(
158
165
}
159
166
 
160
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
/********************************************************************//**
161
198
High-level function which reads a page asynchronously from a file to the
162
199
buffer buf_pool if it is not already there. Sets the io_fix flag and sets
163
200
an exclusive lock on the buffer frame. The flag is cleared and the x-lock
164
 
released by the i/o-handler thread.
165
 
@return TRUE if page has been read in, FALSE in case of failure */
 
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 */
166
205
UNIV_INTERN
167
 
ibool
 
206
ulint
168
207
buf_read_page(
169
208
/*==========*/
170
209
        ulint   space,  /*!< in: space id */
171
210
        ulint   zip_size,/*!< in: compressed page size in bytes, or 0 */
172
211
        ulint   offset) /*!< in: page number */
173
212
{
174
 
        buf_pool_t*     buf_pool = buf_pool_get(space, offset);
175
213
        ib_int64_t      tablespace_version;
176
214
        ulint           count;
 
215
        ulint           count2;
177
216
        ulint           err;
178
217
 
179
218
        tablespace_version = fil_space_get_version(space);
180
219
 
 
220
        count = buf_read_ahead_random(space, zip_size, offset);
 
221
 
181
222
        /* We do the i/o in the synchronous aio mode to save thread
182
223
        switches: hence TRUE */
183
224
 
184
 
        count = buf_read_page_low(&err, TRUE, BUF_READ_ANY_PAGE, space,
185
 
                                  zip_size, FALSE,
186
 
                                  tablespace_version, offset);
187
 
        srv_buf_pool_reads += count;
 
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;
188
229
        if (err == DB_TABLESPACE_DELETED) {
189
230
                ut_print_timestamp(stderr);
190
231
                fprintf(stderr,
196
237
        }
197
238
 
198
239
        /* Flush pages from the end of the LRU list if necessary */
199
 
        buf_flush_free_margin(buf_pool);
 
240
        buf_flush_free_margin();
200
241
 
201
242
        /* Increment number of I/O operations used for LRU policy. */
202
243
        buf_LRU_stat_inc_io();
203
244
 
204
 
        return(count);
 
245
        return(count + count2);
205
246
}
206
247
 
207
248
/********************************************************************//**
237
278
        ulint   offset) /*!< in: page number of a page; NOTE: the current thread
238
279
                        must want access to this page (see NOTE 3 above) */
239
280
{
240
 
        buf_pool_t*     buf_pool = buf_pool_get(space, offset);
241
281
        ib_int64_t      tablespace_version;
242
282
        buf_page_t*     bpage;
243
283
        buf_frame_t*    frame;
253
293
        ulint           err;
254
294
        ulint           i;
255
295
        const ulint     buf_read_ahead_linear_area
256
 
                = BUF_READ_AHEAD_LINEAR_AREA(buf_pool);
 
296
                = BUF_READ_AHEAD_LINEAR_AREA;
257
297
        ulint           threshold;
258
298
 
259
299
        if (UNIV_UNLIKELY(srv_startup_is_before_trx_rollback_phase)) {
288
328
 
289
329
        tablespace_version = fil_space_get_version(space);
290
330
 
291
 
        buf_pool_mutex_enter(buf_pool);
 
331
        buf_pool_mutex_enter();
292
332
 
293
333
        if (high > fil_space_get_size(space)) {
294
 
                buf_pool_mutex_exit(buf_pool);
 
334
                buf_pool_mutex_exit();
295
335
                /* The area is not whole, return */
296
336
 
297
337
                return(0);
299
339
 
300
340
        if (buf_pool->n_pend_reads
301
341
            > buf_pool->curr_size / BUF_READ_AHEAD_PEND_LIMIT) {
302
 
                buf_pool_mutex_exit(buf_pool);
 
342
                buf_pool_mutex_exit();
303
343
 
304
344
                return(0);
305
345
        }
317
357
        /* How many out of order accessed pages can we ignore
318
358
        when working out the access pattern for linear readahead */
319
359
        threshold = ut_min((64 - srv_read_ahead_threshold),
320
 
                           BUF_READ_AHEAD_AREA(buf_pool));
 
360
                           BUF_READ_AHEAD_AREA);
321
361
 
322
362
        fail_count = 0;
323
363
 
324
364
        for (i = low; i < high; i++) {
325
 
                bpage = buf_page_hash_get(buf_pool, space, i);
 
365
                bpage = buf_page_hash_get(space, i);
326
366
 
327
 
                if (bpage == NULL || !buf_page_is_accessed(bpage)) {
 
367
                if ((bpage == NULL) || !buf_page_is_accessed(bpage)) {
328
368
                        /* Not accessed */
329
369
                        fail_count++;
330
370
 
331
371
                } else if (pred_bpage) {
332
 
                       /* Note that buf_page_is_accessed() returns
333
 
                       the time of the first access.  If some blocks
334
 
                       of the extent existed in the buffer pool at
335
 
                       the time of a linear access pattern, the first
336
 
                       access times may be nonmonotonic, even though
337
 
                       the latest access times were linear.  The
338
 
                       threshold (srv_read_ahead_factor) should help
339
 
                       a little against this. */
340
 
                       int res = ut_ulint_cmp(
341
 
                               buf_page_is_accessed(bpage),
342
 
                               buf_page_is_accessed(pred_bpage));
 
372
                        int res = (ut_ulint_cmp(
 
373
                                       buf_page_get_LRU_position(bpage),
 
374
                                       buf_page_get_LRU_position(pred_bpage)));
343
375
                        /* Accesses not in the right order */
344
376
                        if (res != 0 && res != asc_or_desc) {
345
377
                                fail_count++;
348
380
 
349
381
                if (fail_count > threshold) {
350
382
                        /* Too many failures: return */
351
 
                        buf_pool_mutex_exit(buf_pool);
 
383
                        buf_pool_mutex_exit();
352
384
                        return(0);
353
385
                }
354
386
 
360
392
        /* If we got this far, we know that enough pages in the area have
361
393
        been accessed in the right order: linear read-ahead can be sensible */
362
394
 
363
 
        bpage = buf_page_hash_get(buf_pool, space, offset);
 
395
        bpage = buf_page_hash_get(space, offset);
364
396
 
365
397
        if (bpage == NULL) {
366
 
                buf_pool_mutex_exit(buf_pool);
 
398
                buf_pool_mutex_exit();
367
399
 
368
400
                return(0);
369
401
        }
389
421
        pred_offset = fil_page_get_prev(frame);
390
422
        succ_offset = fil_page_get_next(frame);
391
423
 
392
 
        buf_pool_mutex_exit(buf_pool);
 
424
        buf_pool_mutex_exit();
393
425
 
394
426
        if ((offset == low) && (succ_offset == offset + 1)) {
395
427
 
468
500
        os_aio_simulated_wake_handler_threads();
469
501
 
470
502
        /* Flush pages from the end of the LRU list if necessary */
471
 
        buf_flush_free_margin(buf_pool);
 
503
        buf_flush_free_margin();
472
504
 
473
505
#ifdef UNIV_DEBUG
474
506
        if (buf_debug_prints && (count > 0)) {
482
514
        LRU policy decision. */
483
515
        buf_LRU_stat_inc_io();
484
516
 
485
 
        buf_pool->stat.n_ra_pages_read += count;
 
517
        ++srv_read_ahead_seq;
486
518
        return(count);
487
519
}
488
520
 
520
552
#ifdef UNIV_IBUF_DEBUG
521
553
        ut_a(n_stored < UNIV_PAGE_SIZE);
522
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
        }
523
559
 
524
560
        for (i = 0; i < n_stored; i++) {
525
 
                ulint           err;
526
 
                buf_pool_t*     buf_pool;
527
 
                ulint           zip_size = fil_space_get_zip_size(space_ids[i]);
528
 
 
529
 
                buf_pool = buf_pool_get(space_ids[i], space_versions[i]);
530
 
 
531
 
                while (buf_pool->n_pend_reads
532
 
                       > buf_pool->curr_size / BUF_READ_AHEAD_PEND_LIMIT) {
533
 
                        os_thread_sleep(500000);
534
 
                }
 
561
                ulint   zip_size = fil_space_get_zip_size(space_ids[i]);
 
562
                ulint   err;
535
563
 
536
564
                if (UNIV_UNLIKELY(zip_size == ULINT_UNDEFINED)) {
537
565
 
556
584
 
557
585
        os_aio_simulated_wake_handler_threads();
558
586
 
559
 
        /* Flush pages from the end of all the LRU lists if necessary */
560
 
        buf_flush_free_margins();
 
587
        /* Flush pages from the end of the LRU list if necessary */
 
588
        buf_flush_free_margin();
561
589
 
562
590
#ifdef UNIV_DEBUG
563
591
        if (buf_debug_prints) {
606
634
        tablespace_version = fil_space_get_version(space);
607
635
 
608
636
        for (i = 0; i < n_stored; i++) {
609
 
                buf_pool_t*     buf_pool;
610
637
 
611
638
                count = 0;
612
639
 
613
640
                os_aio_print_debug = FALSE;
614
 
                buf_pool = buf_pool_get(space, page_nos[i]);
 
641
 
615
642
                while (buf_pool->n_pend_reads >= recv_n_pool_free_frames / 2) {
616
643
 
617
644
                        os_aio_simulated_wake_handler_threads();
618
 
                        os_thread_sleep(10000);
 
645
                        os_thread_sleep(500000);
619
646
 
620
647
                        count++;
621
648
 
622
 
                        if (count > 1000) {
 
649
                        if (count > 100) {
623
650
                                fprintf(stderr,
624
651
                                        "InnoDB: Error: InnoDB has waited for"
625
 
                                        " 10 seconds for pending\n"
 
652
                                        " 50 seconds for pending\n"
626
653
                                        "InnoDB: reads to the buffer pool to"
627
654
                                        " be finished.\n"
628
655
                                        "InnoDB: Number of pending reads %lu,"
650
677
 
651
678
        os_aio_simulated_wake_handler_threads();
652
679
 
653
 
        /* Flush pages from the end of all the LRU lists if necessary */
654
 
        buf_flush_free_margins();
 
680
        /* Flush pages from the end of the LRU list if necessary */
 
681
        buf_flush_free_margin();
655
682
 
656
683
#ifdef UNIV_DEBUG
657
684
        if (buf_debug_prints) {