1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-08 11:22:35 +03:00

MDEV-33167 ASAN errors in dict_sys_t::load_table / get_foreign_key_info after failing to load a table

Problem:
=======
- While loading the foreign key constraints for the parent table,
if child table wasn't open then InnoDB uses the parent table heap
to store the child table name in fk_tables list. If the consecutive
foreign key relation for the parent table fails with error,
InnoDB evicts the parent table from memory. But InnoDB accesses the
evicted table memory again in dict_sys.load_table()

Solution:
========
dict_load_table_one(): In case of error, remove the child table
names which was added during dict_load_foreigns()
This commit is contained in:
Thirunarayanan Balathandayuthapani
2025-04-03 16:43:01 +05:30
parent 0d7ef4f478
commit b11772d9a5
3 changed files with 48 additions and 7 deletions

View File

@@ -155,7 +155,6 @@ INSERT INTO parent SET a=0;
FLUSH TABLES;
# restart
disconnect incomplete;
SET @save_stats_persistent = @@GLOBAL.innodb_stats_persistent;
SET GLOBAL innodb_stats_persistent = 0;
INSERT INTO child SET a=0;
INSERT INTO child SET a=1;
@@ -1182,5 +1181,23 @@ ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fail
ALTER TABLE t2 ADD KEY(b), ALGORITHM=NOCOPY;
DELETE FROM t1;
DROP TABLE t2, t1;
#
# MDEV-33167 ASAN errors after failing to load foreign key
# relation for the table
#
call mtr.add_suppression("InnoDB: Load table `test`.`t3` failed, the table has missing foreign key indexes. Turn off 'foreign_key_checks' and try again.");
SET STATEMENT FOREIGN_KEY_CHECKS = 0 FOR
CREATE TABLE t1(f1 VARCHAR(8),
FOREIGN KEY(f1) REFERENCES test.t3(f1))ENGINE=InnoDB;
SET STATEMENT FOREIGN_KEY_CHECKS = 0 FOR
CREATE TABLE t2(f1 VARCHAR(8),
FOREIGN KEY(f1) REFERENCES test.t3(f1))
ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;
SET STATEMENT FOREIGN_KEY_CHECKS = 0 FOR
CREATE TABLE t3(f1 VARCHAR(8) PRIMARY KEY)
ENGINE=InnoDB DEFAULT CHARSET=latin1;
set GLOBAL innodb_fast_shutdown=0;
# restart
ALTER TABLE t2 FORCE;
DROP TABLE t2, t1, t3;
# End of 10.6 tests
SET GLOBAL innodb_stats_persistent = @save_stats_persistent;

View File

@@ -133,7 +133,6 @@ FLUSH TABLES;
--let $shutdown_timeout=
disconnect incomplete;
SET @save_stats_persistent = @@GLOBAL.innodb_stats_persistent;
SET GLOBAL innodb_stats_persistent = 0;
INSERT INTO child SET a=0;
@@ -1245,8 +1244,31 @@ ALTER TABLE t2 ADD KEY(b), ALGORITHM=NOCOPY;
DELETE FROM t1;
DROP TABLE t2, t1;
--echo #
--echo # MDEV-33167 ASAN errors after failing to load foreign key
--echo # relation for the table
--echo #
call mtr.add_suppression("InnoDB: Load table `test`.`t3` failed, the table has missing foreign key indexes. Turn off 'foreign_key_checks' and try again.");
SET STATEMENT FOREIGN_KEY_CHECKS = 0 FOR
CREATE TABLE t1(f1 VARCHAR(8),
FOREIGN KEY(f1) REFERENCES test.t3(f1))ENGINE=InnoDB;
SET STATEMENT FOREIGN_KEY_CHECKS = 0 FOR
CREATE TABLE t2(f1 VARCHAR(8),
FOREIGN KEY(f1) REFERENCES test.t3(f1))
ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;
SET STATEMENT FOREIGN_KEY_CHECKS = 0 FOR
CREATE TABLE t3(f1 VARCHAR(8) PRIMARY KEY)
ENGINE=InnoDB DEFAULT CHARSET=latin1;
set GLOBAL innodb_fast_shutdown=0;
--let $shutdown_timeout=
--source include/restart_mysqld.inc
# Error encountered while loading the foreign key
# constraint for t3. t1 wasn't loaded into memory yet
# t2 failed to find index for foreign key relation
ALTER TABLE t2 FORCE;
DROP TABLE t2, t1, t3;
--echo # End of 10.6 tests
SET GLOBAL innodb_stats_persistent = @save_stats_persistent;
--source include/wait_until_count_sessions.inc

View File

@@ -2515,10 +2515,12 @@ corrupted:
if (!table->is_readable()) {
/* Don't attempt to load the indexes from disk. */
} else if (err == DB_SUCCESS) {
auto i = fk_tables.size();
err = dict_load_foreigns(table->name.m_name, nullptr,
0, true, ignore_err, fk_tables);
if (err != DB_SUCCESS) {
fk_tables.erase(fk_tables.begin() + i, fk_tables.end());
ib::warn() << "Load table " << table->name
<< " failed, the table has missing"
" foreign key indexes. Turn off"