1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-30 16:24:05 +03:00

MDEV-26450: Corruption due to innodb_undo_log_truncate

At least since commit 055a3334ad
(MDEV-13564) the undo log truncation in InnoDB did not work correctly.

The main issue is that during the execution of
trx_purge_truncate_history() some pages of the newly truncated
undo tablespace could be discarded.

fsp_try_extend_data_file(): Apply the peculiar rounding of
fil_space_t::size_in_header only to the system tablespace,
whose size can be expressed in megabytes in a configuration parameter.
Other files may freely grow by a number of pages.

fseg_alloc_free_page_low(): Do allow the extension of undo tablespaces,
and mention the file name in the error message.

mtr_t::commit_shrink(): Implement crash-safe shrinking of a tablespace
file. First, durably write the log, then shrink the file, and finally
release the page latches of the rebuilt tablespace. Refactored from
trx_purge_truncate_history().

log_write_and_flush_prepare(), log_write_and_flush(): New functions
to durably write log during mtr_t::commit_shrink().
This commit is contained in:
Marko Mäkelä
2021-09-22 14:15:00 +03:00
parent 21d19ed45b
commit 1cb218c37c
9 changed files with 219 additions and 123 deletions

View File

@ -10,28 +10,12 @@ SET @trunc_start=
WHERE variable_name = 'innodb_undo_truncations');
create table t1(keyc int primary key, c char(100)) engine = innodb;
create table t2(keyc int primary key, c char(100)) engine = innodb;
CREATE PROCEDURE populate_t1()
BEGIN
DECLARE i INT DEFAULT 1;
while (i <= 20000) DO
insert into t1 values (i, 'a');
SET i = i + 1;
END WHILE;
END |
CREATE PROCEDURE populate_t2()
BEGIN
DECLARE i INT DEFAULT 1;
while (i <= 20000) DO
insert into t2 values (i, 'a');
SET i = i + 1;
END WHILE;
END |
connect con1,localhost,root,,;
begin;
call populate_t1();
insert into t1 select seq,'a' from seq_1_to_20000;
connect con2,localhost,root,,;
begin;
call populate_t2();
insert into t2 select seq,'a' from seq_1_to_20000;
connection con1;
update t1 set c = 'mysql';
connection con2;
@ -53,8 +37,6 @@ commit;
disconnect con2;
connection default;
drop table t1, t2;
drop PROCEDURE populate_t1;
drop PROCEDURE populate_t2;
InnoDB 0 transactions not purged
SET GLOBAL innodb_undo_logs = @save_undo_logs;
SET GLOBAL innodb_purge_rseg_truncate_frequency = @save_frequency;