Skip to content

Commit 2945337

Browse files
author
Yasufumi Kinoshita
committed
backport Bug#31060470 to 5.7
Bug#31060470 : InnoDB temp table could hurt InnoDB perf badly (Bug#98974) Minimizes flush_list scanning to find the oldest page except for system temporary. Because the huge number of system temporary pages cause too long scan. - new FlushHp, buf_pool->oldest_hp is introduced - minimizes scan also at page_cleaner_flush_pages_recommendation() * Fixed also the one of the susupected causers of Bug#31073853 buf_flush_relocate_on_flush_list() should move the hp not to skip the page, when conflict with hp. RB: 26176 Reviewed-by: Debarun Banerjee <debarun.banerjee@oracle.com>
1 parent 9bc3ab2 commit 2945337

File tree

3 files changed

+63
-4
lines changed

3 files changed

+63
-4
lines changed

storage/innobase/buf/buf0buf.cc

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -424,8 +424,14 @@ buf_pool_get_oldest_modification(void)
424424
/* We don't let log-checkpoint halt because pages from system
425425
temporary are not yet flushed to the disk. Anyway, object
426426
residing in system temporary doesn't generate REDO logging. */
427-
for (bpage = UT_LIST_GET_LAST(buf_pool->flush_list);
428-
bpage != NULL
427+
bpage = buf_pool->oldest_hp.get();
428+
if (bpage != NULL) {
429+
ut_ad(bpage->in_flush_list);
430+
} else {
431+
bpage = UT_LIST_GET_LAST(buf_pool->flush_list);
432+
}
433+
434+
for (; bpage != NULL
429435
&& fsp_is_system_temporary(bpage->id.space());
430436
bpage = UT_LIST_GET_PREV(list, bpage)) {
431437
/* Do nothing. */
@@ -434,6 +440,12 @@ buf_pool_get_oldest_modification(void)
434440
if (bpage != NULL) {
435441
ut_ad(bpage->in_flush_list);
436442
lsn = bpage->oldest_modification;
443+
buf_pool->oldest_hp.set(bpage);
444+
} else {
445+
/* The last scanned page as entry point,
446+
or nullptr. */
447+
buf_pool->oldest_hp.set(
448+
UT_LIST_GET_FIRST(buf_pool->flush_list));
437449
}
438450

439451
buf_flush_list_mutex_exit(buf_pool);
@@ -1844,6 +1856,10 @@ buf_pool_init_instance(
18441856
new(&buf_pool->flush_hp)
18451857
FlushHp(buf_pool, &buf_pool->flush_list_mutex);
18461858

1859+
/* Initialize the hazard pointer for the oldest page scan */
1860+
new (&buf_pool->oldest_hp)
1861+
FlushHp(buf_pool, &buf_pool->flush_list_mutex);
1862+
18471863
/* Initialize the hazard pointer for LRU batches */
18481864
new(&buf_pool->lru_hp) LRUHp(buf_pool, &buf_pool->mutex);
18491865

@@ -3196,6 +3212,21 @@ HazardPointer::is_hp(const buf_page_t* bpage)
31963212
return(bpage == m_hp);
31973213
}
31983214

3215+
/** Adjust the value of hp for moving. This happens when some other thread
3216+
working on the same list attempts to relocate the hp of the page.
3217+
@param bpage buffer block to be compared
3218+
@param dpage buffer block to be moved to */
3219+
void
3220+
HazardPointer::move(const buf_page_t *bpage, buf_page_t *dpage)
3221+
{
3222+
ut_ad(bpage != NULL);
3223+
ut_ad(dpage != NULL);
3224+
3225+
if (is_hp(bpage)) {
3226+
m_hp = dpage;
3227+
}
3228+
}
3229+
31993230
/** Adjust the value of hp. This happens when some other thread working
32003231
on the same list attempts to remove the hp from the list.
32013232
@param bpage buffer block to be compared */

storage/innobase/buf/buf0flu.cc

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -561,6 +561,11 @@ buf_flush_insert_sorted_into_flush_list(
561561
UT_LIST_INSERT_AFTER(buf_pool->flush_list, prev_b, &block->page);
562562
}
563563

564+
if (buf_pool->oldest_hp.get() != NULL) {
565+
/* clear oldest_hp */
566+
buf_pool->oldest_hp.set(NULL);
567+
}
568+
564569
incr_flush_list_size_in_bytes(block, buf_pool);
565570

566571
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
@@ -658,6 +663,7 @@ buf_flush_remove(
658663
/* Important that we adjust the hazard pointer before removing
659664
the bpage from flush list. */
660665
buf_pool->flush_hp.adjust(bpage);
666+
buf_pool->oldest_hp.adjust(bpage);
661667

662668
switch (buf_page_get_state(bpage)) {
663669
case BUF_BLOCK_POOL_WATCH:
@@ -757,7 +763,8 @@ buf_flush_relocate_on_flush_list(
757763

758764
/* Important that we adjust the hazard pointer before removing
759765
the bpage from the flush list. */
760-
buf_pool->flush_hp.adjust(bpage);
766+
buf_pool->flush_hp.move(bpage, dpage);
767+
buf_pool->oldest_hp.move(bpage, dpage);
761768

762769
/* Must be done after we have removed it from the flush_rbt
763770
because we assert on in_flush_list in comparison function. */
@@ -2599,6 +2606,15 @@ page_cleaner_flush_pages_recommendation(
25992606
lsn_t target_lsn = oldest_lsn
26002607
+ lsn_avg_rate * buf_flush_lsn_scan_factor;
26012608

2609+
/* Cap the maximum IO capacity that we are going to use by
2610+
max_io_capacity. Limit the value to avoid too quick increase */
2611+
const ulint sum_pages_max = srv_max_io_capacity * 2;
2612+
2613+
/* Limit individual BP scan based on overall capacity. */
2614+
const ulint pages_for_lsn_max =
2615+
(sum_pages_max / srv_buf_pool_instances) *
2616+
buf_flush_lsn_scan_factor * 2;
2617+
26022618
for (ulint i = 0; i < srv_buf_pool_instances; i++) {
26032619
buf_pool_t* buf_pool = buf_pool_from_array(i);
26042620
ulint pages_for_lsn = 0;
@@ -2611,6 +2627,9 @@ page_cleaner_flush_pages_recommendation(
26112627
break;
26122628
}
26132629
++pages_for_lsn;
2630+
if (pages_for_lsn >= pages_for_lsn_max) {
2631+
break;
2632+
}
26142633
}
26152634
buf_flush_list_mutex_exit(buf_pool);
26162635

@@ -2632,7 +2651,7 @@ page_cleaner_flush_pages_recommendation(
26322651
/* Cap the maximum IO capacity that we are going to use by
26332652
max_io_capacity. Limit the value to avoid too quick increase */
26342653
ulint pages_for_lsn =
2635-
std::min<ulint>(sum_pages_for_lsn, srv_max_io_capacity * 2);
2654+
std::min<ulint>(sum_pages_for_lsn, sum_pages_max);
26362655

26372656
n_pages = (PCT_IO(pct_total) + avg_page_rate + pages_for_lsn) / 3;
26382657

storage/innobase/include/buf0buf.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1901,6 +1901,13 @@ class HazardPointer {
19011901
@param bpage buffer block to be compared */
19021902
virtual void adjust(const buf_page_t*) = 0;
19031903

1904+
/** Adjust the value of hp for moving. This happens
1905+
when some other thread working on the same list
1906+
attempts to relocate the hp of the page.
1907+
@param bpage buffer block to be compared
1908+
@param dpage buffer block to be moved to */
1909+
void move(const buf_page_t *bpage, buf_page_t *dpage);
1910+
19041911
protected:
19051912
/** Disable copying */
19061913
HazardPointer(const HazardPointer&);
@@ -2129,6 +2136,8 @@ struct buf_pool_t{
21292136
used during scan of flush_list
21302137
while doing flush list batch.
21312138
Protected by flush_list_mutex */
2139+
FlushHp oldest_hp;/*!< entry pointer to scan the oldest
2140+
page except for system temporary */
21322141
UT_LIST_BASE_NODE_T(buf_page_t) flush_list;
21332142
/*!< base node of the modified block
21342143
list */

0 commit comments

Comments
 (0)