1. 04 Jul, 2023 11 commits
    • Nikita Malyavin's avatar
      add partition test · 07191fb4
      Nikita Malyavin authored
      07191fb4
    • Nikita Malyavin's avatar
      MDEV-30985 Replica stops with error on ALTER ONLINE with Geometry Types · afb459ed
      Nikita Malyavin authored
      The bug is inherent for row-based replication as well.
      To reproduce, a virtual (not stored) field of a blob type computed from
      another field of a different blob type is required.
      
      The following happens during an update or delete row event:
      1. A row is unpacked.
      2. Virtual fields are updated. Field b1 stores the pointer in
         Field_blob::value and references it in table->record[0].
      3. record[0] is stored to record[1] in Rows_log_event::find_row.
      4. A new record is fetched from handler. (e.g. ha_rnd_next)
      5. Virtual columns are updated (only non-stored).
      6. Field b1 receives new value. Old value is deallocated
         (Field_blob::val_str).
      7. record_compare is called. record[0] and record[1] are compared.
      8. record[1] contains a reference to a freed value.
      
      record_compare is used in replication to find a matching record for update
      or delete. Virtual columns that are not stored should be definitely skipped
      both for correctness, and for this bug fix.
      
      STORED virtual columns, on the other hand, may be required and shouldn't be
      skipped. Stored columns are not affected, since they are not updated after
      handler's fetch.
      afb459ed
    • Nikita Malyavin's avatar
      MDEV-30924 Server crashes in MYSQL_LOG::is_open upon ALTER vs FUNCTION · cb4d9286
      Nikita Malyavin authored
      ASAN showed use-after-free in binlog_online_alter_end_trans, during
      running through thd->online_alter_cache_list.
      
      In online_alter_binlog_get_cache_data, new_cache_data was allocated on
      thd->mem_root, in case of autocommit=1, but this mem_root could be freed
      in sp_head::execute, upon using stored functions.
      
      It appears that thd->transaction->mem_root exists even in single-stmt
      transaction mode (i.e autocommit=1), so it can be used in all cases.
      This mem_root will remain valid till the end of transaction, including
      commit phase.
      cb4d9286
    • Nikita Malyavin's avatar
      MDEV-30925 Assertion failed in translog_write_record in ONLINE ALTER + Aria · d1fe3487
      Nikita Malyavin authored
      This is the corner case of ONLINE ALTER vs ha_maria vs App-time Periods.
      
      When a Delete_rows_event (or update) is executed, a lookup handler may be
      created, normally to serve long unique index needs, by a call of
      handler::prepare_for_insert. This function also creates a lookup handler
      if an application-time period exists in a table.
      
      A difference with a usual call of prepare_for_insert is that transactions
      are disabled for this table during ALTER TABLE. See
      mysql_trans_prepare_alter_copy_data call in copy_data_between_tables.
      
      Then, ha_maria calls _ma_tmp_disable_logging_for_table during
      ha_maria::external_lock. It never happened so before, that two handlers
      would be created for write to a single ha_maria table under transactions
      disabled.
      
      Hence, the fix handles this scenario.
      It could be done otherwise, by not creating this lookup handler (since it's
      not used anyway during ONLINE ALTER), but architecturally, two handlers
      should be supported.
      
      Avoiding the creation of lookup handler could be done here additionally,
      but with a cost of slowing down other more generic cases, with an
      additional check of online alter table active.
      d1fe3487
    • Nikita Malyavin's avatar
      MDEV-30902 Server crash in LEX::first_lists_tables_same · dc4e5985
      Nikita Malyavin authored
      ONLINE ALTER TABLE uses binlog events like the replication does.
      
      Before it was never used outside of replication, so significant
      change was required. For example, a single event had a statement-like
      befavior: it locked the tables, opened it, and closed them in the end. But
      for ONLINE ALTER we use preopened table.
      
      A crash scenario is following: lex->query_tables was set to NULL in
      restore_empty_query_table_list when alter event is applied.
      Then lex->query_tables->prev_global was write-accessed in
      LEX::first_lists_tables_same, leading to a segfault.
      
      In replication restore_empty_query_table_list would mean resetting lex
      before next query or event.
      
      In ONLINE ALTER TABLE we reuse a locked table between the events, so
      we should avoid it. Here the need to reset lex state (or close the tables)
      can be determined by nonzero rgi->tables_to_lock_count.
      If no table is locked, then event doesn't own the tables.
      
      The same was already done before for rgi->slave_close_thread_tables call.
      dc4e5985
    • Nikita Malyavin's avatar
    • Nikita Malyavin's avatar
      fix main.alter_table_{online,lock} · 955c700e
      Nikita Malyavin authored
      955c700e
    • Nikita Malyavin's avatar
      MDEV-29069 follow-up: improve DEFAULT rules · f434a196
      Nikita Malyavin authored
      previously, fields with DEFAULTs were allowed just when expression is
      deterministic. In case of online alter, we should recursively check that
      underlying fields of expression also either have explicit values, or
      have DEFAULT following this validity rule.
      f434a196
    • Nikita Malyavin's avatar
      cbe733b6
    • Nikita Malyavin's avatar
      6eaf66f2
    • Nikita Malyavin's avatar
      MDEV-29069 ER_KEY_NOT_FOUND on online autoinc addition + concurrent DELETE · a379d592
      Nikita Malyavin authored
      We can't rely on keys formed with columns that were added during this
      ALTER. These columns can be set with non-deterministic values, which can
      end up with broken or incorrect search.
      
      The same applies to the keys that contain reliable columns, but also have
      bogus ones. Using them can narrow the search, but they're also ignored.
      
      Also, added columns shouldn't be considered during the record match. To
      determine them, table->has_value_set bitmap is used.
      
      To fill has_value_set bitmap in the find_key call, extra unpack_row call
      has been added.
      
      For replication case, extra replica columns can be considered for this
      case. We try to ignore them, too.
      a379d592
  2. 30 Jun, 2023 29 commits