Skip to content

Commit

Permalink
PS-9322 fix: With super_read_only=1, undo truncation cannot update DD…
Browse files Browse the repository at this point in the history
… and leaves orphan truncate log files

https://perconadev.atlassian.net/browse/PS-9322

Backported Oracle fix for Bug #35784192
"tablespace is missing for table innodb_undo_002"
(commit mysql/mysql-server@bda098a and mysql/mysql-server@97f4285)
from 8.4 to 8.0.

Bug#35784192 tablespace is missing for table innodb_undo_002

This bug reports following two problems:

Querying the information schema reports undo tablespace is missing -
  while an undo file is present.
Purge threads don't remove the undo_space_number_trunc.log file.

While the first problem is already fixed through Bug#32104924, Bug#32654667

This bug fix aims to address the second problem.

The purge thread attempts to lock dictionary tables, while truncating
the undo tablespace. This lock can't be acquired in
a read-only MySQL instance, except when the thread has some special
flags associated with it. In this case, we use the skip_readonly_check
member of the thread descriptor struct, to signal that the readonly
check should not be applied to the purge thread. This is done
via the set_skip_readonly_check() method.

Change-Id: Iea6255ff6654752db8658bdd422cc3e58e3a8a97

Bug#35784192 tablespace is missing for table innodb_undo_002 [postfix]
Remove MySQL versions number from MTR test.

Change-Id: I3973435edbbc8bf442846c617ade4b5b824bb8c2
  • Loading branch information
GBuella authored and inikep committed Oct 25, 2024
1 parent a325109 commit f298585
Show file tree
Hide file tree
Showing 3 changed files with 124 additions and 0 deletions.
49 changes: 49 additions & 0 deletions mysql-test/suite/innodb_undo/r/purge_on_replica.result
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
include/master-slave.inc
Warnings:
Note #### Sending passwords in plain text without SSL/TLS is extremely insecure.
Note #### Storing MySQL user name or password information in the connection metadata repository is not secure and is therefore not recommended. Please consider using the USER and PASSWORD connection options for START REPLICA; see the 'START REPLICA Syntax' in the MySQL Manual for more information.
[connection master]
# 1: Set replica parameters
set @orig_max_undo_log_size = @@innodb_max_undo_log_size;
set @orig_truncate_frequency = @@innodb_purge_rseg_truncate_frequency;
set global innodb_max_undo_log_size=10485760;
set global innodb_purge_rseg_truncate_frequency=1;
set global super_read_only=1;

# 2: Preparing database
create table t1(id int);
create procedure insert_data()
begin
declare i int;
set i=1;
while(i<=500000) do
insert into t1(id) values(i);
set i=i+1;
end while;
end;$$
begin;
# 3: Inserting data, filling undo logs
call insert_data();
# 4: commit, trigger undo log truncation
commit;
select tablespace_name, file_name from information_schema.files
where file_name like "%undo%";
TABLESPACE_NAME FILE_NAME
innodb_undo_001 ./undo_001
innodb_undo_002 ./undo_002
select name, row_format from information_schema.innodb_tablespaces
where name like '%undo%';
name row_format
innodb_undo_001 Undo
innodb_undo_002 Undo
# 5: undo files undo_001 and undo_002 are expected to exist,
# while files undo_001_trunc.log and undo_002_trunc.log are expected to not exist
undo_001
undo_002
set global innodb_max_undo_log_size=@orig_max_undo_log_size;
set global innodb_purge_rseg_truncate_frequency=@orig_truncate_frequency;
set global super_read_only = 0;
set global read_only = 0;
drop procedure insert_data;
drop table t1;
include/rpl_end.inc
71 changes: 71 additions & 0 deletions mysql-test/suite/innodb_undo/t/purge_on_replica.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
--source include/have_debug.inc
# The test requires a debug build, in order to trigger
# a purge using innodb_purge_run_now=ON .

--source include/master-slave.inc

--echo # 1: Set replica parameters
connection slave;

set @orig_max_undo_log_size = @@innodb_max_undo_log_size;
set @orig_truncate_frequency = @@innodb_purge_rseg_truncate_frequency;

# Trigger truncation of undo log files once they occupy more than 10MB
# which is the minimum value of innodb_max_undo_log_size
set global innodb_max_undo_log_size=10485760;
set global innodb_purge_rseg_truncate_frequency=1;
set global super_read_only=1;

--echo
--echo # 2: Preparing database
connection master;

create table t1(id int);

delimiter $$;
create procedure insert_data()
begin
declare i int;
set i=1;
while(i<=500000) do
insert into t1(id) values(i);
set i=i+1;
end while;
end;$$
delimiter ;$$

begin;

--echo # 3: Inserting data, filling undo logs
call insert_data();

--echo # 4: commit, trigger undo log truncation
commit;
sync_slave_with_master;

connection slave;

--source include/wait_innodb_all_purged.inc


# expecting two undo files, and no undo_*_trunc.log files remaining

select tablespace_name, file_name from information_schema.files
where file_name like "%undo%";
select name, row_format from information_schema.innodb_tablespaces
where name like '%undo%';

let $MYSQLD_DATADIR = `select @@datadir`;

--echo # 5: undo files undo_001 and undo_002 are expected to exist,
--echo # while files undo_001_trunc.log and undo_002_trunc.log are expected to not exist
list_files $MYSQLD_DATADIR undo_0*;

set global innodb_max_undo_log_size=@orig_max_undo_log_size;
set global innodb_purge_rseg_truncate_frequency=@orig_truncate_frequency;
set global super_read_only = 0;
set global read_only = 0;
connection master;
drop procedure insert_data;
drop table t1;
--source include/rpl_end.inc
4 changes: 4 additions & 0 deletions storage/innobase/srv/srv0srv.cc
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ this program; if not, write to the Free Software Foundation, Inc.,
#include "row0log.h"
#include "row0mysql.h"
#include "sql/current_thd.h"
#include "sql/sql_class.h"
#include "sql_thd_internal_api.h"
#include "srv0mon.h"

Expand Down Expand Up @@ -3438,6 +3439,9 @@ void srv_purge_coordinator_thread() {

THD *thd = create_internal_thd();

// Allow purge in read only mode as well.
thd->set_skip_readonly_check();

purge_sys->is_this_a_purge_thread = true;

ulint n_total_purged = ULINT_UNDEFINED;
Expand Down

0 comments on commit f298585

Please sign in to comment.