From 3be190ac30c04f6ca6161dad0e11d145bf75785f Mon Sep 17 00:00:00 2001 From: Thirunarayanan Balathandayuthapani Date: Fri, 13 Feb 2026 20:25:09 +0530 Subject: [PATCH] MDEV-38842 Server fails to drop .ibd file when vector table creation fails Problem: ======== When creating tables with vector indexes, if the secondary table creation fails after the main table is successfully created, the server was not properly cleaning up the main table's .ibd file. Stale file exists because create_table_impl() always called ddl_log_complete() on any error, which disables DDL log entries instead of executing them for cleanup. The main table would be left behind even though the overall CREATE TABLE operation failed. Solution: ========= ha_create_table(): Return error code 2 specifically when secondary table creation for high-level indexes fails create_table_impl(): Call ddl_log_revert() when error code is 2 to properly clean up the main table files. --- mysql-test/suite/atomic/vector_innodb.result | 11 +++++++++++ mysql-test/suite/atomic/vector_innodb.test | 13 +++++++++++++ sql/handler.cc | 10 +++++++++- sql/sql_table.cc | 16 ++++++++++++---- 4 files changed, 45 insertions(+), 5 deletions(-) diff --git a/mysql-test/suite/atomic/vector_innodb.result b/mysql-test/suite/atomic/vector_innodb.result index fff1a6c755be3..841e33e2c5a42 100644 --- a/mysql-test/suite/atomic/vector_innodb.result +++ b/mysql-test/suite/atomic/vector_innodb.result @@ -1816,3 +1816,14 @@ count(*) 2 master-bin.000002 # Query # # use `test`; ALTER TABLE t1 DROP INDEX a ALTER DATABASE test CHARACTER SET utf8mb4 COLLATE utf8mb4_uca1400_ai_ci; +# +# MDEV-38832 Assertion `!commit_lsn' failed in void trx_t::free() +# +CREATE DATABASE test_1; +SET STATEMENT max_session_mem_used=8192 FOR +CREATE TABLE test_1.t (a INT,b VECTOR (5) NOT NULL, +VECTOR INDEX (b)) ENGINE=INNODB; +ERROR HY000: Engine InnoDB failed to discover table `test_1`.`t` with 'CREATE TABLE i ( layer tinyint not null, tref varbinary(6), vec blob not null, neighbors blob not null, unique (tref), key (layer)) ' +# Print the files exist in test_1 directory +db.opt +DROP DATABASE test_1; diff --git a/mysql-test/suite/atomic/vector_innodb.test b/mysql-test/suite/atomic/vector_innodb.test index 929f845cba50d..50f7271b574b9 100644 --- a/mysql-test/suite/atomic/vector_innodb.test +++ b/mysql-test/suite/atomic/vector_innodb.test @@ -1,3 +1,16 @@ let $skip_vector=1; let $extra_fields=, v vector(5) not null default x'e360d63ebe554f3fcdbc523f4522193f5236083d', vector index(v); --source alter_table_innodb.test + +--echo # +--echo # MDEV-38832 Assertion `!commit_lsn' failed in void trx_t::free() +--echo # +let $MYSQLD_DATADIR= `select @@datadir`; +CREATE DATABASE test_1; +--error ER_SQL_DISCOVER_ERROR +SET STATEMENT max_session_mem_used=8192 FOR +CREATE TABLE test_1.t (a INT,b VECTOR (5) NOT NULL, + VECTOR INDEX (b)) ENGINE=INNODB; +--echo # Print the files exist in test_1 directory +--list_files $MYSQLD_DATADIR/test_1 +DROP DATABASE test_1; diff --git a/sql/handler.cc b/sql/handler.cc index 22de4590067be..2d3b9ceea001f 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -6484,6 +6484,7 @@ static int ha_create_table_from_share(THD *thd, TABLE_SHARE *share, 0 ok @retval 1 error + 2 error while creating high level index failure */ int ha_create_table(THD *thd, const char *path, const char *db, const char *table_name, HA_CREATE_INFO *create_info, @@ -6552,7 +6553,10 @@ int ha_create_table(THD *thd, const char *path, const char *db, } if ((error= share.path.length > sizeof(file_name) - HLINDEX_BUF_LEN)) + { + error= 2; goto err; + } enum_sql_command old_sql_command= thd->lex->sql_command; for (uint i= share.keys; i < share.total_keys; i++) @@ -6569,13 +6573,17 @@ int ha_create_table(THD *thd, const char *path, const char *db, if (error) { index_share.db_plugin= NULL; + error= 2; break; } uint unused; if ((error= ha_create_table_from_share(thd, &index_share, &index_cinfo, &unused))) + { + error= 2; break; + } } thd->lex->sql_command= old_sql_command; free_table_share(&index_share); @@ -6583,7 +6591,7 @@ int ha_create_table(THD *thd, const char *path, const char *db, err: free_table_share(&share); - DBUG_RETURN(error != 0); + DBUG_RETURN(error); } void st_ha_check_opt::init() diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 4c660c3924c05..fe27b91f98f94 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -4932,8 +4932,8 @@ int create_table_impl(THD *thd, if (!frm_only) { debug_crash_here("ddl_log_create_before_create_table"); - if (ha_create_table(thd, path.str, db.str, table_name.str, create_info, - frm, 0)) + if ((error= ha_create_table(thd, path.str, db.str, table_name.str, create_info, + frm, 0))) { file->ha_create_partitioning_metadata(path.str, NULL, CHF_DELETE_FLAG); deletefrm(path.str); @@ -4969,8 +4969,16 @@ int create_table_impl(THD *thd, err: if (unlikely(error) && ddl_log_state_create) { - /* Table was never created, so we can ignore the ddl log entry */ - ddl_log_complete(ddl_log_state_create); + if (error == 2) + { + /* hlindex creation failed, need to revert to clean up main table */ + ddl_log_revert(thd, ddl_log_state_create); + } + else + { + /* Table was never created, so we can ignore the ddl log entry */ + ddl_log_complete(ddl_log_state_create); + } } THD_STAGE_INFO(thd, stage_after_create);