Uploaded image for project: 'MariaDB Server'
  1. MariaDB Server
  2. MDEV-31892

Server crash upon moving InnoDB table with fulltext index between databases

    XMLWordPrintable

Details

    • Can result in data loss
    • Q1/2026 Server Development

    Description

      When renaming/moving an InnoDB table with fulltext indexes between databases, the server would crash because InnoDB attempted to open auxiliary tables using the old database name instead of the new one.

      When creating auxiliary index, InnoDB does create temporary sort fulltext index using
      old table reference which creates the auxiliary table name with the prefix of old database name.

      FTS Document ID size optimization in row_merge_create_fts_sort_index() using
      dict_table_get_n_rows() to decide between 4-byte and 8-byte Doc IDs for memory optimization.
      But dict_table_get_n_rows() returns estimated statistics that may be stale or inaccurate,
      potentially leading to wrong size decisions and data corruption if 4-byte Doc IDs are chosen
      when 8-byte are actually needed.

              /* Check whether we can use 4 bytes instead of 8 bytes integer
              field to hold the Doc ID, thus reduce the overall sort size */
              if (DICT_TF2_FLAG_IS_SET(table, DICT_TF2_FTS_ADD_DOC_ID)) {
                      /* If Doc ID column is being added by this create
                      index, then just check the number of rows in the table */
                      if (dict_table_get_n_rows(table) < MAX_DOC_ID_OPT_VAL) {
                              *opt_doc_id_size = TRUE;
                      }
              } else {
                      doc_id_t        max_doc_id;
       
                      /* If the Doc ID column is supplied by user, then
                      check the maximum Doc ID in the table */
                      max_doc_id = fts_get_max_doc_id((dict_table_t*) table);
       
                      if (max_doc_id && max_doc_id < MAX_DOC_ID_OPT_VAL) {
                              *opt_doc_id_size = TRUE;
                      }
              }
      

      --source include/have_innodb.inc
       
      CREATE DATABASE db;
      CREATE TABLE db.t (pk INT PRIMARY KEY, c CHAR(120), FULLTEXT KEY(c)) ENGINE=InnoDB;
      INSERT INTO db.t VALUES (1,'foo'),(2,'bar');
      ALTER TABLE db.t FORCE, RENAME TO test.t;
       
      # Cleanup
      DROP DATABASE db;
      DROP TABLE IF EXISTS test.t;
      

      10.4 e146940a non-debug

      Thread 1 (Thread 0x7f94f7fff6c0 (LWP 1055211)):
      #0  row_fts_merge_insert (index=<optimized out>, table=<optimized out>, psort_info=<optimized out>, id=<optimized out>) at /data/src/10.4/storage/innobase/row/row0ftsort.cc:1668
      #1  0x000055c9363fe431 in fts_parallel_merge (arg=0x7f94f0068318) at /data/src/10.4/storage/innobase/row/row0ftsort.cc:1110
      #2  0x00007f9546fc8fd4 in start_thread (arg=<optimized out>) at ./nptl/pthread_create.c:442
      #3  0x00007f95470495bc in clone3 () at ../sysdeps/unix/sysv/linux/x86_64/clone3.S:81
       
      Thread 30 (Thread 0x7f94f6ffd6c0 (LWP 1055212)):
      #0  0x000055c9364d2ca8 in dict_load_table_one (name=..., ignore_err=ignore_err@entry=DICT_ERR_IGNORE_NONE, fk_tables=std::deque with 0 elements) at /data/src/10.4/storage/innobase/dict/dict0load.cc:2875
      #1  0x000055c9364d4963 in dict_load_table (name=name@entry=0x7f94f6ffcbf0 "db/FTS_", '0' <repeats 14 times>, "20_", '0' <repeats 14 times>, "28_INDEX_3", ignore_err=ignore_err@entry=DICT_ERR_IGNORE_NONE) at /data/src/10.4/storage/innobase/dict/dict0load.cc:2762
      #2  0x000055c9364c87e3 in dict_table_open_on_name (table_name=table_name@entry=0x7f94f6ffcbf0 "db/FTS_", '0' <repeats 14 times>, "20_", '0' <repeats 14 times>, "28_INDEX_3", dict_locked=dict_locked@entry=0, try_drop=try_drop@entry=0, ignore_err=ignore_err@entry=DICT_ERR_IGNORE_NONE) at /data/src/10.4/storage/innobase/dict/dict0dict.cc:889
      #3  0x000055c9363fd61b in row_fts_merge_insert (index=<optimized out>, table=<optimized out>, psort_info=<optimized out>, id=<optimized out>) at /data/src/10.4/storage/innobase/row/row0ftsort.cc:1665
      #4  0x000055c9363fe431 in fts_parallel_merge (arg=0x7f94f00684c0) at /data/src/10.4/storage/innobase/row/row0ftsort.cc:1110
      #5  0x00007f9546fc8fd4 in start_thread (arg=<optimized out>) at ./nptl/pthread_create.c:442
      #6  0x00007f95470495bc in clone3 () at ../sysdeps/unix/sysv/linux/x86_64/clone3.S:81
       
      Thread 31 (Thread 0x7f95401356c0 (LWP 1055205)):
      #0  __pthread_create_2_1 (newthread=<optimized out>, attr=<optimized out>, start_routine=<optimized out>, arg=<optimized out>) at ./nptl/pthread_create.c:775
      #1  0x000055c9363dd820 in os_thread_create_func (func=func@entry=0x55c9363fe410 <fts_parallel_merge(void*)>, arg=arg@entry=0x7f94f00689b8, thread_id=thread_id@entry=0x7f94f0068b18) at /data/src/10.4/storage/innobase/os/os0thread.cc:138
      #2  0x000055c9363fb7db in row_fts_start_parallel_merge (merge_info=<optimized out>) at /data/src/10.4/storage/innobase/row/row0ftsort.cc:1137
      #3  0x000055c936417126 in row_merge_build_indexes (trx=0x7f9540bcd090, old_table=0x7f94f0082218, new_table=0x7f94f0041918, online=online@entry=false, indexes=0x7f94f004dc98, key_numbers=0x7f94f004dcb0, n_indexes=3, table=0x7f9540130a10, defaults=0x0, col_map=0x7f94f004dd48, add_autoinc=18446744073709551615, sequence=..., skip_pk_sort=true, stage=0x7f94f0056200, add_v=0x0, eval_table=0x7f9540130a10, allow_not_null=false) at /data/src/10.4/storage/innobase/row/row0merge.cc:4747
      #4  0x000055c93639703c in ha_innobase::inplace_alter_table (this=0x7f94f0125200, altered_table=0x7f9540130a10, ha_alter_info=0x7f9540130970) at /data/src/10.4/storage/innobase/handler/handler0alter.cc:8728
      #5  0x000055c935fc3a10 in handler::ha_inplace_alter_table (ha_alter_info=0x7f9540130970, altered_table=0x7f9540130a10, this=<optimized out>) at /data/src/10.4/sql/handler.h:4355
      #6  mysql_inplace_alter_table (target_mdl_request=0x7f9540131800, alter_ctx=0x7f9540132940, ha_alter_info=0x7f9540130970, altered_table=0x7f9540130a10, table=0x7f94f007bf88, table_list=0x7f94f0010210, thd=0x7f94f0000c58) at /data/src/10.4/sql/sql_table.cc:7918
      #7  mysql_alter_table (thd=thd@entry=0x7f94f0000c58, new_db=new_db@entry=0x7f94f00052a0, new_name=new_name@entry=0x7f94f00056f8, create_info=create_info@entry=0x7f9540133520, table_list=<optimized out>, table_list@entry=0x7f94f0010210, recreate_info=recreate_info@entry=0x7f9540133440, alter_info=0x7f9540133460, order_num=0, order=0x0, ignore=false) at /data/src/10.4/sql/sql_table.cc:10446
      #8  0x000055c936016fd4 in Sql_cmd_alter_table::execute (this=<optimized out>, thd=0x7f94f0000c58) at /data/src/10.4/sql/sql_alter.cc:531
      #9  0x000055c935f2589f in mysql_execute_command (thd=thd@entry=0x7f94f0000c58) at /data/src/10.4/sql/sql_parse.cc:6216
      #10 0x000055c935f2a3d0 in mysql_parse (thd=thd@entry=0x7f94f0000c58, rawbuf=<optimized out>, length=40, parser_state=parser_state@entry=0x7f9540134540, is_com_multi=is_com_multi@entry=false, is_next_command=<optimized out>) at /data/src/10.4/sql/sql_parse.cc:8008
      #11 0x000055c935f2c095 in dispatch_command (command=command@entry=COM_QUERY, thd=thd@entry=0x7f94f0000c58, packet=packet@entry=0x7f94f0007d69 "ALTER TABLE db.t FORCE, RENAME TO test.t", packet_length=packet_length@entry=40, is_com_multi=is_com_multi@entry=false, is_next_command=is_next_command@entry=false) at /data/src/10.4/sql/sql_parse.cc:1857
      #12 0x000055c935f2db98 in do_command (thd=0x7f94f0000c58) at /data/src/10.4/sql/sql_parse.cc:1378
      #13 0x000055c936012ea4 in do_handle_one_connection (connect=connect@entry=0x55c939b688c8) at /data/src/10.4/sql/sql_connect.cc:1420
      #14 0x000055c936012ff4 in handle_one_connection (arg=arg@entry=0x55c939b688c8) at /data/src/10.4/sql/sql_connect.cc:1324
      #15 0x000055c936331b60 in pfs_spawn_thread (arg=0x55c939887c68) at /data/src/10.4/storage/perfschema/pfs.cc:1869
      #16 0x00007f9546fc8fd4 in start_thread (arg=<optimized out>) at ./nptl/pthread_create.c:442
      #17 0x00007f95470495bc in clone3 () at ../sysdeps/unix/sysv/linux/x86_64/clone3.S:81
      

      10.4 b54e4bf0 debug

      mysqld: /data/src/10.4/storage/innobase/row/row0ftsort.cc:1667: dberr_t row_fts_merge_insert(dict_index_t*, dict_table_t*, fts_psort_t*, ulint): Assertion `aux_table != __null' failed.
      230810 15:45:51 [ERROR] mysqld got signal 6 ;
       
      , line=1667, function=0x55962a301200 "dberr_t row_fts_merge_insert(dict_index_t*, dict_table_t*, fts_psort_t*, ulint)") at ./assert/assert.c:101
      #6  0x0000559628ff7efc in row_fts_merge_insert (index=0x61700004ed08, table=0x61800003d108, psort_info=0x6190000f1480, id=3) at /data/src/10.4/storage/innobase/row/row0ftsort.cc:1667
      #7  0x0000559628ff4e86 in fts_parallel_merge (arg=0x61f0000148b0) at /data/src/10.4/storage/innobase/row/row0ftsort.cc:1110
      #8  0x00007fe3bc6a7fd4 in start_thread (arg=<optimized out>) at ./nptl/pthread_create.c:442
      #9  0x00007fe3bc7285bc in clone3 () at ../sysdeps/unix/sysv/linux/x86_64/clone3.S:81
      

      Reproducible on all existing versions, also on previous minor releases.

      Attachments

        Activity

          People

            thiru Thirunarayanan Balathandayuthapani
            elenst Elena Stepanova
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Git Integration

                Error rendering 'com.xiplink.jira.git.jira_git_plugin:git-issue-webpanel'. Please contact your Jira administrators.