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

join_init_read_record() wrongly issues HA_ERR_OUT_OF_MEM

    XMLWordPrintable

Details

    • Bug
    • Status: Confirmed (View Workflow)
    • Major
    • Resolution: Unresolved
    • 10.5
    • 10.5
    • Optimizer
    • None

    Description

      1. The following code reports HA_ERR_OUT_OF_MEM even if tab->select->quick->reset() returns meaningful error code.

        int join_init_read_record(JOIN_TAB *tab)                                        
        {                                                                               
        ...                                                                             
          if (tab->select && tab->select->quick && tab->select->quick->reset())         
          {                                                                             
            /* Ensures error status is propagated back to client */                     
            report_error(tab->table,                                                    
                         tab->join->thd->killed ? HA_ERR_QUERY_INTERRUPTED : HA_ERR_OUT_OF_MEM);
            return 1;                                                                   
          }                                                                             
        ...                                                                             
        }
        

      The case I analysed is the following.
      In the following stack trace row_merge_is_index_usable() returns false.

      #0  row_merge_is_index_usable (trx=0x3d872403d218, index=0x68c324040588) at /data/MDEV-24035/10.5-MDEV-25163-OOM-debug/storage/innobase/row/row0merge.cc:4299
      #1  0x00005653842cc4ad in ha_innobase::change_active_index (this=0x4d38000b8c60, keynr=2) at /data/MDEV-24035/10.5-MDEV-25163-OOM-debug/storage/innobase/handler/ha_innodb.cc:9036
      #2  0x000056538418f555 in handler::ha_index_init (sorted=true, idx=2, this=0x4d38000b8c60) at /data/MDEV-24035/10.5-MDEV-25163-OOM-debug/sql/opt_range.cc:12644
      #3  QUICK_RANGE_SELECT::reset (this=0x2bdb3c08a640) at /data/MDEV-24035/10.5-MDEV-25163-OOM-debug/sql/opt_range.cc:12614
      #4  0x0000565383eb6585 in join_init_read_record (tab=0x7d0c680128e0) at /data/MDEV-24035/10.5-MDEV-25163-OOM-debug/sql/sql_select.cc:22140
      #5  join_init_read_record (tab=0x7d0c680128e0) at /data/MDEV-24035/10.5-MDEV-25163-OOM-debug/sql/sql_select.cc:22123
      #6  0x0000565383ea0d1a in sub_select (join=0x7d0c680109c8, join_tab=0x7d0c680128e0, end_of_records=<optimized out>)
          at /data/MDEV-24035/10.5-MDEV-25163-OOM-debug/sql/sql_select.cc:21189
      

      Then, ha_innobase::change_active_index() converts it to HA_ERR_TABLE_DEF_CHANGED:

      int                                                                             
      ha_innobase::change_active_index(...)                                           
      {                                                                               
      ...                                                                             
              m_prebuilt->index_usable = row_merge_is_index_usable(                   
                      m_prebuilt->trx, m_prebuilt->index);                            
                                                                                      
              if (!m_prebuilt->index_usable) {                                        
                      if (m_prebuilt->index->is_corrupted()) {                        
      ...                                                                             
                      } else {                                                        
                              push_warning_printf(                                    
                                      m_user_thd, Sql_condition::WARN_LEVEL_WARN,     
                                      HA_ERR_TABLE_DEF_CHANGED,                       
                                      "InnoDB: insufficient history for index %u",    
                                      keynr);                                         
                      }                                                               
                                                                                      
                      /* The caller seems to ignore this.  Thus, we must check        
                      this again in row_search_for_mysql(). */                        
                      DBUG_RETURN(convert_error_code_to_mysql(DB_MISSING_HISTORY,     
                                      0, NULL));                                      
              }                                                                       
      ...                                                                             
      }                                                                               
                                                                                      
      static int                                                                      
      convert_error_code_to_mysql(...)                                                
      {                                                                               
              switch (error) {                                                        
              ...                                                                     
              case DB_MISSING_HISTORY:                                                
                      return(HA_ERR_TABLE_DEF_CHANGED);                               
              ...                                                                     
              }                                                                       
      ...                                                                             
      }
      

      QUICK_RANGE_SELECT::reset() returns it to join_init_read_record(). But join_init_read_record() interprets the returned value as boolean and emits HA_ERR_OUT_OF_MEM for any errors except HA_ERR_QUERY_INTERRUPTED.

      Possible fix: if returned value of tab->select->quick->reset() is not null, return it instead of HA_ERR_OUT_OF_MEM.

      Attachments

        Issue Links

          Activity

            People

              psergei Sergei Petrunia
              vlad.lesin Vladislav Lesin
              Votes:
              0 Vote for this issue
              Watchers:
              4 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.