[MDEV-25691] Simplify handlerton::drop_database for InnoDB Created: 2021-05-17  Updated: 2022-10-21  Resolved: 2021-05-18

Status: Closed
Project: MariaDB Server
Component/s: Storage Engine - InnoDB
Fix Version/s: 10.6.1

Type: Task Priority: Blocker
Reporter: Marko Mäkelä Assignee: Marko Mäkelä
Resolution: Fixed Votes: 0
Labels: performance

Issue Links:
Blocks
blocks MDEV-25506 Atomic DDL: .frm file is removed and ... Closed
Problem/Incident
causes MDEV-25748 DROP DATABASE drops unrelated FOREIGN... Closed
causes MDEV-27336 Crash on DROP DATABASE due to out-of-... Closed
causes MDEV-28802 DROP DATABASE still is case-insensitive Closed
Relates
relates to MDEV-24408 Crash-safe DROP DATABASE Closed
relates to MDEV-29846 deadlock on dict_sys.mutex on databas... Open

 Description   

The implementation of handlerton::drop_database in InnoDB is unnecessarily complex. The minimal implementation should check that no conflicting locks or references exist on the tables, delete all table metadata in a single transaction, and finally delete the tablespaces.

Note: DROP DATABASE will delete each individual table that the SQL layer knows about, one table per transaction. The handlerton::drop_database is basically a final cleanup step for removing any garbage that could have been left behind in InnoDB due to some bug, or not having Atomic DDL (MDEV-17567) in the past.



 Comments   
Comment by Marko Mäkelä [ 2021-05-18 ]

As part of this fix, a function lock_release_on_rollback() was introduced to avoid heap-use-after-free on the rollback of native ALTER TABLE. That and related refactoring of dict_drop_index_tree() could be viewed as a follow-up fix of MDEV-18518.

Comment by Elena Stepanova [ 2021-05-21 ]

For a reference – test case and a failure (one of) that a postfix for this task has fixed.

--source include/have_innodb.inc
 
CREATE TABLE t (a INT PRIMARY KEY) ENGINE=InnoDB;
SET FOREIGN_KEY_CHECKS = OFF;
ALTER TABLE t ADD CONSTRAINT FOREIGN KEY j (a) REFERENCES view_table1_myisam (a);
--connect (con1,localhost,root,,test)
CREATE DATABASE db;
DROP DATABASE db;
 
# Cleanup
DROP TABLE t;

10.6 5d495fc44b

==3247674==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60e000048674 at pc 0x7f2976f0fdfd bp 0x7f2966456120 sp 0x7f29664558c8
READ of size 23 at 0x60e000048674 thread T13
    #0 0x7f2976f0fdfc  (/lib/x86_64-linux-gnu/libasan.so.5+0xdadfc)
    #1 0x55a595618241 in innodb_drop_database_fk /data/src/10.6-bug/storage/innobase/handler/ha_innodb.cc:1298
    #2 0x55a595a5d195 in fetch_step(que_thr_t*) /data/src/10.6-bug/storage/innobase/row/row0sel.cc:2385
    #3 0x55a59590b7c9 in que_thr_step /data/src/10.6-bug/storage/innobase/que/que0que.cc:637
    #4 0x55a59590bc37 in que_run_threads_low /data/src/10.6-bug/storage/innobase/que/que0que.cc:709
    #5 0x55a59590bdd9 in que_run_threads(que_thr_t*) /data/src/10.6-bug/storage/innobase/que/que0que.cc:729
    #6 0x55a59590c215 in que_eval_sql(pars_info_t*, char const*, bool, trx_t*) /data/src/10.6-bug/storage/innobase/que/que0que.cc:779
    #7 0x55a595619612 in innodb_drop_database /data/src/10.6-bug/storage/innobase/handler/ha_innodb.cc:1469
    #8 0x55a594affc1d in dropdb_handlerton /data/src/10.6-bug/sql/handler.cc:824
    #9 0x55a5943295d1 in plugin_foreach_with_mask(THD*, char (*)(THD*, st_plugin_int**, void*), int, unsigned int, void*) /data/src/10.6-bug/sql/sql_plugin.cc:2505
    #10 0x55a594affc56 in ha_drop_database(char*) /data/src/10.6-bug/sql/handler.cc:831
    #11 0x55a5941f9057 in mysql_rm_db_internal /data/src/10.6-bug/sql/sql_db.cc:1082
    #12 0x55a5941f9d64 in mysql_rm_db(THD*, st_mysql_const_lex_string const*, bool) /data/src/10.6-bug/sql/sql_db.cc:1215
    #13 0x55a5942efc5a in mysql_execute_command(THD*) /data/src/10.6-bug/sql/sql_parse.cc:5175
    #14 0x55a59430325b in mysql_parse(THD*, char*, unsigned int, Parser_state*) /data/src/10.6-bug/sql/sql_parse.cc:8019
    #15 0x55a5942d997e in dispatch_command(enum_server_command, THD*, char*, unsigned int, bool) /data/src/10.6-bug/sql/sql_parse.cc:1897
    #16 0x55a5942d669f in do_command(THD*, bool) /data/src/10.6-bug/sql/sql_parse.cc:1406
    #17 0x55a59471deeb in do_handle_one_connection(CONNECT*, bool) /data/src/10.6-bug/sql/sql_connect.cc:1410
    #18 0x55a59471d848 in handle_one_connection /data/src/10.6-bug/sql/sql_connect.cc:1312
    #19 0x55a595432df8 in pfs_spawn_thread /data/src/10.6-bug/storage/perfschema/pfs.cc:2201
    #20 0x7f2976943608 in start_thread /build/glibc-eX1tMB/glibc-2.31/nptl/pthread_create.c:477
    #21 0x7f2976517292 in __clone (/lib/x86_64-linux-gnu/libc.so.6+0x122292)

Fixed by

commit 2714158150d645d74081ded08f3b355e0cd55143 (HEAD)
Author: Marko Mäkelä
Date:   Wed May 19 14:27:12 2021 +0300
 
    MDEV-25691 fixup: Correctly drop orphan foreign keys

Generated at Thu Feb 08 09:39:36 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.