1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-15 19:22:41 +03:00
Files
mariadb/mysql-test/suite/innodb/t/undo_truncate.test
Marko Mäkelä 5567a8c936 MDEV-17138 Reduce redo log volume for undo tablespace initialization
Implement a 10.4 redo log format, which extends the 10.3 format
by introducing the MLOG_MEMSET record.

MLOG_MEMSET: A new redo log record type for filling an area with a byte.

mlog_memset(): Write the MLOG_MEMSET record.

mlog_parse_nbytes(): Handle MLOG_MEMSET as well.

trx_rseg_header_create(): Reduce the redo log volume by making use of
mlog_memset() and the zero-initialization that happens inside page
allocation.

fil_addr_null: Remove.

flst_init(): Create a variant that takes a zero-initialized
buf_block_t* as a parameter, and only writes the FIL_NULL using
mlog_memset().

flst_zero_addr(): A variant of flst_write_addr() that writes
a null address using mlog_memset() for the FIL_NULL.

The following fixes are replacing some use of MLOG_WRITE_STRING
with the more compact MLOG_MEMSET record, or eliminating
redundant redo log writes:

btr_store_big_rec_extern_fields(): Invoke mlog_memset() for
zero-initializing the tail of the ROW_FORMAT=COMPRESSED BLOB page.

trx_sysf_create(), trx_rseg_format_upgrade(): Invoke mlog_memset()
for zero-initializing the page trailer.

fsp_header_init(), trx_rseg_header_create():
Remove redundant zero-initializations.
2018-09-11 21:32:36 +03:00

123 lines
3.4 KiB
Plaintext

--source include/have_innodb.inc
--source include/innodb_page_size.inc
--source include/have_undo_tablespaces.inc
SET @save_undo_logs = @@GLOBAL.innodb_undo_logs;
SET @save_frequency = @@GLOBAL.innodb_purge_rseg_truncate_frequency;
SET @save_truncate = @@GLOBAL.innodb_undo_log_truncate;
SET GLOBAL innodb_undo_log_truncate = 0;
SET GLOBAL innodb_undo_logs = 4;
SET GLOBAL innodb_purge_rseg_truncate_frequency = 1;
SET @trunc_start=
(SELECT variable_value FROM information_schema.global_status
WHERE variable_name = 'innodb_undo_truncations');
#-----------------------------------------------------------------------------
#
# Perform DML action using multiple clients and multiple undo tablespace.
#
#
create table t1(keyc int primary key, c char(100)) engine = innodb;
create table t2(keyc int primary key, c char(100)) engine = innodb;
#
delimiter |;
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 |
delimiter ;|
#
delimiter |;
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 |
delimiter ;|
#
#
let DATADIR = `select @@datadir`;
connect (con1,localhost,root,,);
begin;
send call populate_t1();
connect (con2,localhost,root,,);
begin;
send call populate_t2();
connection con1; reap; send update t1 set c = 'mysql';
connection con2; reap; send update t2 set c = 'mysql';
connection con1; reap; send update t1 set c = 'oracle';
connection con2; reap; send update t2 set c = 'oracle';
connection con1; reap; send delete from t1;
connection con2; reap; delete from t2;
connection con1; reap;
let CHECKFILE = $MYSQL_TMP_DIR/check.txt;
perl;
($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size1)
= stat("$ENV{DATADIR}/undo001");
($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size2)
= stat("$ENV{DATADIR}/undo002");
open(OUT, ">$ENV{CHECKFILE}") || die;
print OUT "let \$size1='$size1,$size2';\n";
close(OUT);
EOF
SET GLOBAL innodb_undo_log_truncate = 1;
commit; disconnect con1;
connection con2; commit; disconnect con2;
connection default;
drop table t1, t2;
drop PROCEDURE populate_t1;
drop PROCEDURE populate_t2;
--source include/wait_all_purged.inc
# Truncation will normally not occur with innodb_page_size=64k,
# and occasionally not with innodb_page_size=32k,
# because the undo log will not grow enough.
if (`select @@innodb_page_size IN (4096,8192,16384)`)
{
let $wait_condition = (SELECT variable_value!=@trunc_start
FROM information_schema.global_status
WHERE variable_name = 'innodb_undo_truncations');
source include/wait_condition.inc;
}
--source $CHECKFILE
perl;
($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size1)
= stat("$ENV{DATADIR}/undo001");
($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size2)
= stat("$ENV{DATADIR}/undo002");
open(OUT, ">$ENV{CHECKFILE}") || die;
print OUT "let \$size2='$size1,$size2';\n";
close(OUT);
EOF
--source $CHECKFILE
--remove_file $CHECKFILE
if ($size1 == $size2)
{
# This fails for innodb_page_size=64k, occasionally also for 32k.
if (`select @@innodb_page_size IN (4096,8192,16384)`)
{
echo Truncation did not happen: $size1;
}
}
SET GLOBAL innodb_undo_logs = @save_undo_logs;
SET GLOBAL innodb_purge_rseg_truncate_frequency = @save_frequency;
SET GLOBAL innodb_undo_log_truncate = @save_truncate;