Skip to content
This repository was archived by the owner on Oct 5, 2021. It is now read-only.

Commit e4a1c91

Browse files
author
Aditya A
committed
Bug #21133329 HANGING "SYSTEM LOCK" WHEN EXECUTING "FLUSH TABLE ... FOR EXPORT"
PROBLEM -------- 1. ibuf_contarct_in background() function is trying to merge all pages related to a certain table (which contains no record). while in background heavy DML operations are happening. When contracting the pages in ibuf_merge_space() we call ibuf_get_merge_pages() to get the pages to be merged.This function call returns the volume ( in bytes) of pages to be merged. In our case , the returned volume is zero since there are no pages to be merged ,but we increment the volume returned by 1 . 2. This volume is returned to ibuf_contract_in_background() which assumes that some pages have been merged since the volume returned is greater than zero and waits it reach the required number of pages to be merged and gets stuck in the loop. FIX 1. The reason we increment the volume by 1 ,is becasue for delete marked records the volume returned is zero and the logic in ibuf_merge_space() is such that acutual merging happens only if volume returned is non zero. 2. To fix this we have changed the logic to merge only if the number of pages returned is greater than zero.We return zero to the ibuf_contarct_in background() when there are no pages to merge which enables it break the loop. [ Reviewed by Jimmy #rb12209 ]
1 parent c487ce8 commit e4a1c91

File tree

3 files changed

+96
-7
lines changed

3 files changed

+96
-7
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
#
2+
#Bug #21133329 HANGING "SYSTEM LOCK" WHEN EXECUTING "FLUSH TABLE ... FOR EXPORT"
3+
#
4+
CREATE TABLE t1 (
5+
c1 BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
6+
c2 BIGINT,
7+
c3 VARCHAR(2048),
8+
c4 VARCHAR(2048),
9+
INDEX idx1(c2),
10+
INDEX idx2(c3(512)),
11+
INDEX idx3(c4(512))) Engine=InnoDB;
12+
CREATE TABLE t2 ( f1 int PRIMARY KEY) engine=innodb;
13+
SET GLOBAL INNODB_PURGE_STOP_NOW=ON;
14+
SET GLOBAL innodb_disable_background_merge=ON;
15+
SET GLOBAL innodb_stats_persistent=OFF;
16+
show variables like '%innodb_stats_persistent%';
17+
Variable_name Value
18+
innodb_stats_persistent OFF
19+
innodb_stats_persistent_sample_pages 20
20+
INSERT INTO t1(c2, c3, c4) VALUES
21+
(1, REPEAT('a', 2048), REPEAT('a', 2048)),
22+
(2, REPEAT('b', 2048), REPEAT('b', 2048)),
23+
(3, REPEAT('c', 2048), REPEAT('c', 2048)),
24+
(4, REPEAT('d', 2048), REPEAT('d', 2048));
25+
INSERT INTO t1(c2, c3, c4) SELECT c2, c3, c4 FROM t1;
26+
INSERT INTO t1(c2, c3, c4) SELECT c2, c3, c4 FROM t1;
27+
INSERT INTO t1(c2, c3, c4) SELECT c2, c3, c4 FROM t1;
28+
INSERT INTO t1(c2, c3, c4) SELECT c2, c3, c4 FROM t1;
29+
INSERT INTO t1(c2, c3, c4) SELECT c2, c3, c4 FROM t1;
30+
INSERT INTO t1(c2, c3, c4) SELECT c2, c3, c4 FROM t1;
31+
FLUSH TABLES t2 FOR EXPORT;
32+
UNLOCK TABLES;
33+
SET GLOBAL innodb_disable_background_merge=OFF;
34+
SET GLOBAL INNODB_PURGE_RUN_NOW=ON;
35+
SET GLOBAL innodb_stats_persistent=ON;
36+
DROP TABLE t1,t2;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
2+
--echo #
3+
--echo #Bug #21133329 HANGING "SYSTEM LOCK" WHEN EXECUTING "FLUSH TABLE ... FOR EXPORT"
4+
--echo #
5+
6+
--source include/not_embedded.inc
7+
--source include/have_debug.inc
8+
--source include/have_innodb.inc
9+
10+
CREATE TABLE t1 (
11+
c1 BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
12+
c2 BIGINT,
13+
c3 VARCHAR(2048),
14+
c4 VARCHAR(2048),
15+
INDEX idx1(c2),
16+
INDEX idx2(c3(512)),
17+
INDEX idx3(c4(512))) Engine=InnoDB;
18+
19+
CREATE TABLE t2 ( f1 int PRIMARY KEY) engine=innodb;
20+
21+
# Stop purge so that it doesn't remove the delete marked entries.
22+
SET GLOBAL INNODB_PURGE_STOP_NOW=ON;
23+
24+
# Disable change buffer merge from the master thread, additionally
25+
# enable aggressive flushing so that more changes are buffered.
26+
SET GLOBAL innodb_disable_background_merge=ON;
27+
SET GLOBAL innodb_stats_persistent=OFF;
28+
show variables like '%innodb_stats_persistent%';
29+
30+
INSERT INTO t1(c2, c3, c4) VALUES
31+
(1, REPEAT('a', 2048), REPEAT('a', 2048)),
32+
(2, REPEAT('b', 2048), REPEAT('b', 2048)),
33+
(3, REPEAT('c', 2048), REPEAT('c', 2048)),
34+
(4, REPEAT('d', 2048), REPEAT('d', 2048));
35+
36+
INSERT INTO t1(c2, c3, c4) SELECT c2, c3, c4 FROM t1;
37+
INSERT INTO t1(c2, c3, c4) SELECT c2, c3, c4 FROM t1;
38+
INSERT INTO t1(c2, c3, c4) SELECT c2, c3, c4 FROM t1;
39+
INSERT INTO t1(c2, c3, c4) SELECT c2, c3, c4 FROM t1;
40+
INSERT INTO t1(c2, c3, c4) SELECT c2, c3, c4 FROM t1;
41+
INSERT INTO t1(c2, c3, c4) SELECT c2, c3, c4 FROM t1;
42+
43+
FLUSH TABLES t2 FOR EXPORT;
44+
UNLOCK TABLES;
45+
46+
SET GLOBAL innodb_disable_background_merge=OFF;
47+
SET GLOBAL INNODB_PURGE_RUN_NOW=ON;
48+
SET GLOBAL innodb_stats_persistent=ON;
49+
50+
DROP TABLE t1,t2;

storage/innobase/ibuf/ibuf0ibuf.cc

+10-7
Original file line numberDiff line numberDiff line change
@@ -2562,7 +2562,7 @@ ibuf_get_merge_pages(
25622562
Contracts insert buffer trees by reading pages to the buffer pool.
25632563
@return a lower limit for the combined size in bytes of entries which
25642564
will be merged from ibuf trees to the pages read, 0 if ibuf is
2565-
empty */
2565+
empty or there are no pages to merge*/
25662566
static
25672567
ulint
25682568
ibuf_merge_pages(
@@ -2617,10 +2617,15 @@ ibuf_merge_pages(
26172617
ibuf_mtr_commit(&mtr);
26182618
btr_pcur_close(&pcur);
26192619

2620+
if (*n_pages == 0) {
2621+
ut_ad(sum_sizes == 0);
2622+
return(0);
2623+
}
2624+
26202625
buf_read_ibuf_merge_pages(
26212626
sync, space_ids, space_versions, page_nos, *n_pages);
26222627

2623-
return(sum_sizes + 1);
2628+
return(sum_sizes);
26242629
}
26252630

26262631
/*********************************************************************//**
@@ -2646,7 +2651,8 @@ ibuf_get_table(
26462651
Contracts insert buffer trees by reading pages to the buffer pool.
26472652
@return a lower limit for the combined size in bytes of entries which
26482653
will be merged from ibuf trees to the pages read, 0 if ibuf is
2649-
empty */
2654+
empty or if there are no pages to merge */
2655+
26502656
static
26512657
ulint
26522658
ibuf_merge_space(
@@ -2693,16 +2699,13 @@ ibuf_merge_space(
26932699
&pages[0], &spaces[0], &versions[0], n_pages,
26942700
&mtr);
26952701

2696-
++sum_sizes;
26972702
}
26982703

26992704
ibuf_mtr_commit(&mtr);
27002705

27012706
btr_pcur_close(&pcur);
27022707

2703-
if (sum_sizes > 0) {
2704-
2705-
ut_a(*n_pages > 0 || sum_sizes == 1);
2708+
if (*n_pages > 0) {
27062709

27072710
#ifdef UNIV_DEBUG
27082711
ut_ad(*n_pages <= UT_ARR_SIZE(pages));

0 commit comments

Comments
 (0)