diff options
author | Thirunarayanan Balathandayuthapani <thiru@mariadb.com> | 2022-08-16 17:34:38 +0530 |
---|---|---|
committer | Thirunarayanan Balathandayuthapani <thiru@mariadb.com> | 2022-08-17 11:08:49 +0530 |
commit | 32167225c728c19ca478bce0529d549a8d056f87 (patch) | |
tree | 00d79e501e7d0df37c7c1b134f32d40d47e462d3 | |
parent | c2080060801342f46849423adf71515ae7a33e04 (diff) | |
download | mariadb-git-32167225c728c19ca478bce0529d549a8d056f87.tar.gz |
MDEV-13013 InnoDB unnecessarily extends data files
- While creating a new InnoDB segment, allocates the extent
before allocating the inode or page allocation even though
the pages are present in fragment segment. This patch does
reserve the extent when InnoDB ran out of fragment pages
in the tablespace.
-rw-r--r-- | mysql-test/suite/innodb/r/check_ibd_filesize,32k.rdiff | 12 | ||||
-rw-r--r-- | mysql-test/suite/innodb/r/check_ibd_filesize,4k.rdiff | 12 | ||||
-rw-r--r-- | mysql-test/suite/innodb/r/check_ibd_filesize,64k.rdiff | 12 | ||||
-rw-r--r-- | mysql-test/suite/innodb/r/check_ibd_filesize,8k.rdiff | 12 | ||||
-rw-r--r-- | mysql-test/suite/innodb/r/check_ibd_filesize.result | 4 | ||||
-rw-r--r-- | mysql-test/suite/innodb/t/temporary_table.test | 1 | ||||
-rw-r--r-- | mysql-test/suite/mariabackup/log_page_corruption.result | 24 | ||||
-rw-r--r-- | storage/innobase/fsp/fsp0fsp.cc | 38 |
8 files changed, 66 insertions, 49 deletions
diff --git a/mysql-test/suite/innodb/r/check_ibd_filesize,32k.rdiff b/mysql-test/suite/innodb/r/check_ibd_filesize,32k.rdiff index 6cf0fdf4159..44446602b9f 100644 --- a/mysql-test/suite/innodb/r/check_ibd_filesize,32k.rdiff +++ b/mysql-test/suite/innodb/r/check_ibd_filesize,32k.rdiff @@ -1,18 +1,18 @@ ---- check_ibd_filesize.result -+++ check_ibd_filesize.result,32k +--- mysql-test/suite/innodb/r/check_ibd_filesize.result 2022-08-16 17:28:06.462350465 +0530 ++++ mysql-test/suite/innodb/r/check_ibd_filesize.reject 2022-08-16 17:29:25.129637040 +0530 @@ -3,18 +3,12 @@ # SPACE IN 5.7 THAN IN 5.6 # CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB; --# bytes: 98304 -+# bytes: 196608 +-# bytes: 65536 ++# bytes: 131072 INSERT INTO t1 SELECT * FROM seq_1_to_25000; -# bytes: 9437184 +# bytes: 786432 DROP TABLE t1; CREATE TABLE t1 (a INT PRIMARY KEY, b BLOB) ENGINE=InnoDB; --# bytes: 98304 -+# bytes: 196608 +-# bytes: 65536 ++# bytes: 131072 INSERT INTO t1 SELECT seq,REPEAT('a',30000) FROM seq_1_to_20; -# bytes: 4194304 -DROP TABLE t1; diff --git a/mysql-test/suite/innodb/r/check_ibd_filesize,4k.rdiff b/mysql-test/suite/innodb/r/check_ibd_filesize,4k.rdiff index 52cd6832755..ef55ad971fe 100644 --- a/mysql-test/suite/innodb/r/check_ibd_filesize,4k.rdiff +++ b/mysql-test/suite/innodb/r/check_ibd_filesize,4k.rdiff @@ -1,17 +1,17 @@ ---- check_ibd_filesize.result -+++ check_ibd_filesize.result,4k +--- mysql-test/suite/innodb/r/check_ibd_filesize.result 2022-08-16 17:28:06.462350465 +0530 ++++ mysql-test/suite/innodb/r/check_ibd_filesize.reject 2022-08-16 17:31:39.288769153 +0530 @@ -3,18 +3,18 @@ # SPACE IN 5.7 THAN IN 5.6 # CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB; --# bytes: 98304 -+# bytes: 24576 +-# bytes: 65536 ++# bytes: 16384 INSERT INTO t1 SELECT * FROM seq_1_to_25000; # bytes: 9437184 DROP TABLE t1; CREATE TABLE t1 (a INT PRIMARY KEY, b BLOB) ENGINE=InnoDB; --# bytes: 98304 -+# bytes: 24576 +-# bytes: 65536 ++# bytes: 16384 INSERT INTO t1 SELECT seq,REPEAT('a',30000) FROM seq_1_to_20; # bytes: 4194304 DROP TABLE t1; diff --git a/mysql-test/suite/innodb/r/check_ibd_filesize,64k.rdiff b/mysql-test/suite/innodb/r/check_ibd_filesize,64k.rdiff index 23d9fbe608f..bcdcea31160 100644 --- a/mysql-test/suite/innodb/r/check_ibd_filesize,64k.rdiff +++ b/mysql-test/suite/innodb/r/check_ibd_filesize,64k.rdiff @@ -1,18 +1,18 @@ ---- check_ibd_filesize.result -+++ check_ibd_filesize.result,64k +--- mysql-test/suite/innodb/r/check_ibd_filesize.result 2022-08-16 17:28:06.462350465 +0530 ++++ mysql-test/suite/innodb/r/check_ibd_filesize.reject 2022-08-16 17:30:28.957174270 +0530 @@ -3,18 +3,12 @@ # SPACE IN 5.7 THAN IN 5.6 # CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB; --# bytes: 98304 -+# bytes: 393216 +-# bytes: 65536 ++# bytes: 262144 INSERT INTO t1 SELECT * FROM seq_1_to_25000; -# bytes: 9437184 +# bytes: 983040 DROP TABLE t1; CREATE TABLE t1 (a INT PRIMARY KEY, b BLOB) ENGINE=InnoDB; --# bytes: 98304 -+# bytes: 393216 +-# bytes: 65536 ++# bytes: 262144 INSERT INTO t1 SELECT seq,REPEAT('a',30000) FROM seq_1_to_20; -# bytes: 4194304 -DROP TABLE t1; diff --git a/mysql-test/suite/innodb/r/check_ibd_filesize,8k.rdiff b/mysql-test/suite/innodb/r/check_ibd_filesize,8k.rdiff index 17936a3def9..7b699ef4cea 100644 --- a/mysql-test/suite/innodb/r/check_ibd_filesize,8k.rdiff +++ b/mysql-test/suite/innodb/r/check_ibd_filesize,8k.rdiff @@ -1,17 +1,17 @@ ---- check_ibd_filesize.result -+++ check_ibd_filesize.result,8k +--- mysql-test/suite/innodb/r/check_ibd_filesize.result 2022-08-16 17:28:06.462350465 +0530 ++++ mysql-test/suite/innodb/r/check_ibd_filesize.reject 2022-08-16 17:31:03.516962339 +0530 @@ -3,18 +3,18 @@ # SPACE IN 5.7 THAN IN 5.6 # CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB; --# bytes: 98304 -+# bytes: 49152 +-# bytes: 65536 ++# bytes: 32768 INSERT INTO t1 SELECT * FROM seq_1_to_25000; # bytes: 9437184 DROP TABLE t1; CREATE TABLE t1 (a INT PRIMARY KEY, b BLOB) ENGINE=InnoDB; --# bytes: 98304 -+# bytes: 49152 +-# bytes: 65536 ++# bytes: 32768 INSERT INTO t1 SELECT seq,REPEAT('a',30000) FROM seq_1_to_20; # bytes: 4194304 DROP TABLE t1; diff --git a/mysql-test/suite/innodb/r/check_ibd_filesize.result b/mysql-test/suite/innodb/r/check_ibd_filesize.result index a6f5fbd9387..0d224d6ac5f 100644 --- a/mysql-test/suite/innodb/r/check_ibd_filesize.result +++ b/mysql-test/suite/innodb/r/check_ibd_filesize.result @@ -3,12 +3,12 @@ # SPACE IN 5.7 THAN IN 5.6 # CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB; -# bytes: 98304 +# bytes: 65536 INSERT INTO t1 SELECT * FROM seq_1_to_25000; # bytes: 9437184 DROP TABLE t1; CREATE TABLE t1 (a INT PRIMARY KEY, b BLOB) ENGINE=InnoDB; -# bytes: 98304 +# bytes: 65536 INSERT INTO t1 SELECT seq,REPEAT('a',30000) FROM seq_1_to_20; # bytes: 4194304 DROP TABLE t1; diff --git a/mysql-test/suite/innodb/t/temporary_table.test b/mysql-test/suite/innodb/t/temporary_table.test index 5f64eb7d22b..cc290b03c34 100644 --- a/mysql-test/suite/innodb/t/temporary_table.test +++ b/mysql-test/suite/innodb/t/temporary_table.test @@ -5,6 +5,7 @@ # --source include/have_innodb.inc +--source include/innodb_page_size.inc # Embedded server does not restart of server --source include/not_embedded.inc --source include/no_valgrind_without_big.inc diff --git a/mysql-test/suite/mariabackup/log_page_corruption.result b/mysql-test/suite/mariabackup/log_page_corruption.result index 01ad4422c6a..b1dc6c8fd5f 100644 --- a/mysql-test/suite/mariabackup/log_page_corruption.result +++ b/mysql-test/suite/mariabackup/log_page_corruption.result @@ -30,13 +30,13 @@ FOUND 1 /Database page corruption detected.*/ in backup.log FOUND 1 /completed OK!/ in backup.log --- "innodb_corrupted_pages" file content: --- test/t1_corrupted -6 8 9 +4 6 7 test/t2_corrupted -7 8 10 +5 6 8 test/t4_corrupted_new 1 test/t5_corrupted_to_rename_renamed -6 +4 test/t7_corrupted_to_alter 3 ------ @@ -46,19 +46,19 @@ INSERT INTO t3_inc VALUES (3), (4), (5), (6), (7), (8), (9); # Backup must not fail, but "innodb_corrupted_pages" file must be created due to --log-innodb-page-corruption option --- "innodb_corrupted_pages" file content: --- test/t1_corrupted -6 8 9 +4 6 7 test/t1_inc_corrupted -6 8 9 +4 6 7 test/t2_corrupted -7 8 10 +5 6 8 test/t2_inc_corrupted -7 8 10 +5 6 8 test/t4_inc_corrupted_new 1 test/t5_corrupted_to_rename_renamed -6 +4 test/t5_inc_corrupted_to_rename_renamed -6 +4 test/t7_inc_corrupted_to_alter 3 ------ @@ -82,15 +82,15 @@ DROP TABLE t7_inc_corrupted_to_alter; # Full backup with --log-innodb-page-corruption --- "innodb_corrupted_pages" file content: --- test/t3 -6 8 +4 6 ------ # Extend some tablespace and corrupt extended pages for incremental backup # Incremental backup --log-innodb-page-corruption --- "innodb_corrupted_pages" file content: --- test/t3 -6 8 +4 6 test/t3_inc -6 8 +4 6 ------ # Full backup prepare # "innodb_corrupted_pages" file must not exist after successful prepare diff --git a/storage/innobase/fsp/fsp0fsp.cc b/storage/innobase/fsp/fsp0fsp.cc index ab143a16417..ba50483cee4 100644 --- a/storage/innobase/fsp/fsp0fsp.cc +++ b/storage/innobase/fsp/fsp0fsp.cc @@ -1886,6 +1886,7 @@ fseg_create(fil_space_t *space, ulint byte_offset, mtr_t *mtr, fseg_header_t* header = 0; /* remove warning */ ulint n_reserved; ulint i; + bool reserved_extent = false; DBUG_ENTER("fseg_create"); @@ -1909,17 +1910,34 @@ fseg_create(fil_space_t *space, ulint byte_offset, mtr_t *mtr, fil_block_check_type(*block, type, mtr); } - if (!has_done_reservation - && !fsp_reserve_free_extents(&n_reserved, space, 2, - FSP_NORMAL, mtr)) { - DBUG_RETURN(NULL); - } - space_header = fsp_get_space_header(space, page_size, mtr); +inode_alloc: inode = fsp_alloc_seg_inode(space, space_header, mtr); if (inode == NULL) { +reserve_extent: + if (!has_done_reservation && !reserved_extent) { + + if (!fsp_reserve_free_extents( + &n_reserved, space, 2, + FSP_NORMAL, mtr)) { + DBUG_RETURN(NULL); + } + + /* Extents reserved successfully. So + try allocating the page or inode */ + reserved_extent = true; + if (inode) { + goto page_alloc; + } + + goto inode_alloc; + } + + if (inode) { + fsp_free_seg_inode(space, page_size, inode, mtr); + } goto funct_exit; } @@ -1944,6 +1962,7 @@ fseg_create(fil_space_t *space, ulint byte_offset, mtr_t *mtr, } if (!block) { +page_alloc: block = fseg_alloc_free_page_low(space, page_size, inode, 0, FSP_UP, mtr, mtr @@ -1957,10 +1976,7 @@ fseg_create(fil_space_t *space, ulint byte_offset, mtr_t *mtr, ut_ad(!has_done_reservation || block != NULL); if (block == NULL) { - - fsp_free_seg_inode(space, page_size, inode, mtr); - - goto funct_exit; + goto reserve_extent; } ut_ad(rw_lock_get_x_lock_count(&block->lock) == 1); @@ -1980,7 +1996,7 @@ fseg_create(fil_space_t *space, ulint byte_offset, mtr_t *mtr, mlog_write_ulint(header + FSEG_HDR_SPACE, space->id, MLOG_4BYTES, mtr); funct_exit: - if (!has_done_reservation) { + if (!has_done_reservation && reserved_extent) { space->release_free_extents(n_reserved); } |