Skip to content

Commit 04531c9

Browse files
author
Shaohua Wang
committed
BUG#22385442 - INNODB: DIFFICULT TO FIND FREE BLOCKS IN THE BUFFER POOL
Problem: We keep pinning pages in dict_stats_analyze_index_below_cur(), but doesn't release these pages. When we have a relative small buffer pool size, and big innodb_stats_persistent_sample_pages, there will be no free pages for use. Solution: Use a separate mtr in dict_stats_analyze_index_below_cur(), and commit mtr before return. Reviewed-by: Jimmy Yang <[email protected]> RB: 11362
1 parent 782920b commit 04531c9

File tree

3 files changed

+78
-8
lines changed

3 files changed

+78
-8
lines changed
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
CREATE PROCEDURE populate_t1()
2+
BEGIN
3+
DECLARE i int DEFAULT 1;
4+
START TRANSACTION;
5+
WHILE (i <= 1000000) DO
6+
INSERT INTO t1 VALUES (i, i, CONCAT('a', i));
7+
SET i = i + 1;
8+
END WHILE;
9+
COMMIT;
10+
END|
11+
CREATE TABLE t1(
12+
class INT,
13+
id INT,
14+
title VARCHAR(100)
15+
) ENGINE=InnoDB;
16+
SELECT COUNT(*) FROM t1;
17+
COUNT(*)
18+
1000000
19+
SET GLOBAL innodb_stats_persistent_sample_pages=2000;
20+
ANALYZE TABLE t1;
21+
Table Op Msg_type Msg_text
22+
test.t1 analyze status OK
23+
DROP TABLE t1;
24+
DROP PROCEDURE populate_t1;
25+
SET GLOBAL innodb_stats_persistent_sample_pages=default;
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
#
2+
# BUG#22385442 - INNODB: DIFFICULT TO FIND FREE BLOCKS IN THE BUFFER POOL
3+
#
4+
5+
--source include/have_innodb.inc
6+
--source include/big_test.inc
7+
8+
DELIMITER |;
9+
CREATE PROCEDURE populate_t1()
10+
BEGIN
11+
DECLARE i int DEFAULT 1;
12+
13+
START TRANSACTION;
14+
WHILE (i <= 1000000) DO
15+
INSERT INTO t1 VALUES (i, i, CONCAT('a', i));
16+
SET i = i + 1;
17+
END WHILE;
18+
COMMIT;
19+
END|
20+
DELIMITER ;|
21+
22+
CREATE TABLE t1(
23+
class INT,
24+
id INT,
25+
title VARCHAR(100)
26+
) ENGINE=InnoDB;
27+
28+
-- disable_query_log
29+
CALL populate_t1();
30+
-- enable_query_log
31+
32+
SELECT COUNT(*) FROM t1;
33+
34+
SET GLOBAL innodb_stats_persistent_sample_pages=2000;
35+
36+
ANALYZE TABLE t1;
37+
38+
DROP TABLE t1;
39+
40+
DROP PROCEDURE populate_t1;
41+
42+
SET GLOBAL innodb_stats_persistent_sample_pages=default;

storage/innobase/dict/dict0stats.cc

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*****************************************************************************
22
3-
Copyright (c) 2009, 2014, Oracle and/or its affiliates. All Rights Reserved.
3+
Copyright (c) 2009, 2015, Oracle and/or its affiliates. All Rights Reserved.
44
55
This program is free software; you can redistribute it and/or modify it under
66
the terms of the GNU General Public License as published by the Free Software
@@ -1434,16 +1434,14 @@ on the leaf page.
14341434
when comparing records
14351435
@param[out] n_diff number of distinct records
14361436
@param[out] n_external_pages number of external pages
1437-
@param[in,out] mtr mini-transaction
14381437
@return number of distinct records on the leaf page */
14391438
static
14401439
void
14411440
dict_stats_analyze_index_below_cur(
14421441
const btr_cur_t* cur,
14431442
ulint n_prefix,
14441443
ib_uint64_t* n_diff,
1445-
ib_uint64_t* n_external_pages,
1446-
mtr_t* mtr)
1444+
ib_uint64_t* n_external_pages)
14471445
{
14481446
dict_index_t* index;
14491447
ulint space;
@@ -1457,6 +1455,7 @@ dict_stats_analyze_index_below_cur(
14571455
ulint* offsets2;
14581456
ulint* offsets_rec;
14591457
ulint size;
1458+
mtr_t mtr;
14601459

14611460
index = btr_cur_get_index(cur);
14621461

@@ -1495,12 +1494,14 @@ dict_stats_analyze_index_below_cur(
14951494
function without analyzing any leaf pages */
14961495
*n_external_pages = 0;
14971496

1497+
mtr_start(&mtr);
1498+
14981499
/* descend to the leaf level on the B-tree */
14991500
for (;;) {
15001501

15011502
block = buf_page_get_gen(space, zip_size, page_no, RW_S_LATCH,
15021503
NULL /* no guessed block */,
1503-
BUF_GET, __FILE__, __LINE__, mtr);
1504+
BUF_GET, __FILE__, __LINE__, &mtr);
15041505

15051506
page = buf_block_get_frame(block);
15061507

@@ -1522,6 +1523,8 @@ dict_stats_analyze_index_below_cur(
15221523
ut_a(*n_diff > 0);
15231524

15241525
if (*n_diff == 1) {
1526+
mtr_commit(&mtr);
1527+
15251528
/* page has all keys equal and the end of the page
15261529
was reached by dict_stats_scan_page(), no need to
15271530
descend to the leaf level */
@@ -1546,7 +1549,7 @@ dict_stats_analyze_index_below_cur(
15461549
}
15471550

15481551
/* make sure we got a leaf page as a result from the above loop */
1549-
ut_ad(btr_page_get_level(page, mtr) == 0);
1552+
ut_ad(btr_page_get_level(page, &mtr) == 0);
15501553

15511554
/* scan the leaf page and find the number of distinct keys,
15521555
when looking only at the first n_prefix columns; also estimate
@@ -1563,6 +1566,7 @@ dict_stats_analyze_index_below_cur(
15631566
__func__, page_no, n_diff);
15641567
#endif
15651568

1569+
mtr_commit(&mtr);
15661570
mem_heap_free(heap);
15671571
}
15681572

@@ -1772,8 +1776,7 @@ dict_stats_analyze_index_for_n_prefix(
17721776
dict_stats_analyze_index_below_cur(btr_pcur_get_btr_cur(&pcur),
17731777
n_prefix,
17741778
&n_diff_on_leaf_page,
1775-
&n_external_pages,
1776-
mtr);
1779+
&n_external_pages);
17771780

17781781
/* We adjust n_diff_on_leaf_page here to avoid counting
17791782
one record twice - once as the last on some page and once

0 commit comments

Comments
 (0)