mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
MDEV-8139 Fix Scrubbing
fil_space_t::freed_ranges: Store ranges of freed page numbers. fil_space_t::last_freed_lsn: Store the most recent LSN of freeing a page. fil_space_t::freed_mutex: Protects freed_ranges, last_freed_lsn. fil_space_create(): Initialize the freed_range mutex. fil_space_free_low(): Frees the freed_range mutex. range_set: Ranges of page numbers. buf_page_create(): Removes the page from freed_ranges when page is being reused. btr_free_root(): Remove the PAGE_INDEX_ID invalidation. Because btr_free_root() and dict_drop_index_tree() are executed in the same atomic mini-transaction, there is no need to invalidate the root page. buf_release_freed_page(): Split from buf_flush_freed_page(). Skip any I/O buf_flush_freed_pages(): Get the freed ranges from tablespace and Write punch-hole or zeroes of the freed ranges. buf_flush_try_neighbors(): Handles the flushing of freed ranges. mtr_t::freed_pages: Variable to store the list of freed pages. mtr_t::add_freed_pages(): To add freed pages. mtr_t::clear_freed_pages(): To clear the freed pages. mtr_t::m_freed_in_system_tablespace: Variable to indicate whether page has been freed in system tablespace. mtr_t::m_trim_pages: Variable to indicate whether the space has been trimmed. mtr_t::commit(): Add the freed page and update the last freed lsn in the tablespace and clear the tablespace freed range if space is trimmed. file_name_t::freed_pages: Store the freed pages during recovery. file_name_t::add_freed_page(), file_name_t::remove_freed_page(): To add and remove freed page during recovery. store_freed_or_init_rec(): Store or remove the freed pages while encountering FREE_PAGE or INIT_PAGE redo log record. recv_init_crash_recovery_spaces(): Add the freed page encountered during recovery to respective tablespace.
This commit is contained in:
@ -1,7 +0,0 @@
|
||||
--innodb-background-scrub-data-compressed=OFF
|
||||
--innodb-background-scrub-data-uncompressed=OFF
|
||||
--innodb-encrypt-tables=OFF
|
||||
--innodb-encryption-threads=0
|
||||
--innodb-immediate-scrub-data-uncompressed=ON
|
||||
--loose-innodb-debug-force-scrubbing=ON
|
||||
--innodb-tablespaces-scrubbing
|
@ -1,147 +0,0 @@
|
||||
-- source include/have_innodb.inc
|
||||
-- source include/not_embedded.inc
|
||||
-- source include/have_example_key_management_plugin.inc
|
||||
|
||||
let $MYSQLD_DATADIR=`select @@datadir`;
|
||||
let INNODB_PAGE_SIZE= `select @@innodb_page_size`;
|
||||
|
||||
create table snapshot_status engine = myisam
|
||||
select * from information_schema.global_status
|
||||
where variable_name like 'innodb_scrub_background%';
|
||||
|
||||
let $rowcount=500;
|
||||
let $maxformatno= 4;
|
||||
let $formatno= $maxformatno;
|
||||
|
||||
--echo # MDEV-8139 Fix scrubbing tests
|
||||
--echo # FIXME: Add index(b) to each table; ensure that undo logs are scrubbed.
|
||||
let $tableformat= (
|
||||
a int auto_increment primary key,
|
||||
b varchar(256),
|
||||
c text) engine = innodb row_format;
|
||||
|
||||
while ($formatno)
|
||||
{
|
||||
dec $formatno;
|
||||
let $format = `select case $formatno
|
||||
when 0 then 'dynamic'
|
||||
when 1 then 'redundant'
|
||||
when 2 then 'compact'
|
||||
when 3 then 'compressed'
|
||||
end`;
|
||||
|
||||
let $t= delete_$formatno;
|
||||
eval create table $t $tableformat=$format;
|
||||
|
||||
let $numinserts = $rowcount;
|
||||
--disable_query_log
|
||||
begin;
|
||||
while ($numinserts)
|
||||
{
|
||||
dec $numinserts;
|
||||
eval insert into $t(b,c) values ('repairman', repeat('unicycle', 1000));
|
||||
}
|
||||
commit;
|
||||
--enable_query_log
|
||||
|
||||
eval delete from $t;
|
||||
|
||||
let $t= delete_rollback_delete_$formatno;
|
||||
eval create table $t $tableformat=$format;
|
||||
|
||||
let $numinserts = $rowcount;
|
||||
--disable_query_log
|
||||
begin;
|
||||
while ($numinserts)
|
||||
{
|
||||
dec $numinserts;
|
||||
eval insert into $t(b,c) values ('breakhuman', repeat('bicycle', 1000));
|
||||
}
|
||||
commit;
|
||||
--enable_query_log
|
||||
|
||||
begin;
|
||||
eval delete from $t;
|
||||
rollback;
|
||||
eval delete from $t;
|
||||
|
||||
let $t= insert_rollback_$formatno;
|
||||
|
||||
eval create table $t $tableformat=$format;
|
||||
|
||||
let $numinserts = $rowcount;
|
||||
begin;
|
||||
--disable_query_log
|
||||
while ($numinserts)
|
||||
{
|
||||
dec $numinserts;
|
||||
eval insert into $t(b,c) values ('wonderwoman', repeat('tricycle', 1000));
|
||||
}
|
||||
--enable_query_log
|
||||
|
||||
rollback;
|
||||
}
|
||||
|
||||
SET GLOBAL innodb_fast_shutdown=0;
|
||||
-- source include/shutdown_mysqld.inc
|
||||
|
||||
let SEARCH_ABORT= FOUND;
|
||||
let SEARCH_PATTERN= (un|b|tr)icycle|(repair|breakhu|wonderwo)man;
|
||||
let SEARCH_RANGE= 12582912;
|
||||
let SEARCH_FILE= $MYSQLD_DATADIR/ibdata1;
|
||||
|
||||
# We may randomly find copies of unscrubbed pages in the doublewrite buffer.
|
||||
# Let us scrub the doublewrite buffer ourselves.
|
||||
perl;
|
||||
use Fcntl 'SEEK_SET';
|
||||
my $page_size = $ENV{INNODB_PAGE_SIZE};
|
||||
open(FILE, "+<", "$ENV{SEARCH_FILE}") or die "cannot open: $!\n";
|
||||
seek(FILE, $page_size * 64, SEEK_SET) or die "cannot seek: $!\n";
|
||||
print(FILE chr(0) x ($page_size * 128)) or die "cannot write: $!\n";
|
||||
close FILE or die "cannot close: $!\n";;
|
||||
EOF
|
||||
|
||||
-- source include/search_pattern_in_file.inc
|
||||
|
||||
let $formatno= $maxformatno;
|
||||
while ($formatno)
|
||||
{
|
||||
dec $formatno;
|
||||
|
||||
let $t= delete_$formatno.ibd;
|
||||
let SEARCH_FILE= $MYSQLD_DATADIR/test/$t;
|
||||
-- echo # $t
|
||||
-- source include/search_pattern_in_file.inc
|
||||
let $t= delete_rollback_delete_$formatno.ibd;
|
||||
let SEARCH_FILE= $MYSQLD_DATADIR/test/$t;
|
||||
-- echo # $t
|
||||
-- source include/search_pattern_in_file.inc
|
||||
let $t= insert_rollback_$formatno.ibd;
|
||||
let SEARCH_FILE= $MYSQLD_DATADIR/test/$t;
|
||||
-- echo # $t
|
||||
-- source include/search_pattern_in_file.inc
|
||||
}
|
||||
|
||||
-- source include/start_mysqld.inc
|
||||
|
||||
let $formatno= $maxformatno;
|
||||
while ($formatno)
|
||||
{
|
||||
dec $formatno;
|
||||
|
||||
let $t= delete_$formatno, delete_rollback_delete_$formatno, insert_rollback_$formatno;
|
||||
|
||||
eval check table $t;
|
||||
eval drop table $t;
|
||||
}
|
||||
|
||||
show variables like 'innodb_%scrub_data%';
|
||||
|
||||
--echo # verify that this test have not caused any background scrubbing
|
||||
--sorted_result
|
||||
select ss.variable_name, gs.variable_value - ss.variable_value as variable_value
|
||||
from snapshot_status ss,
|
||||
information_schema.global_status gs
|
||||
where ss.variable_name = gs.variable_name;
|
||||
|
||||
drop table snapshot_status;
|
@ -1,7 +0,0 @@
|
||||
--innodb-immediate-scrub-data-uncompressed=OFF
|
||||
--innodb-background-scrub-data-uncompressed=ON
|
||||
--innodb-background-scrub-data-compressed=ON
|
||||
--loose-innodb-debug-force-scrubbing=ON
|
||||
--innodb-encryption-threads=0
|
||||
--innodb-encrypt-tables=OFF
|
||||
--innodb-tablespaces-scrubbing
|
@ -1,170 +0,0 @@
|
||||
-- source include/have_innodb.inc
|
||||
-- source include/not_embedded.inc
|
||||
-- source include/have_example_key_management_plugin.inc
|
||||
|
||||
let $MYSQLD_DATADIR=`select @@datadir`;
|
||||
let INNODB_PAGE_SIZE= `select @@innodb_page_size`;
|
||||
|
||||
--echo #
|
||||
--echo # immediate scrubbing is off
|
||||
--echo # background scrubbing is on
|
||||
--echo #
|
||||
show variables like 'innodb_%scrub_data%';
|
||||
|
||||
-- echo # make sure spaces are checked quickly
|
||||
SET GLOBAL innodb_background_scrub_data_check_interval=1;
|
||||
|
||||
let $rowcount=500;
|
||||
let $maxformatno= 4;
|
||||
let $formatno= $maxformatno;
|
||||
|
||||
let $tableformat= (
|
||||
a int auto_increment primary key,
|
||||
b varchar(256),
|
||||
c text,
|
||||
index(b)) engine = innodb row_format;
|
||||
|
||||
while ($formatno)
|
||||
{
|
||||
dec $formatno;
|
||||
let $format = `select case $formatno
|
||||
when 0 then 'dynamic'
|
||||
when 1 then 'redundant'
|
||||
when 2 then 'compact'
|
||||
when 3 then 'compressed'
|
||||
end`;
|
||||
|
||||
let $t= delete_$formatno;
|
||||
eval create table $t $tableformat=$format;
|
||||
|
||||
let $numinserts = $rowcount;
|
||||
-- echo # Populate table with rows
|
||||
--disable_query_log
|
||||
begin;
|
||||
while ($numinserts)
|
||||
{
|
||||
dec $numinserts;
|
||||
eval insert into $t(b,c) values ('unicycle', repeat('wonderwoman', 1000));
|
||||
}
|
||||
commit;
|
||||
--enable_query_log
|
||||
|
||||
eval delete from $t;
|
||||
|
||||
let $t= delete_rollback_delete_$formatno;
|
||||
|
||||
eval create table $t $tableformat=$format;
|
||||
|
||||
let $numinserts = $rowcount;
|
||||
-- echo # Populate table with rows
|
||||
--disable_query_log
|
||||
begin;
|
||||
while ($numinserts)
|
||||
{
|
||||
dec $numinserts;
|
||||
eval insert into $t(b,c) values ('bicycle', repeat('repairman', 1000));
|
||||
}
|
||||
commit;
|
||||
--enable_query_log
|
||||
|
||||
begin;
|
||||
eval delete from $t;
|
||||
rollback;
|
||||
eval delete from $t;
|
||||
|
||||
let $t= insert_rollback_$formatno;
|
||||
|
||||
eval create table $t $tableformat=$format;
|
||||
|
||||
let $numinserts = $rowcount;
|
||||
-- echo # Populate table with rows
|
||||
begin;
|
||||
--disable_query_log
|
||||
while ($numinserts)
|
||||
{
|
||||
dec $numinserts;
|
||||
eval insert into $t(b,c) values ('tricycle', repeat('superhuman', 1000));
|
||||
}
|
||||
--enable_query_log
|
||||
|
||||
rollback;
|
||||
}
|
||||
|
||||
-- echo # start scrubbing threads
|
||||
SET GLOBAL innodb_encryption_threads=5;
|
||||
-- echo # Wait max 10 min for scrubbing
|
||||
let $cnt=600;
|
||||
while ($cnt)
|
||||
{
|
||||
let $success=`SELECT COUNT(*) = 0 FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_SCRUBBING WHERE LAST_SCRUB_COMPLETED IS NULL AND (NAME LIKE 'test/%' OR SPACE = 0)`;
|
||||
if ($success)
|
||||
{
|
||||
let $cnt=0;
|
||||
}
|
||||
if (!$success)
|
||||
{
|
||||
real_sleep 1;
|
||||
dec $cnt;
|
||||
}
|
||||
}
|
||||
if (!$success)
|
||||
{
|
||||
SELECT * FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_SCRUBBING;
|
||||
SHOW STATUS LIKE 'innodb_%scrub%';
|
||||
-- die Timeout waiting for background threads
|
||||
}
|
||||
|
||||
SET GLOBAL innodb_fast_shutdown=0;
|
||||
-- source include/shutdown_mysqld.inc
|
||||
|
||||
let SEARCH_ABORT= FOUND;
|
||||
let SEARCH_PATTERN= (un|b|tr)icycle|(repair|breakhu|wonderwo)man;
|
||||
let SEARCH_RANGE= 12582912;
|
||||
let SEARCH_FILE= $MYSQLD_DATADIR/ibdata1;
|
||||
|
||||
# We may randomly find copies of unscrubbed pages in the doublewrite buffer.
|
||||
# Let us scrub the doublewrite buffer ourselves.
|
||||
perl;
|
||||
use Fcntl 'SEEK_SET';
|
||||
my $page_size = $ENV{INNODB_PAGE_SIZE};
|
||||
open(FILE, "+<", "$ENV{SEARCH_FILE}") or die "cannot open: $!\n";
|
||||
seek(FILE, $page_size * 64, SEEK_SET) or die "cannot seek: $!\n";
|
||||
print(FILE chr(0) x ($page_size * 128)) or die "cannot write: $!\n";
|
||||
close FILE or die "cannot close: $!\n";;
|
||||
EOF
|
||||
|
||||
-- source include/search_pattern_in_file.inc
|
||||
|
||||
let $formatno= $maxformatno;
|
||||
while ($formatno)
|
||||
{
|
||||
dec $formatno;
|
||||
|
||||
let $t= delete_$formatno.ibd;
|
||||
let SEARCH_FILE= $MYSQLD_DATADIR/test/$t;
|
||||
-- echo # $t
|
||||
-- source include/search_pattern_in_file.inc
|
||||
let $t= delete_rollback_delete_$formatno.ibd;
|
||||
let SEARCH_FILE= $MYSQLD_DATADIR/test/$t;
|
||||
-- echo # $t
|
||||
-- source include/search_pattern_in_file.inc
|
||||
let $t= insert_rollback_$formatno.ibd;
|
||||
let SEARCH_FILE= $MYSQLD_DATADIR/test/$t;
|
||||
-- echo # $t
|
||||
-- source include/search_pattern_in_file.inc
|
||||
}
|
||||
|
||||
-- source include/start_mysqld.inc
|
||||
|
||||
let $formatno= $maxformatno;
|
||||
while ($formatno)
|
||||
{
|
||||
dec $formatno;
|
||||
|
||||
let $t= delete_$formatno, delete_rollback_delete_$formatno, insert_rollback_$formatno;
|
||||
|
||||
eval check table $t;
|
||||
eval drop table $t;
|
||||
}
|
||||
|
||||
show variables like 'innodb_%scrub_data%';
|
Reference in New Issue
Block a user