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

InnoDB crash on table-rebuilding DDL when the statistics tables are corrupted

    XMLWordPrintable

Details

    Description

      An upgrade test related to MDEV-25004 triggered the following:

      2022-12-15 15:22:32 3 [ERROR] InnoDB: Table `mysql`.`innodb_index_stats` is corrupted. Please drop the table and recreate.
      2022-12-15 15:22:32 3 [ERROR] InnoDB: Table `mysql`.`innodb_table_stats` is corrupted. Please drop the table and recreate.
      2022-12-15 15:22:32 0x7f999f7686c0  InnoDB: Assertion failure in file /mariadb/10.6m/storage/innobase/pars/pars0pars.cc line 771
      InnoDB: Failing assertion: sym_node->table != NULL
      

      The server had been started up with a subset of a 10.3 data directory. According to the InnoDB data dictionary, the statistics tables exist, but the .ibd files for them had been omitted. After MDEV-13542 was fixed, InnoDB is not expected to crash on any corruption, but it did here:

      #4  0x000055bb9490ce23 in ut_dbg_assertion_failed (
          expr=expr@entry=0x55bb910ed760 "sym_node->table != NULL", 
          file=file@entry=0x55bb910ec7e0 "/mariadb/10.6m/storage/innobase/pars/pars0pars.cc", line=line@entry=771) at /mariadb/10.6m/storage/innobase/ut/ut0dbg.cc:60
      #5  0x000055bb9460a356 in pars_retrieve_table_def (
          sym_node=sym_node@entry=0x629000c174d0)
          at /mariadb/10.6m/storage/innobase/pars/pars0pars.cc:771
      #6  0x000055bb946117c7 in pars_update_statement (node=0x629000c175d8, 
          cursor_sym=cursor_sym@entry=0x0, 
          search_cond=search_cond@entry=0x629000c17ba8)
          at /mariadb/10.6m/storage/innobase/pars/pars0pars.cc:1182
      #7  0x000055bb94617596 in yyparse () at /dev/shm/10.6mu/pars0grm.y:372
      #8  0x000055bb9460ee6b in pars_sql (info=info@entry=0x61700012fb20, 
          str=str@entry=0x55bb91031680 "PROCEDURE DELETE_FROM_TABLE_STATS () IS\nBEGIN\nDELETE FROM \"mysql/innodb_table_stats\" WHERE\ndatabase_name = :database_name AND\ntable_name = :table_name;\nEND;\n")
          at /mariadb/10.6m/storage/innobase/pars/pars0pars.cc:1986
      #9  0x000055bb94632227 in que_eval_sql (info=info@entry=0x61700012fb20, 
          sql=sql@entry=0x55bb91031680 "PROCEDURE DELETE_FROM_TABLE_STATS () IS\nBEGIN\nDELETE FROM \"mysql/innodb_table_stats\" WHERE\ndatabase_name = :database_name AND\ntable_name = :table_name;\nEND;\n", trx=trx@entry=0x7f99a5aefe40)
          at /mariadb/10.6m/storage/innobase/que/que0que.cc:705
      #10 0x000055bb94230804 in dict_stats_exec_sql (
          pinfo=pinfo@entry=0x61700012fb20, 
          sql=sql@entry=0x55bb91031680 "PROCEDURE DELETE_FROM_TABLE_STATS () IS\nBEGIN\nDELETE FROM \"mysql/innodb_table_stats\" WHERE\ndatabase_name = :database_name AND\ntable_name = :table_name;\nEND;\n", trx=trx@entry=0x7f99a5aefe40)
          at /mariadb/10.6m/storage/innobase/dict/dict0stats.cc:532
      #11 0x000055bb94230934 in dict_stats_delete_from_table_stats (
          database_name=database_name@entry=0x7f999f762330 "test", 
          table_name=table_name@entry=0x7f999f762440 "articles2", 
          trx=trx@entry=0x7f99a5aefe40)
          at /mariadb/10.6m/storage/innobase/dict/dict0stats.cc:4244
      #12 0x000055bb942a782d in trx_t::drop_table_statistics (
          this=this@entry=0x7f99a5aefe40, 
            name=@0x7f999f762600: {m_name = 0x61e000056620 "test/articles2"})
          at /mariadb/10.6m/storage/innobase/dict/drop.cc:133
      #13 0x000055bb943dfee4 in commit_try_rebuild (
          ha_alter_info=ha_alter_info@entry=0x7f999f763820, 
          ctx=ctx@entry=0x62b0000c6830, 
          altered_table=altered_table@entry=0x7f999f7643a0, 
          old_table=old_table@entry=0x6190000ca898, trx=trx@entry=0x7f99a5aefe40, 
          table_name=table_name@entry=0x61b00010a655 "articles2")
          at /mariadb/10.6m/storage/innobase/handler/handler0alter.cc:10191
      

      I tried but failed to create a simple test case of this. The fix is simple: avoid the call when the statistics tables could not be opened.

      diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc
      index f91c0a23c08..dd83ed49af0 100644
      --- a/storage/innobase/handler/handler0alter.cc
      +++ b/storage/innobase/handler/handler0alter.cc
      @@ -10101,6 +10101,7 @@ commit_try_rebuild(
       	ha_innobase_inplace_ctx*ctx,
       	TABLE*			altered_table,
       	const TABLE*		old_table,
      +	bool			statistics_exist,
       	trx_t*			trx,
       	const char*		table_name)
       {
      @@ -10171,7 +10172,9 @@ commit_try_rebuild(
       		if (error == DB_SUCCESS) {
       			/* The statistics for the surviving indexes will be
       			re-inserted in alter_stats_rebuild(). */
      -			error = trx->drop_table_statistics(old_name);
      +			if (statistics_exist) {
      +				error = trx->drop_table_statistics(old_name);
      +			}
       			if (error == DB_SUCCESS) {
       				error = trx->drop_table(*user_table);
       			}
      @@ -11316,6 +11319,7 @@ ha_innobase::commit_inplace_alter_table(
       
       			if (commit_try_rebuild(ha_alter_info, ctx,
       					       altered_table, table,
      +					       table_stats && index_stats,
       					       trx,
       					       table_share->table_name.str)) {
       				goto fail;
      

      On TRUNCATE TABLE, a corresponding check was already in place:

          if (err == DB_SUCCESS && table_stats && index_stats)
            err= trx->drop_table_statistics(table->name);
      

      Attachments

        Issue Links

          Activity

            People

              marko Marko Mäkelä
              marko Marko Mäkelä
              Votes:
              0 Vote for this issue
              Watchers:
              1 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.