1. 02 Sep, 2020 2 commits
    • Thirunarayanan Balathandayuthapani's avatar
      MDEV-23470 InnoDB: Failing assertion: cmp < 0 in row_ins_check_foreign_constraint · 837bbbaf
      Thirunarayanan Balathandayuthapani authored
      During insertion of clustered index, InnoDB does the check for foreign key
      constraints. Problem is that it uses the clustered index entry to search
      indexes of referenced tables and it could lead to unexpected result
      when there is no foreign index.
      
      Solution:
      ========
        Rebuild the tuple based on foreign column names before searching it
      on reference index when there is no foreign index.
      837bbbaf
    • Daniel Black's avatar
      innodb: osx build failure fix · 054f96ec
      Daniel Black authored
      Build failure was:
      storage/innobase/os/os0proc.cc:144:3: error: use of undeclared identifier 'MEM_UNDEFINED'
      
                      MEM_UNDEFINED(ptr, size);
      
      Assumed to be introduced in MDEV-20377
      commit: c36834c8
      054f96ec
  2. 01 Sep, 2020 6 commits
  3. 31 Aug, 2020 3 commits
    • Andrei Elkin's avatar
      MDEV-16372 ER_BASE64_DECODE_ERROR upon replaying binary log via mysqlbinlog --verbose · feac078f
      Andrei Elkin authored
      (This commit is exclusively for 10.1 branch, do not merge it to upper ones)
      
      In case of a pattern of non-STMT_END-marked Rows-log-event (A) followed by
      a STMT_END marked one (B) mysqlbinlog mixes up the base64 encoded rows events
      with their pseudo sql representation produced by the verbose option:
            BINLOG '
              base64 encoded data for A
              ### verbose section for A
              base64 encoded data for B
              ### verbose section for B
            '/*!*/;
      In effect the produced BINLOG '...' query is not valid and is rejected with the error.
      Examples of this way malformed BINLOG could have been found in binlog_row_annotate.result
      that gets corrected with the patch.
      
      The issue is fixed with introduction an auxiliary IO_CACHE to hold on the verbose
      comments until the terminal STMT_END event is found. The new cache is emptied
      out after two pre-existing ones are done at that time.
      The correctly produced output now for the above case is as the following:
            BINLOG '
              base64 encoded data for A
              base64 encoded data for B
            '/*!*/;
              ### verbose section for A
              ### verbose section for B
      
      Thanks to Alexey Midenkov for the problem recognition and attempt to tackle,
      Venkatesh Duggirala who produced a patch for the upstream whose
      idea is exploited here, as well as to MDEV-23077 reporter LukeXwang who
      also contributed a piece of a patch aiming at this issue.
      
      Extra: mysqlbinlog_row_minimal refined to not produce mutable numeric values into the result file.
      feac078f
    • Andrei Elkin's avatar
      MDEV-16372 ER_BASE64_DECODE_ERROR upon replaying binary log via mysqlbinlog --verbose · 6112a0f9
      Andrei Elkin authored
      (This commit is exclusively for 10.2 branch. Do not merge it to 10.3)
      
      In case of a pattern of non-STMT_END-marked Rows-log-event (A) followed by
      a STMT_END marked one (B) mysqlbinlog mixes up the base64 encoded rows events
      with their pseudo sql representation produced by the verbose option:
            BINLOG '
              base64 encoded data for A
              ### verbose section for A
              base64 encoded data for B
              ### verbose section for B
            '/*!*/;
      In effect the produced BINLOG '...' query is not valid and is rejected with the error.
      Examples of this way malformed BINLOG could have been found in binlog_row_annotate.result
      that gets corrected with the patch.
      
      The issue is fixed with introduction an auxiliary IO_CACHE to hold on the verbose
      comments until the terminal STMT_END event is found. The new cache is emptied
      out after two pre-existing ones are done at that time.
      The correctly produced output now for the above case is as the following:
            BINLOG '
              base64 encoded data for A
              base64 encoded data for B
            '/*!*/;
              ### verbose section for A
              ### verbose section for B
      
      Thanks to Alexey Midenkov for the problem recognition and attempt to tackle,
      and to Venkatesh Duggirala who produced a patch for the upstream whose
      idea is exploited here, as well as to MDEV-23077 reporter LukeXwang who
      also contributed a piece of a patch aiming at this issue.
      6112a0f9
    • Eugene Kosov's avatar
      fix clang build · 9bb17ecf
      Eugene Kosov authored
      FAILED: sql/CMakeFiles/sql.dir/sql_test.cc.o
      /home/kevgs/bin/clang++ -DHAVE_CONFIG_H -DHAVE_EVENT_SCHEDULER -DHAVE_POOL_OF_THREADS -DMYSQL_SERVER -D_FILE_OFFSET_BITS=64 -Iinclude -I../include -I../sql -Ipcre -I../pcre -I../zlib -Izlib -I../extra/yassl/include -I../extra/yassl/taocrypt/include -Isql -I../wsrep -O2 -fdiagnostics-color=always -fno-omit-frame-pointer -gsplit-dwarf -march=native -mtune=native -fPIC -fno-rtti -g -DENABLED_DEBUG_SYNC -ggdb3 -DSAFE_MUTEX -Wall -Wdeclaration-after-statement -Wextra -Wformat-security -Wno-init-self -Wno-null-conversion -Wno-unused-parameter -Wno-unused-private-field -Woverloaded-virtual -Wvla -Wwrite-strings -Werror   -DHAVE_YASSL -DYASSL_PREFIX -DHAVE_OPENSSL -DMULTI_THREADED -MD -MT sql/CMakeFiles/sql.dir/sql_test.cc.o -MF sql/CMakeFiles/sql.dir/sql_test.cc.o.d -o sql/CMakeFiles/sql.dir/sql_test.cc.o -c ../sql/sql_test.cc
      ../sql/sql_test.cc:390:20: error: '::' and '*' tokens forming pointer to member type are separated by whitespace [-Werror,-Wcompound-token-split-by-space]
      Item* (List<Item>:: *dbug_list_item_elem_ptr)(int)= &List<Item>::elem;
                       ~~^~
      ../sql/sql_test.cc:391:32: error: '::' and '*' tokens forming pointer to member type are separated by whitespace [-Werror,-Wcompound-token-split-by-space]
      Item_equal* (List<Item_equal>:: *dbug_list_item_equal_elem_ptr)(int)=
                                   ~~^~
      ../sql/sql_test.cc:393:32: error: '::' and '*' tokens forming pointer to member type are separated by whitespace [-Werror,-Wcompound-token-split-by-space]
      TABLE_LIST* (List<TABLE_LIST>:: *dbug_list_table_list_elem_ptr)(int) =
                                   ~~^~
      3 errors generated.
      9bb17ecf
  4. 28 Aug, 2020 3 commits
    • Jan Lindström's avatar
      MDEV-21578 : CREATE OR REPLACE TRIGGER in Galera cluster not replicating · c710c450
      Jan Lindström authored
      While doing TOI buffer OR REPLACE option was not added to replicated
      string.
      c710c450
    • sjaakola's avatar
      MDEV-23557 Galera heap-buffer-overflow in wsrep_rec_get_foreign_key · df07ea0b
      sjaakola authored
      This commit contains a fix and extended test case for a ASAN failure
      reported during galera.fk mtr testing.
      The reported heap buffer overflow happens in test case where a cascading
      foreign key constraint is defined for a column of varchar type, and
      galera.fk.test has such vulnerable test scenario.
      
      Troubleshoting revealed that erlier fix for MDEV-19660 has made a fix
      for cascading delete handling to append wsrep keys from pcur->old_rec,
      in row_ins_foreign_check_on_constraint(). And, the ASAN failuer comes from
      later scanning of this old_rec reference.
      
      The fix in this commit, moves the call for wsrep_append_foreign_key() to happen
      somewhat earlier, and inside ongoing mtr, and using clust_rec which is set
      earlier in the same mtr for both update and delete cascade operations.
      for wsrep key populating, it does not matter when the keys are populated,
      all keys just have to be appended before wsrep transaction replicates.
      
      Note that I also tried similar fix for earlier wsrep key append, but using
      the old implementation with pcur->old_rec (instead of clust_rec), and same
      ASAN failure was reported. So it appears that pcur->old_rec is not properly
      set, to be used for wsrep key appending.
      
      galera.galera_fk_cascade_delete test has been extended by two new test scenarios:
      * FK cascade on varchar column.
        This test case reproduces same scenario as galera.fk, and this test scenario
        will also trigger ASAN failure with non fixed MariaDB versions.
      * multi-master conflict with FK cascading.
        this scenario causes a conflict between a replicated FK cascading transaction
        and local transaction trying to modify the cascaded child table row.
        Local transaction should be aborted and get deadlock error.
        This test scenario is passing both with old MariaDB version and with this
        commit as well.
      df07ea0b
    • Jan Lindström's avatar
  5. 27 Aug, 2020 9 commits
  6. 26 Aug, 2020 1 commit
  7. 25 Aug, 2020 5 commits
    • Sergei Golubchik's avatar
      MDEV-23569 temporary tables can overwrite existing files · 62d1e3bf
      Sergei Golubchik authored
      for internal temporary tables: don't use realpath(),
      and let them overwrite whatever orphan temp files might've
      left in the tmpdir (see main.error_simulation test).
      
      for user created temporary tables: we have to use realpath(),
      (see 3a726ab6, remember DATA/INDEX DIRECTORY). don't allow
      them to overwrite existing files.
      
      This bug was reported by RACK911 LABS
      62d1e3bf
    • Marko Mäkelä's avatar
      MDEV-23547 InnoDB: Failing assertion: *len in row_upd_ext_fetch · 8cf8ad86
      Marko Mäkelä authored
      This bug was originally repeated on 10.4 after defining a UNIQUE KEY
      on a TEXT column, which is implemented by MDEV-371 by creating the
      index on a hidden virtual column.
      
      While row_vers_vc_matches_cluster() is executing in a purge thread
      to find out if an index entry may be removed in a secondary index
      that comprises a virtual column, another purge thread may process
      the undo log record that this check is interested in, and write
      a null BLOB pointer in that record. This would trip the assertion.
      
      To prevent this from occurring, we must propagate the 'missing BLOB'
      error up the call stack.
      
      row_upd_ext_fetch(): Return NULL when the error occurs.
      
      row_upd_index_replace_new_col_val(): Return whether the previous
      version was built successfully.
      
      row_upd_index_replace_new_col_vals_index_pos(): Check the error
      result. Yes, we would intentionally crash on this error if it
      occurs outside the purge thread.
      
      row_upd_index_replace_new_col_vals(): Check for the error condition,
      and simplify the logic.
      
      trx_undo_prev_version_build(): Check for the error condition.
      8cf8ad86
    • Marko Mäkelä's avatar
    • Jan Lindström's avatar
      MDEV-23483: Set Galera SST thd as system thread · 0be70a1b
      Jan Lindström authored
      Revert change to MDL and set SST donor thread as a system thread.
      Joiner thread was already a system thread.
      0be70a1b
    • Aleksey Midenkov's avatar
      MDEV-23554 Wrong default value for foreign_key_checks variable · 6fa40b85
      Aleksey Midenkov authored
      Sys_var_bit::session_save_default() ignored reverse_semantics property.
      6fa40b85
  8. 24 Aug, 2020 1 commit
  9. 21 Aug, 2020 4 commits
    • Marko Mäkelä's avatar
      MDEV-22782 AddressSanitizer race condition in trx_free() · f3160ee4
      Marko Mäkelä authored
      In trx_free() we used to declare the entire trx_t unaccessible
      and then declare that some data members are accessible.
      This involves a race condition with other threads that may concurrently
      access the data members that must remain accessible.
      One type of error is "AddressSanitizer: unknown-crash", whose
      exact cause we have not determined.
      
      Another type of error (reported in MDEV-23472) is "use-after-poison",
      where the reported shadow bytes would in fact be 00, indicating that
      the memory was no longer poisoned. The poison-access-unpoison race
      condition was confirmed by "rr replay".
      
      We eliminate the race condition by invoking MEM_NOACCESS on each
      individual data member of trx_t before freeing the memory to the pool.
      The memory would not be unpoisoned until the pool is freed
      or the memory is being reused for another allocation.
      
      trx_t::free(): Replaces trx_free().
      
      trx_t::active_commit_ordered: Changed to bool, so that MEM_NOACCESS
      can be invoked. Removed some accessor functions.
      
      Pool: Remove all MEM_ instrumentation.
      
      TrxFactory: Move the MEM_ instrumentation from Pool.
      
      TrxFactory::debug(): Removed. Moved to trx_t::free(). Because
      the memory was already marked unaccessible in trx_t::free(), the
      Factory::debug() call in Pool::putl() would be unable to access it.
      
      trx_allocate_for_background(): Replaces trx_create_low().
      
      trx_t::free(): Perform all consistency checks while avoiding
      duplication, and declare most data members unaccessible.
      f3160ee4
    • Andrei Elkin's avatar
      MDEV-23511 shutdown_server 10 times out, causing server kill at shutdown · a19cb388
      Andrei Elkin authored
      Shutdown of mtr tests may be too impatient, esp on CI environment where
      10 seconds of `arg` of `shutdown_server arg` may not be enough for the clean
      shutdown to complete.
      
      This is fixed to remove explicit non-zero timeout argument to
      `shutdown_server` from all mtr tests. mysqltest computes 60 seconds default
      value for the timeout for the argless `shutdown_server` command.
      This policy is additionally ensured with a compile time assert.
      a19cb388
    • Marko Mäkelä's avatar
      Merge 10.1 into 10.2 · a43faf6b
      Marko Mäkelä authored
      a43faf6b
    • Jan Lindström's avatar
      29d9df16
  10. 20 Aug, 2020 4 commits
    • Thirunarayanan Balathandayuthapani's avatar
      MDEV-23452 Assertion `buf_page_get_io_fix(bpage) == BUF_IO_NONE' failed · a79c2578
      Thirunarayanan Balathandayuthapani authored
      		in buf_page_set_sticky
      
      - Adding os_thread_yield() in buf_page_create() to avoid the continuous
      buffer pool mutex acquistions.
      a79c2578
    • Thirunarayanan Balathandayuthapani's avatar
      MDEV-23452 Assertion `buf_page_get_io_fix(bpage) == BUF_IO_NONE' failed · e9d6f1c7
      Thirunarayanan Balathandayuthapani authored
      			in buf_page_set_sticky
      
      commit a1f899a8 (MDEV-23233) added the
      code to make page sticky. So that InnoDB can't allow the page to
      be grabbed by other thread while doing lazy drop of ahi.
      
      But the block could be in flush list and it could have io_fix value
      as BUF_IO_WRITE. It could lead to the failure in buf_page_set_sticky().
      
      buf_page_create(): If btr_search_drop_page_hash_index() must be invoked,
      take x-latch on the block. If the block io_fix value is other than
      BUF_IO_NONE, release the buffer pool mutex and page hash lock and
      wait for I/O to complete.
      e9d6f1c7
    • Marko Mäkelä's avatar
      MDEV-23514 Race conditions between ROLLBACK and ALTER TABLE · 22c4a751
      Marko Mäkelä authored
      Since commit 15093639 (MDEV-23484)
      the rollback of InnoDB transactions is no longer protected by
      dict_operation_lock. Removing that protection revealed a race
      condition between transaction rollback and the rollback of an
      online table-rebuilding operation (OPTIMIZE TABLE, or any online
      ALTER TABLE that is rebuilding the table).
      
      row_undo_mod_clust(): Re-check dict_index_is_online_ddl() after
      acquiring index->lock, similar to how row_undo_ins_remove_clust_rec()
      is doing it. Because innobase_online_rebuild_log_free() is holding
      exclusive index->lock while invoking row_log_free(), this re-check
      will ensure that row_log_table_low() will not be invoked when
      index->online_log=NULL.
      
      A different race condition is possible between the rollback of a
      recovered transaction and the start of online secondary index creation.
      Because prepare_inplace_alter_table_dict() is not acquiring an InnoDB
      table lock in this case, and because recovered transactions are not
      covered by metadata locks (MDL), the dict_table_t::indexes could be
      modified by prepare_inplace_alter_table_dict() while the rollback of
      a recovered transaction is being executed. Normal transactions would
      be covered by MDL, and during prepare_inplace_alter_table_dict() we
      do hold MDL_EXCLUSIVE, that is, an online ALTER TABLE operation may
      not execute concurrently with other transactions that have accessed
      the table.
      
      row_undo(): To prevent a race condition with
      prepare_inplace_alter_table_dict(), acquire dict_operation_lock
      for all recovered transactions. Before MDEV-23484 we used to acquire
      it for all transactions, not only recovered ones.
      
      Note: row_merge_drop_indexes() would not invoke
      dict_index_remove_from_cache() while transactional locks
      exist on the table, or while any thread is holding an open table handle.
      OK, it does that for FULLTEXT INDEX, but ADD FULLTEXT INDEX is not
      supported as an online operation, and therefore
      prepare_inplace_alter_table_dict() would acquire a table S lock,
      which cannot succeed as long as recovered transactions on the table
      exist, because they would hold a conflicting IX lock on the table.
      22c4a751
    • Marko Mäkelä's avatar
      Merge 10.1 into 10.2 · bfba2bce
      Marko Mäkelä authored
      bfba2bce
  11. 19 Aug, 2020 1 commit
    • Marko Mäkelä's avatar
      MDEV-23475 InnoDB performance regression for write-heavy workloads · 309302a3
      Marko Mäkelä authored
      In commit fe39d02f (MDEV-20638)
      we removed some wake-up signaling of the master thread that should
      have been there, to ensure a steady log checkpointing workload.
      
      Common sense suggests that the commit omitted some necessary calls
      to srv_inc_activity_count(). But, an attempt to add the call to
      trx_flush_log_if_needed_low() as well as to reinstate the function
      innobase_active_small() did not restore the performance for the
      case where sync_binlog=1 is set.
      
      Therefore, we will revert the entire commit in MariaDB Server 10.2.
      In MariaDB Server 10.5, adding a srv_inc_activity_count() call to
      trx_flush_log_if_needed_low() did restore the performance, so we
      will not revert MDEV-20638 across all versions.
      309302a3
  12. 18 Aug, 2020 1 commit
    • Marko Mäkelä's avatar
      MDEV-23484 Rollback unnecessarily acquires dict_operation_lock for every row · 15093639
      Marko Mäkelä authored
      InnoDB transaction rollback includes an unnecessary work-around for
      a data corruption bug that was fixed by me in MySQL 5.6.12
      mysql/mysql-server@935ba09d52c1908bde273ad1940b5ab919d9763d
      and ported to MariaDB 10.0.8 by
      commit c291ddfd
      in 2013 and 2014, respectively.
      
      By acquiring and releasing dict_operation_lock in shared mode,
      row_undo() hopes to prevent the table from being dropped while
      the undo log record is being rolled back. But, thanks to mentioned fix,
      debug assertions (that we are adding) show that the rollback is
      protected by transactional locks (table IX lock, in addition to
      implicit or explicit exclusive locks on the records that had been modified).
      
      Because row_drop_table_for_mysql() would invoke
      row_add_table_to_background_drop_list() if any locks exist on the table,
      the mere existence of locks (which is guaranteed during ROLLBACK) is
      enough to protect the table from disappearing. Hence, acquiring and
      releasing dict_operation_lock for every row that is being rolled back is
      unnecessary.
      
      row_undo(): Remove the unnecessary acquisition and release of
      dict_operation_lock.
      
      Note: row_add_table_to_background_drop_list() is mostly working around
      bugs outside InnoDB:
      MDEV-21175 (insufficient MDL protection of FOREIGN KEY operations)
      MDEV-21602 (incorrect error handling of CREATE TABLE...SELECT).
      15093639