~maria-captains/maria/xtradb-mergetree-5.5

« back to all changes in this revision

Viewing changes to buf/buf0lru.c

  • Committer: knielsen at knielsen-hq
  • Date: 2012-02-15 10:49:53 UTC
  • Revision ID: knielsen@knielsen-hq.org-20120215104953-wzcl57vil72bbmp1
Updated with XtraDB from Percona Server 5.5.20-24.1
Files copied from Percona-Server-5.5.20-rel24.1.tar.gz source tarball.

Show diffs side-by-side

added added

removed removed

Lines of Context:
68
68
 
69
69
/** When dropping the search hash index entries before deleting an ibd
70
70
file, we build a local array of pages belonging to that tablespace
71
 
in the buffer pool. Following is the size of that array. */
72
 
#define BUF_LRU_DROP_SEARCH_HASH_SIZE   1024
 
71
in the buffer pool. Following is the size of that array.
 
72
We also release buf_pool->mutex after scanning this many pages of the
 
73
flush_list when dropping a table. This is to ensure that other threads
 
74
are not blocked for extended period of time when using very large
 
75
buffer pools. */
 
76
#define BUF_LRU_DROP_SEARCH_SIZE        1024
73
77
 
74
78
/** If we switch on the InnoDB monitor because there are too few available
75
79
frames in the buffer pool, we set this to TRUE */
222
226
        ulint   i;
223
227
 
224
228
        ut_ad(arr != NULL);
225
 
        ut_ad(count <= BUF_LRU_DROP_SEARCH_HASH_SIZE);
 
229
        ut_ad(count <= BUF_LRU_DROP_SEARCH_SIZE);
226
230
 
227
231
        for (i = 0; i < count; ++i) {
228
232
                btr_search_drop_page_hash_when_freed(space_id, zip_size,
256
260
        }
257
261
 
258
262
        page_arr = ut_malloc(
259
 
                sizeof(ulint) * BUF_LRU_DROP_SEARCH_HASH_SIZE);
 
263
                sizeof(ulint) * BUF_LRU_DROP_SEARCH_SIZE);
260
264
 
261
265
        //buf_pool_mutex_enter(buf_pool);
262
266
        mutex_enter(&buf_pool->LRU_list_mutex);
293
297
 
294
298
                //mutex_enter(&((buf_block_t*) bpage)->mutex);
295
299
                is_fixed = bpage->buf_fix_count > 0
296
 
                        || !((buf_block_t*) bpage)->is_hashed;
 
300
                        || !((buf_block_t*) bpage)->index;
297
301
                //mutex_exit(&((buf_block_t*) bpage)->mutex);
298
302
 
299
303
                if (is_fixed) {
304
308
                /* Store the page number so that we can drop the hash
305
309
                index in a batch later. */
306
310
                page_arr[num_entries] = bpage->offset;
 
311
 
307
312
                mutex_exit(block_mutex);
308
313
 
309
 
                ut_a(num_entries < BUF_LRU_DROP_SEARCH_HASH_SIZE);
 
314
                ut_a(num_entries < BUF_LRU_DROP_SEARCH_SIZE);
 
315
 
310
316
                ++num_entries;
311
317
 
312
 
                if (num_entries < BUF_LRU_DROP_SEARCH_HASH_SIZE) {
 
318
                if (num_entries < BUF_LRU_DROP_SEARCH_SIZE) {
313
319
                        goto next_page;
314
320
                }
315
321
 
366
372
}
367
373
 
368
374
/******************************************************************//**
369
 
Invalidates all pages belonging to a given tablespace inside a specific
 
375
Remove all dirty pages belonging to a given tablespace inside a specific
370
376
buffer pool instance when we are deleting the data file(s) of that
371
 
tablespace. */
 
377
tablespace. The pages still remain a part of LRU and are evicted from
 
378
the list as they age towards the tail of the LRU. */
372
379
static
373
380
void
374
 
buf_LRU_invalidate_tablespace_buf_pool_instance(
375
 
/*============================================*/
 
381
buf_LRU_remove_dirty_pages_for_tablespace(
 
382
/*======================================*/
376
383
        buf_pool_t*     buf_pool,       /*!< buffer pool instance */
377
384
        ulint           id)             /*!< in: space id */
378
385
{
379
386
        buf_page_t*     bpage;
380
387
        ibool           all_freed;
 
388
        ulint           i;
381
389
 
382
390
scan_again:
383
391
        //buf_pool_mutex_enter(buf_pool);
384
392
        mutex_enter(&buf_pool->LRU_list_mutex);
385
393
        rw_lock_x_lock(&buf_pool->page_hash_latch);
 
394
        buf_flush_list_mutex_enter(buf_pool);
386
395
 
387
396
        all_freed = TRUE;
388
397
 
389
 
        bpage = UT_LIST_GET_LAST(buf_pool->LRU);
 
398
        for (bpage = UT_LIST_GET_LAST(buf_pool->flush_list), i = 0;
 
399
             bpage != NULL; ++i) {
390
400
 
391
 
        while (bpage != NULL) {
392
401
                buf_page_t*     prev_bpage;
393
402
                mutex_t*        block_mutex = NULL;
394
403
 
395
404
                ut_a(buf_page_in_file(bpage));
396
405
 
397
 
                prev_bpage = UT_LIST_GET_PREV(LRU, bpage);
 
406
                prev_bpage = UT_LIST_GET_PREV(flush_list, bpage);
398
407
 
399
408
                /* bpage->space and bpage->io_fix are protected by
400
 
                buf_pool_mutex and block_mutex.  It is safe to check
401
 
                them while holding buf_pool_mutex only. */
 
409
                buf_pool->mutex and block_mutex. It is safe to check
 
410
                them while holding buf_pool->mutex only. */
402
411
 
403
412
                if (buf_page_get_space(bpage) != id) {
404
413
                        /* Skip this block, as it does not belong to
411
420
 
412
421
                        all_freed = FALSE;
413
422
                        goto next_page;
414
 
                } else {
415
 
                        block_mutex = buf_page_get_mutex_enter(bpage);
416
 
 
417
 
                        if (!block_mutex) {
418
 
                                /* It may be impossible case...
419
 
                                Something wrong, so will be scan_again */
420
 
 
421
 
                                all_freed = FALSE;
422
 
                                goto next_page;
423
 
                        }
424
 
 
425
 
                        if (bpage->buf_fix_count > 0) {
426
 
 
427
 
                                mutex_exit(block_mutex);
428
 
                                /* We cannot remove this page during
429
 
                                this scan yet; maybe the system is
430
 
                                currently reading it in, or flushing
431
 
                                the modifications to the file */
432
 
 
433
 
                                all_freed = FALSE;
434
 
 
435
 
                                goto next_page;
436
 
                        }
437
 
                }
438
 
 
439
 
                ut_ad(mutex_own(block_mutex));
440
 
 
441
 
#ifdef UNIV_DEBUG
442
 
                if (buf_debug_prints) {
443
 
                        fprintf(stderr,
444
 
                                "Dropping space %lu page %lu\n",
445
 
                                (ulong) buf_page_get_space(bpage),
446
 
                                (ulong) buf_page_get_page_no(bpage));
447
 
                }
448
 
#endif
449
 
                if (buf_page_get_state(bpage) != BUF_BLOCK_FILE_PAGE) {
450
 
                        /* This is a compressed-only block
451
 
                        descriptor. Do nothing. */
452
 
                } else if (((buf_block_t*) bpage)->is_hashed) {
453
 
                        ulint   page_no;
454
 
                        ulint   zip_size;
455
 
 
456
 
                        //buf_pool_mutex_exit(buf_pool);
457
 
                        mutex_exit(&buf_pool->LRU_list_mutex);
458
 
                        rw_lock_x_unlock(&buf_pool->page_hash_latch);
459
 
 
460
 
                        zip_size = buf_page_get_zip_size(bpage);
461
 
                        page_no = buf_page_get_page_no(bpage);
462
 
 
463
 
                        mutex_exit(block_mutex);
464
 
 
465
 
                        /* Note that the following call will acquire
466
 
                        an S-latch on the page */
467
 
 
468
 
                        btr_search_drop_page_hash_when_freed(
469
 
                                id, zip_size, page_no);
470
 
                        goto scan_again;
471
 
                }
472
 
 
473
 
                if (bpage->oldest_modification != 0) {
474
 
 
475
 
                        buf_flush_remove(bpage);
476
 
                }
477
 
 
478
 
                /* Remove from the LRU list. */
479
 
 
480
 
                if (buf_LRU_block_remove_hashed_page(bpage, TRUE)
481
 
                    != BUF_BLOCK_ZIP_FREE) {
482
 
                        buf_LRU_block_free_hashed_page((buf_block_t*) bpage, TRUE);
483
 
                        mutex_exit(block_mutex);
484
 
                } else {
485
 
                        /* The block_mutex should have been released
486
 
                        by buf_LRU_block_remove_hashed_page() when it
487
 
                        returns BUF_BLOCK_ZIP_FREE. */
488
 
                        ut_ad(block_mutex == &buf_pool->zip_mutex);
489
 
                        ut_ad(!mutex_own(block_mutex));
490
 
                }
 
423
                }
 
424
 
 
425
                /* We have to release the flush_list_mutex to obey the
 
426
                latching order. We are however guaranteed that the page
 
427
                will stay in the flush_list because buf_flush_remove()
 
428
                needs buf_pool->mutex as well. */
 
429
                buf_flush_list_mutex_exit(buf_pool);
 
430
                block_mutex = buf_page_get_mutex_enter(bpage);
 
431
 
 
432
                if (!block_mutex) {
 
433
                        /* It may be impossible case...
 
434
                        Something wrong, so will be scan_again */
 
435
                        all_freed = FALSE;
 
436
                        goto next_page;
 
437
                }
 
438
 
 
439
                if (bpage->buf_fix_count > 0) {
 
440
                        mutex_exit(block_mutex);
 
441
                        buf_flush_list_mutex_enter(buf_pool);
 
442
 
 
443
                        /* We cannot remove this page during
 
444
                        this scan yet; maybe the system is
 
445
                        currently reading it in, or flushing
 
446
                        the modifications to the file */
 
447
 
 
448
                        all_freed = FALSE;
 
449
                        goto next_page;
 
450
                }
 
451
 
 
452
                ut_ad(bpage->oldest_modification != 0);
 
453
 
 
454
                buf_flush_remove(bpage);
 
455
 
 
456
                mutex_exit(block_mutex);
 
457
                buf_flush_list_mutex_enter(buf_pool);
491
458
next_page:
492
459
                bpage = prev_bpage;
 
460
 
 
461
                if (!bpage) {
 
462
                        break;
 
463
                }
 
464
 
 
465
                /* Every BUF_LRU_DROP_SEARCH_SIZE iterations in the
 
466
                loop we release buf_pool->mutex to let other threads
 
467
                do their job. */
 
468
                if (i < BUF_LRU_DROP_SEARCH_SIZE) {
 
469
                        continue;
 
470
                }
 
471
 
 
472
                /* We IO-fix the block to make sure that the block
 
473
                stays in its position in the flush_list. */
 
474
                if (buf_page_get_io_fix(bpage) != BUF_IO_NONE) {
 
475
                        /* Block is already IO-fixed. We don't
 
476
                        want to change the value. Lets leave
 
477
                        this block alone. */
 
478
                        continue;
 
479
                }
 
480
 
 
481
                buf_flush_list_mutex_exit(buf_pool);
 
482
                block_mutex = buf_page_get_mutex(bpage);
 
483
                mutex_enter(block_mutex);
 
484
                buf_page_set_sticky(bpage);
 
485
                mutex_exit(block_mutex);
 
486
 
 
487
                /* Now it is safe to release the buf_pool->mutex. */
 
488
                //buf_pool_mutex_exit(buf_pool);
 
489
                mutex_exit(&buf_pool->LRU_list_mutex);
 
490
                rw_lock_x_unlock(&buf_pool->page_hash_latch);
 
491
 
 
492
                os_thread_yield();
 
493
                //buf_pool_mutex_enter(buf_pool);
 
494
                mutex_enter(&buf_pool->LRU_list_mutex);
 
495
                rw_lock_x_lock(&buf_pool->page_hash_latch);
 
496
 
 
497
 
 
498
                mutex_enter(block_mutex);
 
499
                buf_page_unset_sticky(bpage);
 
500
                mutex_exit(block_mutex);
 
501
 
 
502
                buf_flush_list_mutex_enter(buf_pool);
 
503
                ut_ad(bpage->in_flush_list);
 
504
 
 
505
                i = 0;
493
506
        }
494
507
 
495
 
        //buf_pool_mutex_exit(buf_pool);
 
508
//      buf_pool_mutex_exit(buf_pool);
496
509
        mutex_exit(&buf_pool->LRU_list_mutex);
497
510
        rw_lock_x_unlock(&buf_pool->page_hash_latch);
 
511
        buf_flush_list_mutex_exit(buf_pool);
 
512
 
 
513
        ut_ad(buf_flush_validate(buf_pool));
498
514
 
499
515
        if (!all_freed) {
500
516
                os_thread_sleep(20000);
525
541
 
526
542
                buf_pool = buf_pool_from_array(i);
527
543
                buf_LRU_drop_page_hash_for_tablespace(buf_pool, id);
528
 
                buf_LRU_invalidate_tablespace_buf_pool_instance(buf_pool, id);
 
544
                buf_LRU_remove_dirty_pages_for_tablespace(buf_pool, id);
529
545
        }
530
546
}
531
547
 
567
583
                        for (k = chunk->size; k--; block++) {
568
584
                                if (buf_block_get_state(block)
569
585
                                    != BUF_BLOCK_FILE_PAGE
570
 
                                    || !block->is_hashed
 
586
                                    || !block->index
571
587
                                    || buf_page_get_space(&block->page) != id) {
572
588
                                        continue;
573
589
                                }
575
591
                                btr_search_s_unlock_all();
576
592
 
577
593
                                rw_lock_x_lock(&block->lock);
578
 
                                btr_search_drop_page_hash_index(block, NULL);
 
594
                                btr_search_drop_page_hash_index(block);
579
595
                                rw_lock_x_unlock(&block->lock);
580
596
 
581
597
                                btr_search_s_lock_all();
1726
1742
                        /* Prevent buf_page_get_gen() from
1727
1743
                        decompressing the block while we release
1728
1744
                        buf_pool->mutex and block_mutex. */
1729
 
                        b->buf_fix_count++;
1730
 
                        b->io_fix = BUF_IO_READ;
 
1745
                        buf_page_set_sticky(b);
1731
1746
                        mutex_exit(&buf_pool->zip_mutex);
1732
1747
                }
1733
1748
 
1744
1759
 
1745
1760
                UNIV_MEM_VALID(((buf_block_t*) bpage)->frame,
1746
1761
                               UNIV_PAGE_SIZE);
1747
 
                btr_search_drop_page_hash_index((buf_block_t*) bpage, NULL);
 
1762
                btr_search_drop_page_hash_index((buf_block_t*) bpage);
1748
1763
                UNIV_MEM_INVALID(((buf_block_t*) bpage)->frame,
1749
1764
                                 UNIV_PAGE_SIZE);
1750
1765
 
1772
1787
 
1773
1788
                if (b) {
1774
1789
                        mutex_enter(&buf_pool->zip_mutex);
1775
 
                        b->buf_fix_count--;
1776
 
                        buf_page_set_io_fix(b, BUF_IO_NONE);
 
1790
                        buf_page_unset_sticky(b);
1777
1791
                        mutex_exit(&buf_pool->zip_mutex);
1778
1792
                }
1779
1793