337
337
/******************************************************************//**
338
While flushing (or removing dirty) pages from a tablespace we don't
339
want to hog the CPU and resources. Release the buffer pool and block
340
mutex and try to force a context switch. Then reacquire the same mutexes.
341
The current page is "fixed" before the release of the mutexes and then
342
"unfixed" again once we have reacquired the mutexes. */
347
buf_pool_t* buf_pool, /*!< in/out: buffer pool instance */
348
buf_page_t* bpage) /*!< in/out: current page */
350
mutex_t* block_mutex;
352
ut_ad(buf_pool_mutex_own(buf_pool));
353
ut_ad(buf_page_in_file(bpage));
355
block_mutex = buf_page_get_mutex(bpage);
357
mutex_enter(block_mutex);
358
/* "Fix" the block so that the position cannot be
359
changed after we release the buffer pool and
361
buf_page_set_sticky(bpage);
363
/* Now it is safe to release the buf_pool->mutex. */
364
buf_pool_mutex_exit(buf_pool);
366
mutex_exit(block_mutex);
367
/* Try and force a context switch. */
370
buf_pool_mutex_enter(buf_pool);
372
mutex_enter(block_mutex);
373
/* "Unfix" the block now that we have both the
374
buffer pool and block mutex again. */
375
buf_page_unset_sticky(bpage);
376
mutex_exit(block_mutex);
379
/******************************************************************//**
380
If we have hogged the resources for too long then release the buffer
381
pool and flush list mutex and do a thread yield. Set the current page
382
to "sticky" so that it is not relocated during the yield.
383
@return TRUE if yielded */
388
buf_pool_t* buf_pool, /*!< in/out: buffer pool instance */
389
buf_page_t* bpage, /*!< in/out: bpage to remove */
390
ulint processed) /*!< in: number of pages processed */
392
/* Every BUF_LRU_DROP_SEARCH_SIZE iterations in the
393
loop we release buf_pool->mutex to let other threads
394
do their job but only if the block is not IO fixed. This
395
ensures that the block stays in its position in the
399
&& processed >= BUF_LRU_DROP_SEARCH_SIZE
400
&& buf_page_get_io_fix(bpage) == BUF_IO_NONE) {
402
buf_flush_list_mutex_exit(buf_pool);
404
/* Release the buffer pool and block mutex
405
to give the other threads a go. */
407
buf_flush_yield(buf_pool, bpage);
409
buf_flush_list_mutex_enter(buf_pool);
411
/* Should not have been removed from the flush
412
list during the yield. However, this check is
413
not sufficient to catch a remove -> add. */
415
ut_ad(bpage->in_flush_list);
423
/******************************************************************//**
424
Removes a single page from a given tablespace inside a specific
425
buffer pool instance.
426
@return TRUE if page was removed. */
429
buf_flush_or_remove_page(
430
/*=====================*/
431
buf_pool_t* buf_pool, /*!< in/out: buffer pool instance */
432
buf_page_t* bpage) /*!< in/out: bpage to remove */
434
mutex_t* block_mutex;
435
ibool processed = FALSE;
437
ut_ad(buf_pool_mutex_own(buf_pool));
438
ut_ad(buf_flush_list_mutex_own(buf_pool));
440
block_mutex = buf_page_get_mutex(bpage);
442
/* bpage->space and bpage->io_fix are protected by
443
buf_pool->mutex and block_mutex. It is safe to check
444
them while holding buf_pool->mutex only. */
446
if (buf_page_get_io_fix(bpage) != BUF_IO_NONE) {
448
/* We cannot remove this page during this scan
449
yet; maybe the system is currently reading it
450
in, or flushing the modifications to the file */
454
/* We have to release the flush_list_mutex to obey the
455
latching order. We are however guaranteed that the page
456
will stay in the flush_list because buf_flush_remove()
457
needs buf_pool->mutex as well (for the non-flush case). */
459
buf_flush_list_mutex_exit(buf_pool);
461
mutex_enter(block_mutex);
463
ut_ad(bpage->oldest_modification != 0);
465
if (bpage->buf_fix_count == 0) {
467
buf_flush_remove(bpage);
472
mutex_exit(block_mutex);
474
buf_flush_list_mutex_enter(buf_pool);
477
ut_ad(!mutex_own(block_mutex));
482
/******************************************************************//**
338
483
Remove all dirty pages belonging to a given tablespace inside a specific
339
484
buffer pool instance when we are deleting the data file(s) of that
340
485
tablespace. The pages still remain a part of LRU and are evicted from
341
the list as they age towards the tail of the LRU. */
344
buf_LRU_remove_dirty_pages_for_tablespace(
345
/*======================================*/
486
the list as they age towards the tail of the LRU.
487
@return TRUE if all freed. */
490
buf_flush_or_remove_pages(
491
/*======================*/
492
buf_pool_t* buf_pool, /*!< buffer pool instance */
493
ulint id) /*!< in: target space id for which
494
to remove or flush pages */
499
ibool all_freed = TRUE;
501
buf_flush_list_mutex_enter(buf_pool);
503
for (bpage = UT_LIST_GET_LAST(buf_pool->flush_list);
507
ut_a(buf_page_in_file(bpage));
508
ut_ad(bpage->in_flush_list);
510
/* Save the previous link because once we free the
511
page we can't rely on the links. */
513
prev = UT_LIST_GET_PREV(list, bpage);
515
if (buf_page_get_space(bpage) != id) {
517
/* Skip this block, as it does not belong to
520
} else if (!buf_flush_or_remove_page(buf_pool, bpage)) {
522
/* Remove was unsuccessful, we have to try again
523
by scanning the entire list from the end. */
530
/* Yield if we have hogged the CPU and mutexes for too long. */
531
if (buf_flush_try_yield(buf_pool, prev, processed)) {
533
/* Reset the batch size counter if we had to yield. */
540
buf_flush_list_mutex_exit(buf_pool);
545
/******************************************************************//**
546
Remove or flush all the dirty pages that belong to a given tablespace
547
inside a specific buffer pool instance. The pages will remain in the LRU
548
list and will be evicted from the LRU list as they age and move towards
549
the tail of the LRU list. */
552
buf_flush_dirty_pages(
553
/*==================*/
554
buf_pool_t* buf_pool, /*!< buffer pool instance */
555
ulint id) /*!< in: space id */
560
buf_pool_mutex_enter(buf_pool);
562
all_freed = buf_flush_or_remove_pages(buf_pool, id);
564
buf_pool_mutex_exit(buf_pool);
566
ut_ad(buf_flush_validate(buf_pool));
569
os_thread_sleep(20000);
572
} while (!all_freed);
575
/******************************************************************//**
576
Remove all pages that belong to a given tablespace inside a specific
577
buffer pool instance when we are DISCARDing the tablespace. */
580
buf_LRU_remove_all_pages(
581
/*=====================*/
346
582
buf_pool_t* buf_pool, /*!< buffer pool instance */
347
583
ulint id) /*!< in: space id */
349
585
buf_page_t* bpage;
354
589
buf_pool_mutex_enter(buf_pool);
355
buf_flush_list_mutex_enter(buf_pool);
357
591
all_freed = TRUE;
359
for (bpage = UT_LIST_GET_LAST(buf_pool->flush_list), i = 0;
360
bpage != NULL; ++i) {
593
for (bpage = UT_LIST_GET_LAST(buf_pool->LRU);
362
597
buf_page_t* prev_bpage;
363
598
mutex_t* block_mutex = NULL;
365
600
ut_a(buf_page_in_file(bpage));
601
ut_ad(bpage->in_LRU_list);
367
prev_bpage = UT_LIST_GET_PREV(list, bpage);
603
prev_bpage = UT_LIST_GET_PREV(LRU, bpage);
369
605
/* bpage->space and bpage->io_fix are protected by
370
buf_pool->mutex and block_mutex. It is safe to check
606
buf_pool->mutex and the block_mutex. It is safe to check
371
607
them while holding buf_pool->mutex only. */
373
609
if (buf_page_get_space(bpage) != id) {
382
618
all_freed = FALSE;
386
/* We have to release the flush_list_mutex to obey the
387
latching order. We are however guaranteed that the page
388
will stay in the flush_list because buf_flush_remove()
389
needs buf_pool->mutex as well. */
390
buf_flush_list_mutex_exit(buf_pool);
391
block_mutex = buf_page_get_mutex(bpage);
392
mutex_enter(block_mutex);
394
if (bpage->buf_fix_count > 0) {
395
mutex_exit(block_mutex);
396
buf_flush_list_mutex_enter(buf_pool);
398
/* We cannot remove this page during
399
this scan yet; maybe the system is
400
currently reading it in, or flushing
401
the modifications to the file */
407
ut_ad(bpage->oldest_modification != 0);
409
buf_flush_remove(bpage);
411
mutex_exit(block_mutex);
412
buf_flush_list_mutex_enter(buf_pool);
622
block_mutex = buf_page_get_mutex(bpage);
623
mutex_enter(block_mutex);
625
if (bpage->buf_fix_count > 0) {
627
mutex_exit(block_mutex);
629
/* We cannot remove this page during
630
this scan yet; maybe the system is
631
currently reading it in, or flushing
632
the modifications to the file */
640
ut_ad(mutex_own(block_mutex));
643
if (buf_debug_prints) {
645
"Dropping space %lu page %lu\n",
646
(ulong) buf_page_get_space(bpage),
647
(ulong) buf_page_get_page_no(bpage));
650
if (buf_page_get_state(bpage) != BUF_BLOCK_FILE_PAGE) {
651
/* Do nothing, because the adaptive hash index
652
covers uncompressed pages only. */
653
} else if (((buf_block_t*) bpage)->index) {
657
buf_pool_mutex_exit(buf_pool);
659
zip_size = buf_page_get_zip_size(bpage);
660
page_no = buf_page_get_page_no(bpage);
662
mutex_exit(block_mutex);
664
/* Note that the following call will acquire
665
and release block->lock X-latch. */
667
btr_search_drop_page_hash_when_freed(
668
id, zip_size, page_no);
673
if (bpage->oldest_modification != 0) {
674
buf_flush_remove(bpage);
677
ut_ad(!bpage->in_flush_list);
679
/* Remove from the LRU list. */
681
if (buf_LRU_block_remove_hashed_page(bpage, TRUE)
682
!= BUF_BLOCK_ZIP_FREE) {
684
buf_LRU_block_free_hashed_page((buf_block_t*) bpage);
685
mutex_exit(block_mutex);
688
/* The block_mutex should have been released
689
by buf_LRU_block_remove_hashed_page() when it
690
returns BUF_BLOCK_ZIP_FREE. */
691
ut_ad(block_mutex == &buf_pool->zip_mutex);
694
ut_ad(!mutex_own(block_mutex));
414
697
bpage = prev_bpage;
420
/* Every BUF_LRU_DROP_SEARCH_SIZE iterations in the
421
loop we release buf_pool->mutex to let other threads
423
if (i < BUF_LRU_DROP_SEARCH_SIZE) {
427
/* We IO-fix the block to make sure that the block
428
stays in its position in the flush_list. */
429
if (buf_page_get_io_fix(bpage) != BUF_IO_NONE) {
430
/* Block is already IO-fixed. We don't
431
want to change the value. Lets leave
436
buf_flush_list_mutex_exit(buf_pool);
437
block_mutex = buf_page_get_mutex(bpage);
438
mutex_enter(block_mutex);
439
buf_page_set_sticky(bpage);
440
mutex_exit(block_mutex);
442
/* Now it is safe to release the buf_pool->mutex. */
443
buf_pool_mutex_exit(buf_pool);
445
buf_pool_mutex_enter(buf_pool);
447
mutex_enter(block_mutex);
448
buf_page_unset_sticky(bpage);
449
mutex_exit(block_mutex);
451
buf_flush_list_mutex_enter(buf_pool);
452
ut_ad(bpage->in_flush_list);
457
700
buf_pool_mutex_exit(buf_pool);
458
buf_flush_list_mutex_exit(buf_pool);
460
ut_ad(buf_flush_validate(buf_pool));
462
702
if (!all_freed) {
463
703
os_thread_sleep(20000);
469
709
/******************************************************************//**
470
Invalidates all pages belonging to a given tablespace when we are deleting
471
the data file(s) of that tablespace. */
710
Removes all pages belonging to a given tablespace. */
474
buf_LRU_invalidate_tablespace(
713
buf_LRU_flush_or_remove_pages(
475
714
/*==========================*/
476
ulint id) /*!< in: space id */
715
ulint id, /*!< in: space id */
716
enum buf_remove_t buf_remove)/*!< in: remove or flush
480
/* Before we attempt to drop pages one by one we first
481
attempt to drop page hash index entries in batches to make
482
it more efficient. The batching attempt is a best effort
483
attempt and does not guarantee that all pages hash entries
484
will be dropped. We get rid of remaining page hash entries
486
721
for (i = 0; i < srv_buf_pool_instances; i++) {
487
722
buf_pool_t* buf_pool;
489
724
buf_pool = buf_pool_from_array(i);
490
buf_LRU_drop_page_hash_for_tablespace(buf_pool, id);
491
buf_LRU_remove_dirty_pages_for_tablespace(buf_pool, id);
726
switch (buf_remove) {
727
case BUF_REMOVE_ALL_NO_WRITE:
728
/* A DISCARD tablespace case. Remove AHI entries
729
and evict all pages from LRU. */
731
/* Before we attempt to drop pages hash entries
732
one by one we first attempt to drop page hash
733
index entries in batches to make it more
734
efficient. The batching attempt is a best effort
735
attempt and does not guarantee that all pages
736
hash entries will be dropped. We get rid of
737
remaining page hash entries one by one below. */
738
buf_LRU_drop_page_hash_for_tablespace(buf_pool, id);
739
buf_LRU_remove_all_pages(buf_pool, id);
742
case BUF_REMOVE_FLUSH_NO_WRITE:
743
/* A DROP table case. AHI entries are already
744
removed. No need to evict all pages from LRU
745
list. Just evict pages from flush list without
747
buf_flush_dirty_pages(buf_pool, id);