Details
-
Bug
-
Status: Closed (View Workflow)
-
Critical
-
Resolution: Fixed
-
10.2(EOL), 10.3(EOL), 10.4(EOL), 10.5, 10.6, 10.7(EOL), 10.8(EOL), 10.9(EOL)
-
None
Description
Reproduce
--source include/have_innodb.inc
|
|
set names utf8; |
let $d= `select repeat('❎', 45)`; |
let $t= `select repeat('❎', 64)`; |
eval create database `$d`; |
eval use `$d`; |
create table t (a int primary key) engine=innodb; |
eval create or replace table u ( |
a int primary key, |
constraint `$t` foreign key d (a) references t (a)) engine=innodb; |
#select * from information_schema.innodb_sys_foreign; |
eval create or replace table u ( |
a int primary key, |
constraint `$t` foreign key d (a) references t (a)) engine=innodb; |
#select * from information_schema.innodb_sys_foreign; |
show create table u; |
use test; |
eval drop database `$d`; |
Result
0ba528fe56f |
#5 0x00005580cf377991 in ut_dbg_assertion_failed (expr=0x5580cf8d2fec "len <= MAX_TABLE_NAME_LEN", file=0x5580cf95086b "../src/storage/innobase/dict/dict0load.cc", line=3690) at ../src/storage/innobase/ut/ut0dbg.cc:60
|
#6 0x00005580cf44f98e in dict_load_foreigns (table_name=0x7f43c80ee490 "@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e/u", col_names=0x0, check_recursive=false, check_charsets=true, ignore_err=DICT_ERR_IGNORE_NONE, fk_tables=std::deque with 0 elements) at ../src/storage/innobase/dict/dict0load.cc:3690
|
#7 0x00005580cf133244 in create_table_info_t::create_table (this=0x7f43c80ee208, create_fk=true) at ../src/storage/innobase/handler/ha_innodb.cc:12718
|
#8 0x00005580cf14f4ad in ha_innobase::create (this=0x7f43d002a9c0, name=0x7f43c80f1b20 "./@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e/u", form=0x7f43c80eef08, create_info=0x7f43c80f2080, file_per_table=true, trx=0x7f43e02dc218) at ../src/storage/innobase/handler/ha_innodb.cc:13167
|
#9 0x00005580cf134157 in ha_innobase::create (this=0x7f43d002a9c0, name=0x7f43c80f1b20 "./@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e/u", form=0x7f43c80eef08, create_info=0x7f43c80f2080) at ../src/storage/innobase/handler/ha_innodb.cc:13220
|
#10 0x00005580ceef71c3 in handler::ha_create (this=0x7f43d002a9c0, name=0x7f43c80f1b20 "./@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e/u", form=0x7f43c80eef08, info_arg=0x7f43c80f2080) at ../src/sql/handler.cc:4510
|
#11 0x00005580ceef8394 in ha_create_table (thd=0x7f43d0008ef8, path=0x7f43c80f1b20 "./@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e/u", db=0x7f43d001c3b8 "❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎", table_name=0x7f43d001bd48 "u", create_info=0x7f43c80f2080, frm=0x7f43c80f1b10) at ../src/sql/handler.cc:4883
|
#12 0x00005580ced98188 in rea_create_table (thd=0x7f43d0008ef8, frm=0x7f43c80f1b10, path=0x7f43c80f1b20 "./@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e/u", db=0x7f43d001c3b8 "❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎", table_name=0x7f43d001bd48 "u", create_info=0x7f43c80f2080, file=0x7f43d001ce80, no_ha_create_table=false) at ../src/sql/unireg.cc:429
|
#13 0x00005580ced366f8 in create_table_impl (thd=0x7f43d0008ef8, orig_db=0x7f43d001c3b8 "❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎", orig_table_name=0x7f43d001bd48 "u", db=0x7f43d001c3b8 "❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎", table_name=0x7f43d001bd48 "u", path=0x7f43c80f1b20 "./@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e@274e/u", options=..., create_info=0x7f43c80f2080, alter_info=0x7f43c80f1fd8, create_table_mode=0, is_trans=0x7f43c80f1e47, key_info=0x7f43c80f1d38, key_count=0x7f43c80f1d34, frm=0x7f43c80f1b10) at ../src/sql/sql_table.cc:5006
|
#14 0x00005580ced35be6 in mysql_create_table_no_lock (thd=0x7f43d0008ef8, db=0x7f43d001c3b8 "❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎", table_name=0x7f43d001bd48 "u", create_info=0x7f43c80f2080, alter_info=0x7f43c80f1fd8, is_trans=0x7f43c80f1e47, create_table_mode=0) at ../src/sql/sql_table.cc:5116
|
#15 0x00005580ced36e2c in mysql_create_table (thd=0x7f43d0008ef8, create_table=0x7f43d001bd98, create_info=0x7f43c80f2080, alter_info=0x7f43c80f1fd8) at ../src/sql/sql_table.cc:5184
|
#16 0x00005580ced4897a in Sql_cmd_create_table::execute (this=0x7f43d001bd78, thd=0x7f43d0008ef8) at ../src/sql/sql_table.cc:11067
|
#17 0x00005580cec5e6bd in mysql_execute_command (thd=0x7f43d0008ef8) at ../src/sql/sql_parse.cc:6017
|
#18 0x00005580cec52928 in mysql_parse (thd=0x7f43d0008ef8, rawbuf=0x7f43d001ba00 "create or replace table u (\na int primary key,\nconstraint `❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎ ❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎❎` foreign key d (a) references t (a)) engine=innodb", length=302, parser_state=0x7f43c80f4560, is_com_multi=false, is_next_command=false) at ../src/sql/sql_parse.cc:7793
|
3682 /* Now we get a foreign key constraint id */ |
3683 field = rec_get_nth_field_old(
|
3684 rec, DICT_FLD__SYS_FOREIGN_FOR_NAME__ID, &len);
|
3685
|
3686 /* Copy the string because the page may be modified or evicted |
3687 after mtr_commit() below. */
|
3688 char fk_id[MAX_TABLE_NAME_LEN + 1]; |
3689
|
3690 ut_a(len <= MAX_TABLE_NAME_LEN);
|
Attachments
Issue Links
- blocks
-
MDEV-28933 Per-table unique FOREIGN KEY constraint names
-
- In Testing
-
- relates to
-
MDEV-29258 Failing assertion for name length on RENAME TABLE
-
- Closed
-
I reproduced this with a simpler test case, using a minimal-length database name (26*5 characters in my_charset_filename), and with 64 normal-width 3-byte UTF-8 glyphs in the constraint name:
--source include/have_innodb.inc
let $d=##########################;
10.3 95989e82114f74b4c8b6bb47456794811f0c3f8b
2022-07-25 08:24:09 0x7fa4fd7de640 InnoDB: Assertion failure in file /mariadb/10.3/storage/innobase/dict/dict0load.cc line 3656
InnoDB: Failing assertion: len <= MAX_TABLE_NAME_LEN
The SYS_FOREIGN.ID will contain the database name in the filename-safe encoding, a separator /, and the constraint name. This easily exceeds the MAX_TABLE_NAME_LEN (5*64=320). The actual maximum length of SYS_FOREIGN.ID should be 5*64+1+3*64=513 bytes, but operating systems may restrict the path component length further. In Linux, a path component may be up to 255 bytes. So, the maximum database name length would be 51 characters when each of them is encoded in 5 bytes.
The internal SQL interpreter of InnoDB does not really enforce any maximum length; we saw it in
MDEV-14637already, where an exception was implemented for SYS_FOREIGN and SYS_FOREIGN_COLS. As far as I can tell, the maximum record length would be achieved for the SYS_FOREIGN secondary indexes (FOR_NAME,ID) and (REF_NAME,ID): 5*64+1+5*64 = 641 bytes for the table name and 513 bytes for the FOREIGN KEY identifier. Those 1154 bytes are nowhere near the maximum record length, which is almost twice as long even with the minimal innodb_page_size=4k.The SYS_FOREIGN.ID could be potentially longer for implicitly created constraint names. In that case, the string _ibfk_ and a number (presumably up to 2 or 3 digits) would be appended to the table name. However, in such a case the FN_REFLEN (512 bytes) would kick in way before the maximum-length database and table name (641 bytes) are exceeded. Even with 255-byte table and database names (51*5 characters), the limit will be exceeded, because the total length would be 2+255+1+255 = 513 bytes. The actual maximum length that I got to work is a 255-byte database name and a 250-byte table name.