1. 12 Apr, 2022 1 commit
    • Sergei Golubchik's avatar
      MDEV-24317 Data race in LOGGER::init_error_log at sql/log.cc:1443 and in... · bbdec04d
      Sergei Golubchik authored
      MDEV-24317 Data race in LOGGER::init_error_log at sql/log.cc:1443 and in LOGGER::error_log_print at sql/log.cc:1181
      
      don't initialize error_log_handler_list in set_handlers()
      * error_log_handler_list is initialized to LOG_FILE early, in init_base()
      * set_handlers always reinitializes it to LOG_FILE, so it's pointless
      * after init_base() concurrent threads start using sql_log_warning,
        so following set_handlers() shouldn't modify error_log_handler_list
        without some protection
      bbdec04d
  2. 11 Apr, 2022 1 commit
    • Monty's avatar
      MDEV-28269 Assertion `save_errno' in maria_write or ER_GET_ERRNO · 6891c487
      Monty authored
      The issue was that the value of MARIA_FOUND_WRONG_KEY was a value
      that could be returned by ha_key_cmp.
      
      This was already fixed in MyISAM, now using the same fix in Aria:
      Setting the value to INT_MAX32, which should be impossible in any
      normal cases.
      
      I also fixed so that if there is a wrong key, we now get a proper error
      message and not an assert.
      6891c487
  3. 09 Apr, 2022 2 commits
    • Alexander Barkov's avatar
      MDEV-28267 ASAN heap-use-after-free in Item_sp::func_name_cstring · 2ae92e89
      Alexander Barkov authored
      This crash happens on a combination of multiple conditions:
      
      - There is a thead#1 running an "ANALYZE FORMAT=JSON" query for a
        "SELECT .. FROM INFORMATION_SCHEMA.COLUMNS WHERE .. "
      - The WHERE clause contains a stored function call, say f1().
      - The WHERE clause is built in the way so that the function f1()
        is never actually called, e.g.
          WHERE .. AND (TRUE OR f1()=expr)
      - The database contains multiple VIEWs that have the function f1() call,
        e.g. in their <select list>
      - The WHERE clause is built in the way so that these VIEWs match
        the condition.
      - There is a parallel thread#2 running. It creates or drops or recreates
        some other stored routine, say f2(), which is not used in the ANALYZE query.
        It effectively invalidates the stored routine cache for thread#1
        without locking.
        Note, it is important that f2() is NOT used by ANALYZE query.
        Otherwise, thread#2 would be locked until the ANALYZE query
        finishes.
      
      When all of the above conditions are met, the following happens:
      
      1. thread#1 starts the ANALYZE query. It notices a call for the stored function
         f1() in the WHERE condition. The function f1() gets parsed and cached
         to the SP cache. Its address also gets assigned to Item_func_sp::m_sp.
      
      2. thread#1 starts iterating through all tables that
         match the WHERE condition to find the information about their columns.
      
      3. thread#1 processes columns of the VIEW v1.
         It notices a call for f1() in the VIEW v1 definition.
         But f1() is already cached in the step#1 and it is up to date.
         So nothing happens with the SP cache.
      
      4. thread#2 re-creates f2() in a non-locking mode.
         It effectively invalidates the SP cache in thread#1.
      
      5. thread#1 processes columns of the VIEW v2.
         It notices a call for f1() in the VIEW v2 definition.
         It also notices that the cached version of f1() is not up to date.
         It frees the old definition of f1(), parses it again, and puts a
         new version of f1() to the SP cache.
      
      6. thread#1 finishes processing rows and generates the JSON output.
         When printing the "attached_condition" value, it calls
         Item_func_sp::print() for f1(). But this Item_func_sp links
         to the old (freed) version of f1().
      
      The above scenario demonstrates that Item_func_sp::m_sp can point to an
      alredy freed instance when Item_func_sp::func_name() is called,
      so accessing to Item_sp::m_sp->m_handler is not safe.
      
      This patch rewrites the code to use Item_func_sp::m_handler instead,
      which is always reliable.
      
      Note, this patch is only a cleanup for MDEV-28166 to quickly fix the regression.
      It fixes MDEV-28267. But it does not fix the core problem:
      The code behind I_S does not take into account that the SP
      cache can be updated while evaluating rows of the COLUMNS table.
      This is a corner case and it never happens with any other tables.
      I_S.COLUMNS is very special.
      
      Another example of the core problem is reported in MDEV-25243.
      The code accesses to Item_sp::m_sp->m_chistics of an
      already freed m_sp, again. It will be addressed separately.
      2ae92e89
    • Sergei Golubchik's avatar
      MDEV-22282 When using mysqldump to backup a view that contains derived tables,... · d623b5a1
      Sergei Golubchik authored
      MDEV-22282 When using mysqldump to backup a view that contains derived tables, the database name is prepended to each table in the view
      
      derived tables have db = "", table_name = "*", those aren't real names
      to be compared with.
      d623b5a1
  4. 08 Apr, 2022 2 commits
    • Alexander Barkov's avatar
      MDEV-28062 Assertion `(length % 4) == 0' failed in my_lengthsp_utf32 on INSERT..SELECT · 3814b04d
      Alexander Barkov authored
      Adding an MTR test only.
      
      This problem was earlier fixed by the patch for:
        MDEV-28078 Garbage on multiple equal ENUMs with tricky character sets
      3814b04d
    • Nayuta Yanagisawa's avatar
      MDEV-25116 Spider: IF(COUNT( trigger SQL Error (1054)_ Unknown column '' in field list · 4194f7b6
      Nayuta Yanagisawa authored
      The original query "SELECT IF(COUNT(a.`id`)>=0,'Y','N') FROM t" is
      transformed to "SELECT COUNT(a.`id`), IF(ref >= 0, 'Y', 'N') FROM t",
      where ref is Item_ref to "COUNT(a.`id`)", by split_sum_func().
      
      Spider walks the item list twice, invoking spider_db_print_item_type().
      The first invocation is in spider_create_group_by_handler() with
      str == NULL. The second one is in spider_group_by_handler::init_scan()
      with str != NULL.
      
      spider_db_print_item_type() prints nothing at the first invocation,
      and it prints item at the second invocation. However, at the second
      invocation, the above mentioned ref to "COUNT(a.`id`)" points to
      a field in a temporary table where the result will be stored. Thus,
      to look behind the item_ref, Spider need to generate the query earlier.
      
      A possible fix would be to generate a query to send in
      spider_create_group_by_handler(). However, the fix requires a
      considerable amount of changes of the Spider's GROUP BY handler.
      I'd like to avoid that.
      
      So, I fix the problem by not to use the GROUP BY handler when a
      query contains Item_ref whose table_name, name, and alias_name_used
      are not set.
      4194f7b6
  5. 07 Apr, 2022 4 commits
  6. 06 Apr, 2022 2 commits
    • Marko Mäkelä's avatar
      MDEV-25975 innodb_disallow_writes causes shutdown to hang · e9735a81
      Marko Mäkelä authored
      We will remove the parameter innodb_disallow_writes because it is badly
      designed and implemented. The parameter was never allowed at startup.
      It was only internally used by Galera snapshot transfer.
      If a user executed
      SET GLOBAL innodb_disallow_writes=ON;
      the server could hang even on subsequent read operations.
      
      During Galera snapshot transfer, we will block writes
      to implement an rsync friendly snapshot, as follows:
      
      sst_flush_tables() will acquire a global lock by executing
      FLUSH TABLES WITH READ LOCK, which will block any writes
      at the high level.
      
      sst_disable_innodb_writes(), invoked via ha_disable_internal_writes(true),
      will suspend or disable InnoDB background tasks or threads that could
      initiate writes. As part of this, log_make_checkpoint() will be invoked
      to ensure that anything in the InnoDB buf_pool.flush_list will be written
      to the data files. This has the nice side effect that the Galera joiner
      will avoid crash recovery.
      
      The changes to sql/wsrep.cc and to the tests are based on a prototype
      that was developed by Jan Lindström.
      
      Reviewed by: Jan Lindström
      e9735a81
    • Marko Mäkelä's avatar
      Merge 10.2 into 10.3 · 7c584d82
      Marko Mäkelä authored
      7c584d82
  7. 05 Apr, 2022 3 commits
  8. 04 Apr, 2022 3 commits
  9. 03 Apr, 2022 1 commit
    • Daniel Black's avatar
      MDEV-26136: Correct AIX/macOS cast warning (my_time.h) · 75b9014f
      Daniel Black authored
      tv_usec is a (suseconds_t) so we cast to it. Prevents the AIX(gcc-10) warning:
      
      include/my_time.h: In function 'void my_timeval_trunc(timeval*, uint)':
      include/my_time.h:249:65: warning: conversion from 'long int' to 'suseconds_t' {aka 'int'} may change value [-Wconversion]
        249 |   tv->tv_usec-= my_time_fraction_remainder(tv->tv_usec, decimals);
            |
      
      macOS is: conversion from 'long int' to '__darwin_suseconds_t' {aka 'int'} may change value
      
      On Windows suseconds_t isn't defined so we use the existing
      long return type of my_time_fraction_remainder.
      
      Reviewed by Marko Mäkelä
      
      Closes: #2079
      75b9014f
  10. 02 Apr, 2022 1 commit
    • Dmitry Shulga's avatar
      MDEV-28220: Assert failure in sp_head::~sp_head on parsing a syntax incorrect... · 8c169f5e
      Dmitry Shulga authored
      MDEV-28220: Assert failure in sp_head::~sp_head on parsing a syntax incorrect statement CREATE SEQUENCE ... RESTART inside CREATE PROCEDURE/CREATE FUNCTION
      
      This bug report is about the same issue as MDEV-28129 and MDEV-21173.
      The issue is that the macros YYABORT is called instead of MYSQL_YYABORT
      on parse error. In result the method LEX::cleanup_lex_after_parse_error
      is not called to clean up data structures created on parsing of
      the statement.
      8c169f5e
  11. 01 Apr, 2022 1 commit
  12. 30 Mar, 2022 3 commits
    • Vlad Lesin's avatar
      MDEV-27343 Useless warning "InnoDB: Allocated tablespace ID <id> for... · c1ab0e6f
      Vlad Lesin authored
      MDEV-27343 Useless warning "InnoDB: Allocated tablespace ID <id> for <tablename>, old maximum was 0" during backup stage
      
      mariabackup does not load dictionary during backup, but it loads
      tablespaces, that is why fil_system.max_assigned_id is not set with
      dict_check_tablespaces_and_store_max_id(). There is no sense to issue the
      warning during backup.
      c1ab0e6f
    • Marko Mäkelä's avatar
      Cleanup: Remove some unused functions · 35425cfc
      Marko Mäkelä authored
      35425cfc
    • Dmitry Shulga's avatar
      MDEV-19631: Assertion `0' failed in st_select_lex_unit::optimize or different... · bdba1d46
      Dmitry Shulga authored
      MDEV-19631: Assertion `0' failed in st_select_lex_unit::optimize or different plan upon 2nd execution of PS with EXPLAIN
      
      Second execution of a prepared statement for a query containing a constant
      subquery with union that can be optimized away, could result in server abnormal
      termination for debug build or incorrect result set output for release build.
      
      For example, the following test case crashes a server built with debug on second
      run of the statement EXECUTE stmt
        CREATE TABLE t1 (a INT);
        PREPARE stmt FROM 'EXPLAIN SELECT * FROM t1 HAVING 6 IN ( SELECT 6 UNION SELECT 5 )';
        EXECUTE stmt;
        EXECUTE stmt;
      
      The reason for incorrect result set output or abnormal server termination
      is careless working with the data member fake_select_lex->options inside
      the function mysql_explain_union(). Once the flag SELECT_DESCRIBE is set in
      the data member fake_select_lex->option before calling the methods
        SELECT_LEX_UNIT::prepare/SELECT_LEX_UNIT::execute
      the original value of the option is no longer restored.
      As a consequence, next time the prepared statement is re-executed we have
      the fake_select_lex with the flag SELECT_DESCRIBE set in the data member
      fake_select_lex->option, that is incorrect. In result, the method
        Item_subselect::assigned()
      is not invoked during evaluation of a constant condition (constant subquery
      with union) that being performed on OPTIMIZE phase of query handling.
      
      This leads to the fact that records in the temporary table are not deleted
      before calling
        table->file->ha_enable_indexes(HA_KEY_SWITCH_ALL)
      in the method st_select_lex_unit::optimize().
      In result table->file->ha_enable_indexes(HA_KEY_SWITCH_ALL) returns error
      and DBUG_ASSERT(0) is fired.
      
      Stack trace to the line where the error generated on re-enabling indexes
      for next subselect iteration is below:
      st_select_lex_unit::optimize (at sql_union.cc:954)
        handler::ha_enable_indexes (at handler.cc:4338)
          ha_heap::enable_indexes (at ha_heap.cc:519)
            heap_enable_indexes (at hp_clear.c:164)
      
      The code snippet to clarify raising the error is also listed:
      int heap_enable_indexes(HP_INFO *info)
      {
        int error= 0;
        HP_SHARE *share= info->s;
      
        if (share->data_length || share->index_length)
          error= HA_ERR_CRASHED; <<== set error the value HA_ERR_CRASHED
                                      since share->data_length != 0
      
      To fix this issue the original value of unit->fake_select_lex->options
      has to be saved before setting the flag SELECT_DESCRIBE and restored
      on return from invocation of SELECT_LEX_UNIT::prepare/SELECT_LEX_UNIT::execute
      bdba1d46
  13. 29 Mar, 2022 4 commits
  14. 28 Mar, 2022 3 commits
    • Vladislav Vaintroub's avatar
      MDEV-28178 Windows : sporadic ER_ERROR_ON_RENAME .. (errno: 13 "Permission denied") · 739002ee
      Vladislav Vaintroub authored
      On affected machine, the error happens sporadically in
      innodb.instant_alter_limit.
      
      Procmon shows SetRenameInformationFile failing with ERROR_ACCESS_DENIED.
      In this case, the destination file was previously opened rsp oplocked by
      Windows defender antivirus.
      
      The fix is to retry MoveFileEx on ERROR_ACCESS_DENIED.
      739002ee
    • Marko Mäkelä's avatar
      MDEV-27931: buf_page_is_corrupted() wrongly claims corruption · 303448bc
      Marko Mäkelä authored
      In commit 437da7bc (MDEV-19534),
      the default value of the global variable srv_checksum_algorithm
      in innochecksum was changed from SRV_CHECKSUM_ALGORITHM_INNODB
      to implied 0 (innodb_checksum_algorithm=crc32). As a result,
      the function buf_page_is_corrupted() would by default invoke
      buf_calc_page_crc32() in innochecksum, and crc32_inited would hold.
      
      This would cause "innochecksum" to fail on a particular page.
      
      The actual problem is older, introduced in 2011 in
      mysql/mysql-server@17e497bdb793bc6b8360aa1c626dcd8bb5cfad1b
      (MySQL 5.6.3). It should affect the validation of pages of old
      data files that were written with innodb_checksum_algorithm=innodb.
      When using innodb_checksum_algorithm=crc32 (the default setting
      since MariaDB Server 10.2), some valid pages would be rejected
      only because exactly one of the two checksum fields accidentally
      matches the innodb_checksum_algorithm=crc32 value.
      
      buf_page_is_corrupted(): Simplify the logic of non-strict
      checksum validation, by always invoking buf_calc_page_crc32().
      Remove a bogus condition that if only one of the checksum fields
      contains the value returned by buf_calc_page_crc32(), the page
      is corrupted.
      303448bc
    • hongdongjian's avatar
      MDEV-28177: server_audit; Update the offset of dbName on the aarch64 platform. · 7af133cc
      hongdongjian authored
      On the aarch64 platform, MySQL 5.7.33 cannot install this version of the audit
      plugin, but X86_64 can run well。
      7af133cc
  15. 25 Mar, 2022 6 commits
    • Igor Babaev's avatar
      MDEV-27937 Assertion failure when executing prepared statement with ? in IN list · e048289e
      Igor Babaev authored
      This bug affected queries with IN predicates that contain parameter markers
      in the value list. Such queries are executed via prepared statements.
      The problem appeared only if the number of elements in the value list
      was greater than the set value of the system variable
      in_predicate_conversion_threshold.
      
      The patch unconditionally prohibits conversion of an IN predicate to the
      equivalent IN predicand if the value list of the IN predicate contains
      parameters markers.
      
      Approved by Oleksandr Byelkin <sanja@mariadb.com>
      e048289e
    • Rucha Deodhar's avatar
      MDEV-21873: 10.2 to 10.3 upgrade doesn't remove semi-sync reference · 549a71e7
      Rucha Deodhar authored
      from mysql.plugin table
      Fix: Since mysql_upgrade runs commands from mysql_system_tables.fix,
      added sql commands to check for semisync plugins in
      INFORMATION_SCHEMA.PLUGINS and if they aren't there then delete them
      from mysql.plugin.
      549a71e7
    • Alexander Barkov's avatar
      MDEV-19804 sql_mode=ORACLE: call procedure in packages · fbcf0225
      Alexander Barkov authored
      Adding support for the fully qualified package procedure calls:
      
      BEGIN
        CALL db.pkg.proc(args); -- SQL/PSM call style
        db.pkg.proc(args);      -- PL/SQL call style
      END;
      fbcf0225
    • Sachin Kumar's avatar
      MDEV-24667 LOAD DATA INFILE on temporary table not written to slave binlog · 9f4ba624
      Sachin Kumar authored
      Problem: In regular replication, when master binlogged using statement format
      slave might not have written an event to its binary log when the Query
      event aimed at a temporary table.
      Specifically this was observed with LOAD DATA INFILE.
      
      This effect was possible because unlike master slave holds temporary
      tables in its pool and the master side check of existence of a
      temporary table at the format bin-logging decision did not apply.
      
      Solution: replace THD::has_thd_temporary_tables() with
      THD::has_temporary_tables which allows to identify temporary table
      presence on either side.
      
      --
      Reviewed by Andrei Elkin.
      9f4ba624
    • sjaakola's avatar
      MDEV-24845 Oddities around innodb_fatal_semaphore_wait_threshold and global.innodb_disallow_writes · 9b2fa2ae
      sjaakola authored
      This commit adds a mtr test for reproducing a test scenario where despite of
      innodb_disallow_writes blocking, writes to file system can still happen.
      
      The test launches a garbd node, which triggers one of the cluster node to switch to
      SST donor state. In this state, all disk activity should be halted, and e.g.
      innodb_disallow_writes has been set. The test records md5sum aggregate over mariadb
      data directory when the node enters the donor state, and records another md5sum
      when the node leaves the donor state. If there is no IO activity in data directory, these
      hashes should be equal.
      
      For this test, the Donor state processing, has beeen instrumented so that, SST donor thread can be
      stopped when entering the donor state. The test uses this new dbug sync point,
      to control when to record the md5sums.
      
      New SST script was added: wsrep_sst_backup, and garbd uses backup method to lauch the donor
      node to call this script, and to enter in donor state.
      
      The backup script could be later extended as general purpose backup method for the cluster.
      
      This commit fixes also one race condition happening in wsrep_sst_rsync, like this:
      * wsrep_rsync_sst script requests for flush tables,
        and then waits in a loop until mariadbd has created file tables_flushed,
        as confirmation that FLUSH TABLES has completed
      * mariadbd's SST donor thread, wakes for the flush table request and then performs FTWRL,
        and after this it creates the tables_flushed file
      * note that SST script will now continue to startup rsync sending
      * mariadbd's SST donor thread now calls for sst_disallow_writes(),
        so that innodb would setup disk IO blockage, however rsyncing may already be ongoing at this point
      
      This race condition is fixed in this commit, by performing all disk IO blocking before
      creating the tables_flushed file.
      Reviewed-by: default avatarJan Lindström <jan.lindstrom@mariadb.com>
      9b2fa2ae
    • Alexander Barkov's avatar
      MDEV-28166 sql_mode=ORACLE: fully qualified package function calls do not work: db.pkg.func() · 6437b304
      Alexander Barkov authored
      Also fixes MDEV-19328 sql_mode=ORACLE: Package function in VIEW
      6437b304
  16. 24 Mar, 2022 3 commits
    • Brandon Nesterenko's avatar
      DBAAS-7828: Primary/replica: configuration change of autocommit=0 can not be applied · cd88b083
      Brandon Nesterenko authored
      Problem:
      ========
      When the mysql.gtid_slave_pos table uses the InnoDB engine, and
      mysqld starts, it reads the table and begins a transaction. After
      reading the value, it should end the transaction and release all
      associated locks. The bug reported in DBAAS-7828 shows that when
      autocommit is off, the locks are not released, resulting in
      indefinite hangs on future attempts to change gtid_slave_pos. In
      particular, the transaction was not properly finalized because
      thd->server_status was not updated to reflect the end of the
      transaction.
      
      Solution:
      ========
      This patch updates the code to properly commit the transaction after
      reading gtid_slave_pos during mysqld start-up.
      
      Reviewed By:
      ============
      Andrei Elkin <andrei.elkin@mariadb.com>
      cd88b083
    • Brandon Nesterenko's avatar
      MDEV-14608: mysqlbinlog lastest backupfile size is 0 · 174f1734
      Brandon Nesterenko authored
      Problem:
      ========
      When using mariadb-binlog with --raw and --stop-never, events from
      the master's currently active log file should be written to their
      respective log file specified by --result-file, and shown on-disk.
      There is a bug where mariadb-binlog does not flush the result file
      to disk when new events are received
      
      Solution:
      ========
      Add a function call to flush mariadb-binlog’s result file after
      receiving an event in --raw mode.
      
      Reviewed By:
      ============
      Andrei Elkin <andrei.elkin@mariadb.com>
      174f1734
    • Brandon Nesterenko's avatar
      MDEV-25580: rpl.rpl_semi_sync_slave_compressed_protocol crashes because of wrong packet · 32ab6219
      Brandon Nesterenko authored
      Problem:
      ========
      When both semi-sync and slave compression are enabled, the numbering
      on packet headers can become out of sync between the primary and
      replica servers. More specifically, after the master flushes its
      write, it should increment the counters that track packets. The
      bug is such that the master only updates the normal packet counter
      and leaves the compressed packet counter alone.
      
      Solution:
      ========
      After the master flushes, additionally increment the compressed
      packet counter.
      
      Reviewed By:
      ============
      Andrei Elkin: <andrei.elkin@mariadb.com>
      32ab6219