[MDEV-33400] Adaptive hash index corruption after ALTER TABLE…DISCARD TABLESPACE Created: 2024-02-07  Updated: 2024-02-08

Status: Stalled
Project: MariaDB Server
Component/s: Storage Engine - InnoDB
Affects Version/s: 10.4, 10.5
Fix Version/s: 10.4, 10.5

Type: Bug Priority: Major
Reporter: Ramesh Sivaraman Assignee: Marko Mäkelä
Resolution: Unresolved Votes: 1
Labels: None

Issue Links:
Problem/Incident
is caused by MDEV-18295 IMPORT TABLESPACE fails with instant-... Closed

 Description   

--source include/have_innodb.inc
--source include/have_sequence.inc
 
CREATE TABLE t (a INT) ENGINE=INNODB;
INSERT INTO t SELECT * FROM seq_1_to_1000;
ALTER TABLE t ADD hid INT DEFAULT 2;
INSERT INTO t VALUES (1,1);
ALTER TABLE t DISCARD TABLESPACE;
DROP TABLE t;
CREATE TABLE t (a CHAR KEY,b CHAR,KEY(b)) ENGINE=INNODB;
CHECK TABLE t;

Leads to:

10.4.33 f4ee7c110cd6faee3fa80b61ae572f471341c906 (Debug)

mariadbd: /test/10.4_dbg/storage/innobase/rem/rem0rec.cc:641: void rec_init_offsets(const rec_t*, const dict_index_t*, ulint, rec_offs*): Assertion `index->is_instant()' failed.

10.4.33 f4ee7c110cd6faee3fa80b61ae572f471341c906 (Debug)

Core was generated by `/test/MD010224-mariadb-10.4.33-linux-x86_64-dbg/bin/mariadbd --no-defaults --ma'.
Program terminated with signal SIGABRT, Aborted.
#0  __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
[Current thread is 1 (Thread 0x14855407b700 (LWP 1590611))]
(gdb) bt
#0  __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
#1  0x000014855ed02859 in __GI_abort () at abort.c:79
#2  0x000014855ed02729 in __assert_fail_base (fmt=0x14855ee98588 "%s%s%s:%u: %s%sAssertion `%s' failed.\n%n", assertion=0x556be51dc7e0 "index->is_instant()", file=0x556be51f46e0 "/test/10.4_dbg/storage/innobase/rem/rem0rec.cc", line=641, function=<optimized out>) at assert.c:92
#3  0x000014855ed13fd6 in __GI___assert_fail (assertion=assertion@entry=0x556be51dc7e0 "index->is_instant()", file=file@entry=0x556be51f46e0 "/test/10.4_dbg/storage/innobase/rem/rem0rec.cc", line=line@entry=641, function=function@entry=0x556be51f5b38 "void rec_init_offsets(const rec_t*, const dict_index_t*, ulint, rec_offs*)") at assert.c:101
#4  0x0000556be4a89eee in rec_init_offsets (offsets=0x148554077e00, n_core=5, index=0x1484f4020680, rec=0x14853c951a19 "") at /test/10.4_dbg/storage/innobase/rem/rem0rec.cc:641
#5  rec_get_offsets_func (rec=0x14853c951a19 "", index=0x1484f4020680, offsets=offsets@entry=0x148554077e00, n_core=5, n_fields=<optimized out>, file=file@entry=0x556be5227b60 "/test/10.4_dbg/storage/innobase/btr/btr0sea.cc", line=2095, heap=0x148554077da8) at /test/10.4_dbg/storage/innobase/rem/rem0rec.cc:931
#6  0x0000556be4c362b5 in btr_search_hash_table_validate (hash_table_id=hash_table_id@entry=3) at /test/10.4_dbg/storage/innobase/btr/btr0sea.cc:2095
#7  0x0000556be4c3657f in btr_search_validate () at /test/10.4_dbg/storage/innobase/btr/btr0sea.cc:2195
#8  0x0000556be49486c3 in ha_innobase::check (this=0x1484f407f960, thd=<optimized out>, check_opt=0x1484f4005fa0) at /test/10.4_dbg/storage/innobase/include/dict0dict.inl:239
#9  0x0000556be45cbcc7 in handler::ha_check (this=0x1484f407f960, thd=0x1484f4000d28, check_opt=0x1484f4005fa0) at /test/10.4_dbg/sql/handler.cc:4428
#10 0x0000556be446f52a in mysql_admin_table (thd=thd@entry=0x1484f4000d28, tables=tables@entry=0x1484f4012700, check_opt=check_opt@entry=0x1484f4005fa0, operator_name=operator_name@entry=0x556be54e0ae9 "check", lock_type=lock_type@entry=TL_READ_NO_INSERT, org_open_for_modify=org_open_for_modify@entry=false, repair_table_use_frm=false, extra_open_options=32, prepare_func=0x0, operator_func=(int (handler::*)(class handler * const, class THD *, HA_CHECK_OPT *)) 0x556be45cbc60 <handler::ha_check(THD*, st_ha_check_opt*)>, view_operator_func=0x556be4413e25 <view_check(THD*, TABLE_LIST*, st_ha_check_opt*)>, is_cmd_replicated=false) at /test/10.4_dbg/sql/sql_admin.cc:865
#11 0x0000556be4471134 in Sql_cmd_check_table::execute (this=<optimized out>, thd=0x1484f4000d28) at /test/10.4_dbg/sql/sql_admin.cc:1458
#12 0x0000556be432bb37 in mysql_execute_command (thd=thd@entry=0x1484f4000d28) at /test/10.4_dbg/sql/sql_parse.cc:6292
#13 0x0000556be432e229 in mysql_parse (thd=thd@entry=0x1484f4000d28, rawbuf=<optimized out>, length=<optimized out>, parser_state=parser_state@entry=0x14855407a360, is_com_multi=is_com_multi@entry=false, is_next_command=is_next_command@entry=false) at /test/10.4_dbg/sql/sql_parse.cc:8088
#14 0x0000556be433123b in dispatch_command (command=command@entry=COM_QUERY, thd=thd@entry=0x1484f4000d28, packet=packet@entry=0x1484f4019699 "", packet_length=packet_length@entry=13, is_com_multi=is_com_multi@entry=false, is_next_command=is_next_command@entry=false) at /test/10.4_dbg/sql/sql_class.h:1242
#15 0x0000556be4333eba in do_command (thd=0x1484f4000d28) at /test/10.4_dbg/sql/sql_parse.cc:1378
#16 0x0000556be445f846 in do_handle_one_connection (connect=connect@entry=0x556be6f52108) at /test/10.4_dbg/sql/sql_connect.cc:1419
#17 0x0000556be445f965 in handle_one_connection (arg=0x556be6f52108) at /test/10.4_dbg/sql/sql_connect.cc:1323
#18 0x000014855f213609 in start_thread (arg=<optimized out>) at pthread_create.c:477
#19 0x000014855edff133 in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95

Bug confirmed present in:
MariaDB: 10.4.33 (dbg)

Bug (or feature/syntax) confirmed not present in:
MariaDB: 10.4.33 (opt), 10.5.24 (dbg), 10.5.24 (opt), 10.6.17 (dbg), 10.6.17 (opt), 10.11.7 (dbg), 10.11.7 (opt), 11.0.5 (dbg), 11.0.5 (opt), 11.1.4 (dbg), 11.1.4 (opt), 11.2.3 (dbg), 11.2.3 (opt), 11.3.2 (dbg), 11.3.2 (opt), 11.4.0 (dbg), 11.4.0 (opt)



 Comments   
Comment by Marko Mäkelä [ 2024-02-07 ]

We might not want to fix this in 10.4, because there is only one scheduled release of the 10.4 release left and the adaptive hash index code was heavily refactored between 10.4 and 10.5.

I can reproduce this on 10.5 just fine if I explicitly enable the adaptive hash index, which was disabled by default in MDEV-20487. Here is a little better test:

--source include/have_innodb.inc
--source include/have_sequence.inc
SET @save_adaptive=@@GLOBAL.innodb_adaptive_hash_index;
SET GLOBAL innodb_adaptive_hash_index=ON;
CREATE TEMPORARY TABLE tt (a INT PRIMARY KEY) ENGINE=INNODB;
 
CREATE TABLE t (a INT PRIMARY KEY) ENGINE=INNODB;
INSERT INTO t SELECT * FROM seq_1_to_131;
ALTER TABLE t ADD hid INT DEFAULT 2;
INSERT INTO t VALUES (251,1);
ALTER TABLE t DISCARD TABLESPACE;
CHECK TABLE tt;
DROP TABLE t;
SET GLOBAL innodb_adaptive_hash_index=@save_adaptive;

Comment by Marko Mäkelä [ 2024-02-07 ]

The problem is that row_discard_tablespace() invoked dict_index_t::clear_instant_alter() but did not drop the adaptive hash index. We can better invoke that at the start of ALTER TABLE…IMPORT TABLESPACE. As far as I understand, the bug was introduced in MDEV-18295.

Comment by Marko Mäkelä [ 2024-02-07 ]

thiru, thank you for pointing out that the adaptive hash index cannot actually be corrupted in this case. I implemented a simpler fix of relaxing two debug assertions.

Comment by Marko Mäkelä [ 2024-02-08 ]

It turns out that we can’t fix this easily by relaxing debug assertions after all. I think that it is less risky to move the call to dict_index_t::clear_instant_alter() until after the adaptive hash index has been dropped or detached than to try to tweak the calculations. Initially, I repeated and relaxed 2 assertion failures with the test. Occasionally, a 3rd one fails as well, and I do not think I can relax that one.

Generated at Thu Feb 08 10:38:37 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.