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

Virtual column value not available during purge

    XMLWordPrintable

Details

    Description

      With the following patch applied, the test gcol.innodb_virtual_debug_purge would crash in purge:

      diff --git a/storage/innobase/row/row0row.cc b/storage/innobase/row/row0row.cc
      index ad4991fb4e9..80513f7223e 100644
      --- a/storage/innobase/row/row0row.cc
      +++ b/storage/innobase/row/row0row.cc
      @@ -127,6 +127,7 @@ row_build_index_entry_low(
       
       			ut_ad(dfield_is_null(dfield2) ||
       			      dfield_get_len(dfield2) == 0 || dfield2->data);
      +			ut_ad(dfield2->type.mtype != DATA_MISSING);
       		} else {
       			dfield2 = dtuple_get_nth_field(row, col_no);
       			ut_ad(dfield_get_type(dfield2)->mtype == DATA_MISSING
      

      10.2 af6077b5358198384eb873ce26f88e7a7ecfe106

      #8  0x000056493cb05ca4 in row_build_index_entry_low (row=0x7fb5c400aa00, 
          ext=0x0, index=0x7fb598040a58, heap=0x7fb5c4008890, flag=1)
          at /mariadb/10.2/storage/innobase/row/row0row.cc:130
      #9  0x000056493caffbbc in row_purge_del_mark (node=0x56493ed4d0f8)
          at /mariadb/10.2/storage/innobase/row/row0purge.cc:788
      #10 0x000056493cb00826 in row_purge_record_func (node=0x56493ed4d0f8, 
          undo_rec=0x56493ed4d6a8 "", thr=0x56493ed4cf40, updated_extern=false)
          at /mariadb/10.2/storage/innobase/row/row0purge.cc:1102
      Thread 11 (Thread 0x7fb5ebfff700 (LWP 29131)):
      #6  0x000056493c56a7e2 in debug_sync (thd=0x7fb598000cf8, 
          sync_point_name=0x56493d0bf389 "inplace_after_index_build", name_len=25)
          at /mariadb/10.2/sql/debug_sync.cc:1552
      #7  0x000056493c9e1ede in ha_innobase::inplace_alter_table (
          this=0x7fb59807ffb0, altered_table=0x7fb5980f41e8, 
          ha_alter_info=0x7fb5ebffb5a0)
          at /mariadb/10.2/storage/innobase/handler/handler0alter.cc:6532
      #8  0x000056493c61089d in handler::ha_inplace_alter_table (this=
          0x7fb59807ffb0, altered_table=0x7fb5980f41e8, 
          ha_alter_info=0x7fb5ebffb5a0) at /mariadb/10.2/sql/handler.h:3783
      #9  0x000056493c6071a7 in mysql_inplace_alter_table (thd=0x7fb598000cf8, 
          table_list=0x7fb598011838, table=0x7fb598059668, 
          altered_table=0x7fb5980f41e8, ha_alter_info=0x7fb5ebffb5a0, 
          inplace_supported=HA_ALTER_INPLACE_NO_LOCK_AFTER_PREPARE, 
          target_mdl_request=0x7fb5ebffb610, alter_ctx=0x7fb5ebffc1d0)
          at /mariadb/10.2/sql/sql_table.cc:7365
      #10 0x000056493c60c7c8 in mysql_alter_table (thd=0x7fb598000cf8, 
          new_db=0x7fb598011e48 "test", new_name=0x0, create_info=0x7fb5ebffcdf0, 
          table_list=0x7fb598011838, alter_info=0x7fb5ebffcd40, order_num=0, 
          order=0x0, ignore=false) at /mariadb/10.2/sql/sql_table.cc:9390
      #11 0x000056493c6844f7 in Sql_cmd_alter_table::execute (this=0x7fb598011f28, 
          thd=0x7fb598000cf8) at /mariadb/10.2/sql/sql_alter.cc:323
      #12 0x000056493c542078 in mysql_execute_command (thd=0x7fb598000cf8)
          at /mariadb/10.2/sql/sql_parse.cc:6225
      #13 0x000056493c54709e in mysql_parse (thd=0x7fb598000cf8, 
          rawbuf=0x7fb598011710 "ALTER TABLE t1 ADD INDEX idx (c), ALGORITHM=INPLACE, LOCK=NONE", length=62, parser_state=0x7fb5ebffe1b0, is_com_multi=false, 
          is_next_command=false) at /mariadb/10.2/sql/sql_parse.cc:8011
      

      This seems related to a MySQL 5.7 bug fix that worked around a similar issue by introducing the function row_purge_skip_uncommitted_virtual_index(). In this case, the ALTER TABLE has already completed the index creation inside InnoDB, but the metadata change has not been committed. The following assertion appears to be valid:

      diff --git a/storage/innobase/row/row0row.cc b/storage/innobase/row/row0row.cc
      index ad4991fb4e9..3f4308d4bed 100644
      --- a/storage/innobase/row/row0row.cc
      +++ b/storage/innobase/row/row0row.cc
      @@ -127,6 +127,8 @@ row_build_index_entry_low(
       
       			ut_ad(dfield_is_null(dfield2) ||
       			      dfield_get_len(dfield2) == 0 || dfield2->data);
      +			ut_ad(dfield2->type.mtype != DATA_MISSING
      +			      || !index->is_committed());
       		} else {
       			dfield2 = dtuple_get_nth_field(row, col_no);
       			ut_ad(dfield_get_type(dfield2)->mtype == DATA_MISSING
      

      As noted in MDEV-11657, a better approach would be to write each key to the undo log record explicitly. Then purge and rollback should avoid evaluating any virtual columns.

      Attachments

        Issue Links

          Activity

            People

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