~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

[patch 112/129] Merge patch for revision 1925 from InnoDB SVN:
revno: 1925
revision-id: svn-v4:16c675df-0fcb-4bc9-8058-dcc011a37293:branches/zip:6169
parent: svn-v4:16c675df-0fcb-4bc9-8058-dcc011a37293:branches/zip:6163
committer: calvin
timestamp: Thu 2009-11-12 12:40:43 +0000
message:
  branches/zip: add test case for bug#46676
  
  This crash is reproducible with InnoDB plugin 1.0.4 + MySQL 5.1.37.
  But no longer reproducible after MySQL 5.1.38 (with plugin 1.0.5).
  Add test case to catch future regression.
added:
  mysql-test/innodb_bug46676.result 6169@16c675df-0fcb-4bc9-8058-dcc011a37293:branches%2Fzip%2Fmysql-test%2Finnodb_bug46676.result
  mysql-test/innodb_bug46676.test 6169@16c675df-0fcb-4bc9-8058-dcc011a37293:branches%2Fzip%2Fmysql-test%2Finnodb_bug46676.test
diff:
=== added file 'mysql-test/innodb_bug46676.result'

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
158
158
}
159
159
 
160
160
/********************************************************************//**
 
161
Applies a random read-ahead in buf_pool if there are at least a threshold
 
162
value of accessed pages from the random read-ahead area. Does not read any
 
163
page, not even the one at the position (space, offset), if the read-ahead
 
164
mechanism is not activated. NOTE 1: the calling thread may own latches on
 
165
pages: to avoid deadlocks this function must be written such that it cannot
 
166
end up waiting for these latches! NOTE 2: the calling thread must want
 
167
access to the page given: this rule is set to prevent unintended read-aheads
 
168
performed by ibuf routines, a situation which could result in a deadlock if
 
169
the OS does not support asynchronous i/o.
 
170
@return number of page read requests issued; NOTE that if we read ibuf
 
171
pages, it may happen that the page at the given page number does not
 
172
get read even if we return a positive value! */
 
173
static
 
174
ulint
 
175
buf_read_ahead_random(
 
176
/*==================*/
 
177
        ulint   space,  /*!< in: space id */
 
178
        ulint   zip_size,/*!< in: compressed page size in bytes, or 0 */
 
179
        ulint   offset) /*!< in: page number of a page which the current thread
 
180
                        wants to access */
 
181
{
 
182
        (void)space;
 
183
        (void)zip_size;
 
184
        (void)offset;
 
185
        /* We have currently disabled random readahead */
 
186
        return(0);
 
187
 
 
188
}
 
189
 
 
190
/********************************************************************//**
161
191
High-level function which reads a page asynchronously from a file to the
162
192
buffer buf_pool if it is not already there. Sets the io_fix flag and sets
163
193
an exclusive lock on the buffer frame. The flag is cleared and the x-lock
171
201
        ulint   zip_size,/*!< in: compressed page size in bytes, or 0 */
172
202
        ulint   offset) /*!< in: page number */
173
203
{
174
 
        buf_pool_t*     buf_pool = buf_pool_get(space, offset);
175
204
        ib_int64_t      tablespace_version;
176
205
        ulint           count;
 
206
        ulint           count2;
177
207
        ulint           err;
178
208
 
179
209
        tablespace_version = fil_space_get_version(space);
180
210
 
 
211
        count = buf_read_ahead_random(space, zip_size, offset);
 
212
 
181
213
        /* We do the i/o in the synchronous aio mode to save thread
182
214
        switches: hence TRUE */
183
215
 
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;
 
216
        count2 = buf_read_page_low(&err, TRUE, BUF_READ_ANY_PAGE, space,
 
217
                                   zip_size, FALSE,
 
218
                                   tablespace_version, offset);
 
219
        srv_buf_pool_reads+= count2;
188
220
        if (err == DB_TABLESPACE_DELETED) {
189
221
                ut_print_timestamp(stderr);
190
222
                fprintf(stderr,
196
228
        }
197
229
 
198
230
        /* Flush pages from the end of the LRU list if necessary */
199
 
        buf_flush_free_margin(buf_pool);
 
231
        buf_flush_free_margin();
200
232
 
201
233
        /* Increment number of I/O operations used for LRU policy. */
202
234
        buf_LRU_stat_inc_io();
203
235
 
204
 
        return(count);
 
236
        return((count + count2) > 0);
205
237
}
206
238
 
207
239
/********************************************************************//**
237
269
        ulint   offset) /*!< in: page number of a page; NOTE: the current thread
238
270
                        must want access to this page (see NOTE 3 above) */
239
271
{
240
 
        buf_pool_t*     buf_pool = buf_pool_get(space, offset);
241
272
        ib_int64_t      tablespace_version;
242
273
        buf_page_t*     bpage;
243
274
        buf_frame_t*    frame;
253
284
        ulint           err;
254
285
        ulint           i;
255
286
        const ulint     buf_read_ahead_linear_area
256
 
                = BUF_READ_AHEAD_LINEAR_AREA(buf_pool);
 
287
                = BUF_READ_AHEAD_LINEAR_AREA;
257
288
        ulint           threshold;
258
289
 
259
290
        if (UNIV_UNLIKELY(srv_startup_is_before_trx_rollback_phase)) {
288
319
 
289
320
        tablespace_version = fil_space_get_version(space);
290
321
 
291
 
        buf_pool_mutex_enter(buf_pool);
 
322
        buf_pool_mutex_enter();
292
323
 
293
324
        if (high > fil_space_get_size(space)) {
294
 
                buf_pool_mutex_exit(buf_pool);
 
325
                buf_pool_mutex_exit();
295
326
                /* The area is not whole, return */
296
327
 
297
328
                return(0);
299
330
 
300
331
        if (buf_pool->n_pend_reads
301
332
            > buf_pool->curr_size / BUF_READ_AHEAD_PEND_LIMIT) {
302
 
                buf_pool_mutex_exit(buf_pool);
 
333
                buf_pool_mutex_exit();
303
334
 
304
335
                return(0);
305
336
        }
317
348
        /* How many out of order accessed pages can we ignore
318
349
        when working out the access pattern for linear readahead */
319
350
        threshold = ut_min((64 - srv_read_ahead_threshold),
320
 
                           BUF_READ_AHEAD_AREA(buf_pool));
 
351
                           BUF_READ_AHEAD_AREA);
321
352
 
322
353
        fail_count = 0;
323
354
 
324
355
        for (i = low; i < high; i++) {
325
 
                bpage = buf_page_hash_get(buf_pool, space, i);
 
356
                bpage = buf_page_hash_get(space, i);
326
357
 
327
 
                if (bpage == NULL || !buf_page_is_accessed(bpage)) {
 
358
                if ((bpage == NULL) || !buf_page_is_accessed(bpage)) {
328
359
                        /* Not accessed */
329
360
                        fail_count++;
330
361
 
331
362
                } 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));
 
363
                        int res = (ut_ulint_cmp(
 
364
                                       buf_page_get_LRU_position(bpage),
 
365
                                       buf_page_get_LRU_position(pred_bpage)));
343
366
                        /* Accesses not in the right order */
344
367
                        if (res != 0 && res != asc_or_desc) {
345
368
                                fail_count++;
348
371
 
349
372
                if (fail_count > threshold) {
350
373
                        /* Too many failures: return */
351
 
                        buf_pool_mutex_exit(buf_pool);
 
374
                        buf_pool_mutex_exit();
352
375
                        return(0);
353
376
                }
354
377
 
360
383
        /* If we got this far, we know that enough pages in the area have
361
384
        been accessed in the right order: linear read-ahead can be sensible */
362
385
 
363
 
        bpage = buf_page_hash_get(buf_pool, space, offset);
 
386
        bpage = buf_page_hash_get(space, offset);
364
387
 
365
388
        if (bpage == NULL) {
366
 
                buf_pool_mutex_exit(buf_pool);
 
389
                buf_pool_mutex_exit();
367
390
 
368
391
                return(0);
369
392
        }
389
412
        pred_offset = fil_page_get_prev(frame);
390
413
        succ_offset = fil_page_get_next(frame);
391
414
 
392
 
        buf_pool_mutex_exit(buf_pool);
 
415
        buf_pool_mutex_exit();
393
416
 
394
417
        if ((offset == low) && (succ_offset == offset + 1)) {
395
418
 
468
491
        os_aio_simulated_wake_handler_threads();
469
492
 
470
493
        /* Flush pages from the end of the LRU list if necessary */
471
 
        buf_flush_free_margin(buf_pool);
 
494
        buf_flush_free_margin();
472
495
 
473
496
#ifdef UNIV_DEBUG
474
497
        if (buf_debug_prints && (count > 0)) {
520
543
#ifdef UNIV_IBUF_DEBUG
521
544
        ut_a(n_stored < UNIV_PAGE_SIZE);
522
545
#endif
 
546
        while (buf_pool->n_pend_reads
 
547
               > buf_pool->curr_size / BUF_READ_AHEAD_PEND_LIMIT) {
 
548
                os_thread_sleep(500000);
 
549
        }
523
550
 
524
551
        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
 
                }
 
552
                ulint   zip_size = fil_space_get_zip_size(space_ids[i]);
 
553
                ulint   err;
535
554
 
536
555
                if (UNIV_UNLIKELY(zip_size == ULINT_UNDEFINED)) {
537
556
 
556
575
 
557
576
        os_aio_simulated_wake_handler_threads();
558
577
 
559
 
        /* Flush pages from the end of all the LRU lists if necessary */
560
 
        buf_flush_free_margins();
 
578
        /* Flush pages from the end of the LRU list if necessary */
 
579
        buf_flush_free_margin();
561
580
 
562
581
#ifdef UNIV_DEBUG
563
582
        if (buf_debug_prints) {
606
625
        tablespace_version = fil_space_get_version(space);
607
626
 
608
627
        for (i = 0; i < n_stored; i++) {
609
 
                buf_pool_t*     buf_pool;
610
628
 
611
629
                count = 0;
612
630
 
613
631
                os_aio_print_debug = FALSE;
614
 
                buf_pool = buf_pool_get(space, page_nos[i]);
 
632
 
615
633
                while (buf_pool->n_pend_reads >= recv_n_pool_free_frames / 2) {
616
634
 
617
635
                        os_aio_simulated_wake_handler_threads();
618
 
                        os_thread_sleep(10000);
 
636
                        os_thread_sleep(500000);
619
637
 
620
638
                        count++;
621
639
 
622
 
                        if (count > 1000) {
 
640
                        if (count > 100) {
623
641
                                fprintf(stderr,
624
642
                                        "InnoDB: Error: InnoDB has waited for"
625
 
                                        " 10 seconds for pending\n"
 
643
                                        " 50 seconds for pending\n"
626
644
                                        "InnoDB: reads to the buffer pool to"
627
645
                                        " be finished.\n"
628
646
                                        "InnoDB: Number of pending reads %lu,"
650
668
 
651
669
        os_aio_simulated_wake_handler_threads();
652
670
 
653
 
        /* Flush pages from the end of all the LRU lists if necessary */
654
 
        buf_flush_free_margins();
 
671
        /* Flush pages from the end of the LRU list if necessary */
 
672
        buf_flush_free_margin();
655
673
 
656
674
#ifdef UNIV_DEBUG
657
675
        if (buf_debug_prints) {