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

rpl.create_or_replace_mix2 fails in MDEV-35915 branch

    XMLWordPrintable

Details

    Description

      The symptom looks like

      rpl.create_or_replace_mix2 'mix'         w5 [ fail ]
              Test ended at 2025-09-17 16:45:27
       
      CURRENT_TEST: rpl.create_or_replace_mix2
      mysqltest: In included file "/home/buildbot/aarch64-centos-stream10/build/mysql-test/suite/rpl/t/create_or_replace.inc": 
      included from /home/buildbot/aarch64-centos-stream10/build/mysql-test/suite/rpl/t/create_or_replace_mix2.test at line 7:
      At line 142: failed in 'select master_pos_wait('master-bin.000001', 4538, 300, '')': 2013: Lost connection to server during query
      ...
      create table t2 select * from t9;
      ...
      sql/opt_hints.cc:939(hint_table_state(THD const*, TABLE_LIST const*, opt_hints_enum, bool))[0xaaaaeb38c500]
      sql/sql_select.cc:2541(JOIN::optimize_inner())[0xaaaaeb21b150]
      sql/sql_select.cc:2023(JOIN::optimize())[0xaaaaeb21bddc]
      sql/sql_select.cc:5388(mysql_select(THD*, TABLE_LIST*, List<Item>&, Item*, unsigned int, st_order*, st_order*, Item*, st_order*, unsigned long long, select_result*, st_select_lex_unit*, st_select_lex*))[0xaaaaeb21bed4]
      sql/sql_select.cc:634(handle_select(THD*, LEX*, select_result*, unsigned long long))[0xaaaaeb21c538]
      sql/sql_table.cc:13952(Sql_cmd_create_table_like::execute(THD*))[0xaaaaeb25854c]
      sql/sql_parse.cc:5861(mysql_execute_command(THD*, bool))[0xaaaaeb1b156c]
      sql/sql_parse.cc:7895(mysql_parse(THD*, char*, unsigned int, Parser_state*))[0xaaaaeb1b50d4]
      sql/log_event_server.cc:2092(Query_log_event::do_apply_event(rpl_group_info*, char const*, unsigned int))[0xaaaaeb53185c]
      sql/log_event.cc:3986(Log_event::apply_event(rpl_group_info*))[0xaaaaeb524e80]
      sql/slave.cc:3615(apply_event_and_update_pos_apply(Log_event*, THD*, rpl_group_info*, int))[0xaaaaeb106df8]
      

      in other words, it crashes in the slave thread here:

      bool hint_table_state(const THD *thd, const TABLE_LIST *table_list,
                            opt_hints_enum type_arg, bool fallback_value)
      {
        if (table_list->opt_hints_qb)
      

      because table_list is NULL. It comes from

      bool hint_table_state(const THD *thd, const TABLE *table,
                                        opt_hints_enum type_arg,
                                        bool fallback_value)
      {
        return hint_table_state(thd, table->pos_in_table_list, type_arg,
                                fallback_value);
      }
      

      And table->pos_in_table_list becomes NULL because of

      @@ -869,6 +953,7 @@ void THD::mark_tmp_table_as_free_for_reuse(TABLE *table)
           table->mark_as_not_binlogged();
         }
       
      +  table->pos_in_table_list= NULL;
         table->query_id= 0;
         table->file->ha_reset();
      

      which was added in

      commit f024fe7885b
      Author: Nikita Malyavin <nikita.malyavin@mariadb.com>
      Date:   Fri Feb 7 01:34:56 2025 +0100
       
          MDEV-35915 Implement Global temporary tables
      

      But this does not look like the actual problem. THD::mark_tmp_table_as_free_for_reuse() is invoked because the offending statement

      CREATE t2 SELECT * FROM t9
      

      is executed as CREATE OR REPLACE, the table t2 exists and create_table_impl() does

            if (options.or_replace())
            {
              (void) delete_statistics_for_table(thd, &db, &table_name);
      

      delete_statistics_for_table() in turn, creates a separate transation, deletes statistics, commits that transaction using

        thd->commit_whole_transaction_and_close_tables();
      

      and restores the original transaction. commit_whole_transaction_and_close_tables() invokes THD::mark_tmp_table_as_free_for_reuse(), which looks certainly wrong here, because the temporary table t9 is definitely not "free for reuse" it'll be used in SELECT part of this very statement.

      Consider the following test case:

      create table t2 (a int);
      create temporary table t9 (a int);
      insert t9 values (1);
      create or replace table t2 select * from t9
      

      The code path is almost the same, but there's no crash here. Because "creating a separate transaction" includes saving and resetting the list of temporary tables in the THD. So THD::mark_tmp_table_as_free_for_reuse() only affects temporary tables in that separate transaction. Specifically,

        start_new_trans new_trans(thd);
      

      does in THD::reset_open_tables_state()

          temporary_tables= 0;
      

      But

      bool THD::has_temporary_tables()
      {
        DBUG_ENTER("THD::has_temporary_tables");
        bool result;
      #ifdef HAVE_REPLICATION
        if (rgi_slave)
        {
          mysql_mutex_lock(&rgi_slave->rli->data_lock);
          result= rgi_slave->rli->save_temporary_tables &&
            !rgi_slave->rli->save_temporary_tables->is_empty();
          mysql_mutex_unlock(&rgi_slave->rli->data_lock);
        }
        else
      #endif
        {
          result= has_thd_temporary_tables();
        }
        DBUG_RETURN(result);
      }
      

      that is, in the slave thread, temporary tables are in rgi_slave->rli->save_temporary_tables, not in thd->temporary_tables. Meaning, on the master, new_trans(thd) correctly saves the state, creates a clean one, and later restores the old state. But on the slave it doesn't.

      That is, perhaps, it has to be fixed not only in GTT branch, but much earlier.

      Attachments

        Issue Links

          Activity

            People

              Elkin Andrei Elkin
              serg Sergei Golubchik
              Votes:
              0 Vote for this issue
              Watchers:
              5 Start watching this issue

              Dates

                Created:
                Updated:

                Git Integration

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