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

Wrong handling of 'table was dropped' error in purge thread

    XMLWordPrintable

    Details

      Description

      There is possibility to get exception:

      #1  0x00007f610fcb2535 in __GI_abort () at abort.c:79
      #2  0x000000000131649a in ib::fatal::~fatal (this=0x7f61000a9b18) at /home/midenok/src/mariadb/10.5b/src/storage/innobase/ut/ut0ut.cc:597
      #3  0x0000000001200172 in row_mysql_handle_errors (new_err=0x7f61000aa574, trx=0x7f610927e130, thr=0x7f609c033cd8, savept=0x7f61000aa578) at /home/midenok/src/mariadb/10.5b/src/storage/innobase/row/row0mysql.cc:790
      #4  0x00000000012049a0 in row_update_for_mysql (prebuilt=0x7f609c032f58) at /home/midenok/src/mariadb/10.5b/src/storage/innobase/row/row0mysql.cc:1908
      #5  0x000000000101474e in ha_innobase::update_row (this=0x7f609c02c000, old_row=0x7f609c026150 "\377\001", new_row=0x7f609c026148 "\377\002") at /home/midenok/src/mariadb/10.5b/src/storage/innobase/handler/ha_innodb.cc:8777
      #6  0x0000000000bf62aa in handler::ha_update_row (this=0x7f609c02c000, old_data=0x7f609c026150 "\377\001", new_data=0x7f609c026148 "\377\002") at /home/midenok/src/mariadb/10.5b/src/sql/handler.cc:6750
      #7  0x000000000097da11 in mysql_update (thd=0x7f609c000d08, table_list=0x7f609c0145f8, fields=..., values=..., conds=0x0, order_num=0, order=0x0, limit=18446744073709551615, ignore=false, found_return=0x7f61000ac118, updated_return=0x7f61000ac110) at /home/midenok/src/mariadb/10.5b/src/sql/sql_update.cc:1046
      #8  0x0000000000843e38 in mysql_execute_command (thd=0x7f609c000d08) at /home/midenok/src/mariadb/10.5b/src/sql/sql_parse.cc:4347
      #9  0x000000000083b410 in mysql_parse (thd=0x7f609c000d08, rawbuf=0x7f609c014520 "update t1 set fld1= 2", length=21, parser_state=0x7f61000ad5c0, is_com_multi=false, is_next_command=false) at /home/midenok/src/mariadb/10.5b/src/sql/sql_parse.cc:7998
      

      on wrongly thrown DB_OUT_OF_MEMORY from:

      #0  innobase_allocate_row_for_vcol (thd=0x7f609c000d08, index=0x7f609c0829a8, heap=0x7f61000a8170, table=0x7f61000a8168, record=0x7f61000a8158, storage=0x7f61000a8160) at /home/midenok/src/mariadb/10.5b/src/storage/innobase/handler/ha_innodb.cc:20860
      #1  0x00000000011d688a in row_ins_foreign_fill_virtual (cascade=0x7f609c02eba8, rec=0x7f6108fc407d "", index=0x7f609c0829a8, node=0x7f609c033a00, foreign=0x7f609c083608, err=0x7f61000a89dc) at /home/midenok/src/mariadb/10.5b/src/storage/innobase/row/row0ins.cc:968
      #2  0x00000000011cc02e in row_ins_foreign_check_on_constraint (thr=0x7f609c033cd8, foreign=0x7f609c083608, pcur=0x7f61000a9550, entry=0x7f609c0280d0, mtr=0x7f61000a9050) at /home/midenok/src/mariadb/10.5b/src/storage/innobase/row/row0ins.cc:1366
      #3  0x00000000011c9bde in row_ins_check_foreign_constraint (check_ref=0, foreign=0x7f609c083608, table=0x7f609c026ee8, entry=0x7f609c0280d0, thr=0x7f609c033cd8) at /home/midenok/src/mariadb/10.5b/src/storage/innobase/row/row0ins.cc:1848
      #4  0x000000000127da44 in row_upd_check_references_constraints (node=0x7f609c033a00, pcur=0x7f609c026c60, table=0x7f609c026ee8, index=0x7f609c02aec8, offsets=0x7f609c080328, thr=0x7f609c033cd8, mtr=0x7f61000a9da0) at /home/midenok/src/mariadb/10.5b/src/storage/innobase/row/row0upd.cc:296
      #5  0x000000000127c794 in row_upd_clust_rec_by_insert (node=0x7f609c033a00, index=0x7f609c02aec8, thr=0x7f609c033cd8, referenced=1, mtr=0x7f61000a9da0) at /home/midenok/src/mariadb/10.5b/src/storage/innobase/row/row0upd.cc:2759
      #6  0x000000000127aa41 in row_upd_clust_step (node=0x7f609c033a00, thr=0x7f609c033cd8) at /home/midenok/src/mariadb/10.5b/src/storage/innobase/row/row0upd.cc:3210
      #7  0x0000000001276b22 in row_upd (node=0x7f609c033a00, thr=0x7f609c033cd8) at /home/midenok/src/mariadb/10.5b/src/storage/innobase/row/row0upd.cc:3289
      #8  0x0000000001276635 in row_upd_step (thr=0x7f609c033cd8) at /home/midenok/src/mariadb/10.5b/src/storage/innobase/row/row0upd.cc:3433
      #9  0x00000000012048e1 in row_update_for_mysql (prebuilt=0x7f609c032f58) at /home/midenok/src/mariadb/10.5b/src/storage/innobase/row/row0mysql.cc:1889
      #10 0x000000000101474e in ha_innobase::update_row (this=0x7f609c02c000, old_row=0x7f609c026150 "\377\001", new_row=0x7f609c026148 "\377\002") at /home/midenok/src/mariadb/10.5b/src/storage/innobase/handler/ha_innodb.cc:8777
      #11 0x0000000000bf62aa in handler::ha_update_row (this=0x7f609c02c000, old_data=0x7f609c026150 "\377\001", new_data=0x7f609c026148 "\377\002") at /home/midenok/src/mariadb/10.5b/src/sql/handler.cc:6750
      #12 0x000000000097da11 in mysql_update (thd=0x7f609c000d08, table_list=0x7f609c0145f8, fields=..., values=..., conds=0x0, order_num=0, order=0x0, limit=18446744073709551615, ignore=false, found_return=0x7f61000ac118, updated_return=0x7f61000ac110) at /home/midenok/src/mariadb/10.5b/src/sql/sql_update.cc:1046
      #13 0x0000000000843e38 in mysql_execute_command (thd=0x7f609c000d08) at /home/midenok/src/mariadb/10.5b/src/sql/sql_parse.cc:4347
      #14 0x000000000083b410 in mysql_parse (thd=0x7f609c000d08, rawbuf=0x7f609c014520 "update t1 set fld1= 2", length=21, parser_state=0x7f61000ad5c0, is_com_multi=false, is_next_command=false) at /home/midenok/src/mariadb/10.5b/src/sql/sql_parse.cc:7998
      

      the code from frame 0 returns error like this:

      20854           if (!*table)
      20855                   *table= innodb_find_table_for_vc(thd, index->table);
      20856   
      20857           /* For purge thread, there is a possiblity that table could have
      20858           dropped, corrupted or unaccessible. */
      20859           if (!*table)
      20860                   return true;
      

      but up in frame 1 it is handled like a memory error:

      968             if (innobase_allocate_row_for_vcol(thd, index, &v_heap,
      969                                                &mysql_table,
      970                                                &record, &vcol_storage)) {
      971                     if (v_heap) mem_heap_free(v_heap);
      972                     *err = DB_OUT_OF_MEMORY;
      973                     goto func_exit;
      974             }
      

      Make proper error handling by allowing innobase_allocate_row_for_vcol() return dberr_t and handle it properly up the stack. This requires to refactor a row of functions which were not supposed to fail with error (?!).

      Handle DB_OUT_OF_MEMORY in row_mysql_handle_errors().

      Affected tests: gcol.innodb_virtual_fk, innodb_zip.bug56680

      More analysis

        Attachments

          Issue Links

            Activity

              People

              Assignee:
              midenok Aleksey Midenkov
              Reporter:
              midenok Aleksey Midenkov
              Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

                Dates

                Created:
                Updated: