1. 31 Aug, 2022 15 commits
    • Aleksey Midenkov's avatar
      MDEV-28933 CREATE OR REPLACE fails to recreate same constraint name · cf6c5176
      Aleksey Midenkov authored
      Use temporary constraint names for temporary tables. The constraints
      are not added to cache (skipped in dict_table_rename_in_cache()).
      
      The scheme for temporary constraint names is as follows:
      
          for old table: db_name/\xFFconstraint_name
          for new table: db_name/\xFF\xFFconstraint_name
      
      normalize_table_name_c_low(): wrong comparison "less than FN_REFLEN -
      1". Somewhere array of FN_REFLEN includes the trailing 0, somewhere
      array of FN_REFLEN + 1 includes trailing 0, but nowhere array of
      FN_REFLEN - 1 must include trailing 0.
      cf6c5176
    • Aleksey Midenkov's avatar
      MDEV-28933 Moved RENAME_CONSTRAINT_IDS to include/sql_funcs.h · f1e1c133
      Aleksey Midenkov authored
      All InnoDB internal SQL functions should be moved to sql_funcs.h
      f1e1c133
    • Aleksey Midenkov's avatar
      MDEV-28956 Locking is broken if CREATE OR REPLACE fails under LOCK TABLES · a228ec80
      Aleksey Midenkov authored
      add_back_last_deleted_lock() was called when the lock was never
      removed. Lock is removed in finalize_atomic_replace() in
      close_all_tables_for_name(). finalize_atomic_replace() is done only
      for successful operation.
      
      In non-atomic codepath it drops the table first, if anything fails
      later we don't need to return back the lock since there is no table
      now. So the fix is required as well.
      a228ec80
    • Aleksey Midenkov's avatar
      MDEV-25292 gcol.gcol_bugfixes --ps fix · 24fff826
      Aleksey Midenkov authored
      Related to MDEV-24176.
      
      1. vcol_fix_expr() generates new tree changes:
      Type_std_attributes::agg_item_set_converter() does change_item_tree().
      
      The changes are allocated on expr_arena (via Vcol_expr_context as per
      MDEV-24176).
      
      2. vcol_cleanup_expr() doesn't remove these changes (can be a bug of
      Type_std_attributes or per design).
      
      3. Atomic CREATE OR REPLACE renames old table to backup
      (finalize_atomic_replace()). It does that via
      rename_table_and_triggers() and that closes table share and releases
      expr_arena root. Hence now we have Item corpses in thd->change_list.
      
      4. PS cleanup phase tries to rollback thd->change_list and accesses
      already freed item corpses.
      
      The fix saves and restores change_list on
      vcol_fix_expr()/vcol_cleanup_expr().
      24fff826
    • Aleksey Midenkov's avatar
      MDEV-25292 Disable atomic replace for slave-generated or-replace · 2af15914
      Aleksey Midenkov authored
      Also fixes wrong rollback of ddl_log_state_rm in case of non-atomic
      replace. There is no backup to remove in that case.
      2af15914
    • Aleksey Midenkov's avatar
      MDEV-25292 backup_log improved · 34398a20
      Aleksey Midenkov authored
      Separate backup_log_print per each test case group.
      34398a20
    • Aleksey Midenkov's avatar
      MDEV-25292 Atomic CREATE OR REPLACE TABLE · 93c8252f
      Aleksey Midenkov authored
      Atomic CREATE OR REPLACE allows to keep an old table intact if the
      command fails or during the crash. That is done through creating
      a table with a temporary name and filling it with the data
      (for CREATE OR REPLACE .. SELECT), then renaming the original table
      to another temporary (backup) name and renaming the replacement table
      to original table. The backup table is kept until the last chance of
      failure and if that happens, the replacement table is thrown off and
      backup recovered. When the command is complete and logged the backup
      table is deleted.
      
      Atomic replace algorithm
      
        Two DDL chains are used for CREATE OR REPLACE:
        ddl_log_state_create (C) and ddl_log_state_rm (D).
      
        1. (C) Log CREATE_TABLE_ACTION of TMP table (drops TMP table);
        2. Create new table as TMP;
        3. Do everything with TMP (like insert data);
      
        finalize_atomic_replace():
        4. Link chains: (D) is executed only if (C) is closed;
        5. (D) Log DROP_ACTION of BACKUP;
        6. (C) Log RENAME_TABLE_ACTION from ORIG to BACKUP (replays BACKUP -> ORIG);
        7. Rename ORIG to BACKUP;
        8. (C) Log CREATE_TABLE_ACTION of ORIG (drops ORIG);
        9. Rename TMP to ORIG;
      
        finalize_ddl() in case of success:
        10. Close (C);
        11. Replay (D): BACKUP is dropped.
      
        finalize_ddl() in case of error:
        10. Close (D);
        11. Replay (C):
          1) ORIG is dropped (only after finalize_atomic_replace());
          2) BACKUP renamed to ORIG (only after finalize_atomic_replace());
          3) drop TMP.
      
        If crash happens (C) or (D) is replayed in reverse order. (C) is
        replayed if crash happens before it is closed, otherwise (D) is
        replayed.
      
      Temporary table for CREATE OR REPLACE
      
        Before dropping "old" table, CREATE OR REPLACE creates "tmp" table.
        ddl_log_state_create holds the drop of the "tmp" table.  When
        everything is OK (data is inserted, "tmp" is ready) ddl_log_state_rm
        is written to replace "old" with "tmp". Until ddl_log_state_create
        is closed ddl_log_state_rm is not executed.
      
        After the binlogging is done ddl_log_state_create is closed. At that
        point ddl_log_state_rm is executed and "tmp" is replaced with
        "old". That is: final rename is done by the DDL log.
      
        With that important role of DDL log for CREATE OR REPLACE operation
        replay of ddl_log_state_rm must fail at the first hit error and
        print the error message if possible. F.ex. foreign key error is
        discovered at this phase: InnoDB rejects to drop the "old" table and
        returns corresponding foreign key error code.
      
      Additional notes
      
        - CREATE TABLE without REPLACE is not affected by this commit.
      
        - Engines having HTON_EXPENSIVE_RENAME flag set are not affected by
          this commit.
      
        - CREATE TABLE .. SELECT XID usage is fixed and now there is no need
          to log DROP TABLE via DDL_CREATE_TABLE_PHASE_LOG (see comments in
          do_postlock()). XID is now correctly updated so it disables
          DDL_LOG_DROP_TABLE_ACTION. Note that binary log is flushed at the
          final stage when the table is ready. So if we have XID in the
          binary log we don't need to drop the table.
      
        - Three variations of CREATE OR REPLACE handled:
      
          1. CREATE OR REPLACE TABLE t1 (..);
          2. CREATE OR REPLACE TABLE t1 LIKE t2;
          3. CREATE OR REPLACE TABLE t1 SELECT ..;
      
        - Test case uses 6 combinations for engines (aria, aria_notrans,
          myisam, ib, lock_tables, expensive_rename) and 2 combinations for
          binlog types (row, stmt). Combinations help to check differences
          between the results. Error failures are tested for the above three
          variations.
      
        - expensive_rename tests CREATE OR REPLACE without atomic
          replace. The effect should be the same as with the old behaviour
          before this commit.
      
        - Triggers mechanism is unaffected by this change. This is tested in
          create_replace.test.
      
        - LOCK TABLES is affected. Lock restoration must be done after "rm"
          chain is replayed.
      
        - Moved ddl_log_complete() from send_eof() to finalize_ddl(). This
          checkpoint was not executed before for normal CREATE TABLE but is
          executed now.
      
        - CREATE TABLE will now rollback also if writing to the binary
          logging failed. See rpl_gtid_strict.test
      
      Rename and drop via DDL log
      
        We replay ddl_log_state_rm to drop the old table and rename the
        temporary table. In that case we must throw the correct error
        message if ddl_log_revert() fails (f.ex. on FK error).
      
        If table is deleted earlier and not via DDL log and the crash
        happened, the create chain is not closed. Linked drop chain is not
        executed and the new table is not installed. But the old table is
        already deleted.
      
      ddl_log.cc changes
      
        Now we can place action before DDL_LOG_DROP_INIT_ACTION and it will
        be replayed after DDL_LOG_DROP_TABLE_ACTION.
      
        report_error parameter for ddl_log_revert() allows to fail at first
        error and print the error message if possible.
        ddl_log_execute_action() now can print error message.
      
        Since we now can handle errors from ddl_log_execute_action() (in
        case of non-recovery execution) unconditional setting "error= TRUE"
        is wrong (it was wrong anyway because it was overwritten at the end
        of the function).
      
      On XID usage
      
        Like with all other atomic DDL operations XID is used to avoid
        inconsistency between master and slave in the case of a crash after
        binary log is written and before ddl_log_state_create is closed. On
        recovery XIDs are taken from binary log and corresponding DDL log
        events get disabled.  That is done by
        ddl_log_close_binlogged_events().
      
      On linking two chains together
      
        Chains are executed in the ascending order of entry_pos of execute
        entries. But entry_pos assignment order is undefined: it may assign
        bigger number for the first chain and then smaller number for the
        second chain. So the execution order in that case will be reverse:
        second chain will be executed first.
      
        To avoid that we link one chain to another. While the base chain
        (ddl_log_state_create) is active the secondary chain
        (ddl_log_state_rm) is not executed. That is: only one chain can be
        executed in two linked chains.
      
        The interface ddl_log_link_chains() was done in "MDEV-22166
        ddl_log_write_execute_entry() extension".
      
      More on CREATE OR REPLACE .. SELECT
      
        We use create_and_open_tmp_table() like in ALTER TABLE to create
        temporary TABLE object (tmp_table is (NON_)TRANSACTIONAL_TMP_TABLE).
      
        After we created such TABLE object we use create_info->tmp_table()
        instead of table->s->tmp_table when we need to check for
        parser-requested tmp-table.
      
        External locking is required for temporary table created by
        create_and_open_tmp_table(). F.ex. that disables logging for Aria
        transactional tables and without that (when no mysql_lock_tables()
        is done) it cannot work correctly.
      
        For making external lock the patch requires Aria table to work in
        non-transactional mode. That is usually done by
        ha_enable_transaction(false). But we cannot disable transaction
        completely because: 1. binlog rollback removes pending row events
        (binlog_remove_pending_rows_event()). The row events are added
        during CREATE .. SELECT data insertion phase. 2. replication slave
        highly depends on transaction and cannot work without it.
      
        So we put temporary Aria table into non-transactional mode with
        "thd->transaction->on hack". See comment for on_save variable.
      
        Note that Aria table has internal_table mode. But we cannot use it
        because:
      
        if (!internal_table)
        {
          mysql_mutex_lock(&THR_LOCK_myisam);
          old_info= test_if_reopen(name_buff);
        }
      
        For internal_table test_if_reopen() is not called and we get a new
        MARIA_SHARE for each file handler. In that case duplicate errors are
        missed because insert and lookup in CREATE .. SELECT is done via two
        different handlers (see create_lookup_handler()).
      
        For temporary table before dropping TABLE_SHARE by
        drop_temporary_table() we must do ha_reset(). ha_reset() releases
        storage share. Without that the share is kept and the second CREATE
        OR REPLACE .. SELECT fails with:
      
          HA_ERR_TABLE_EXIST (156): MyISAM table '#sql-create-b5377-4-t2' is
          in use (most likely by a MERGE table). Try FLUSH TABLES.
      
          HA_EXTRA_PREPARE_FOR_DROP also removes MYISAM_SHARE, but that is
          not needed as ha_reset() does the job.
      
        ha_reset() is usually done by
        mark_tmp_table_as_free_for_reuse(). But we don't need that mechanism
        for our temporary table.
      
      Atomic_info in HA_CREATE_INFO
      
        Many functions in CREATE TABLE pass the same parameters. These
        parameters are part of table creation info and should be in
        HA_CREATE_INFO (or whatever). Passing parameters via single
        structure is much easier for adding new data and
        refactoring.
      
      InnoDB changes (revised by Marko Mäkelä)
      
        row_rename_table_for_mysql(): Specify the treatment of FOREIGN KEY
        constraints in a 4-valued enum parameter. In cases where FOREIGN KEY
        constraints cannot exist (partitioned tables, or internal tables of
        FULLTEXT INDEX), we can use the mode RENAME_IGNORE_FK.
        The mod RENAME_REBUILD is for any DDL operation that rebuilds the
        table inside InnoDB, such as TRUNCATE and native ALTER TABLE
        (or OPTIMIZE TABLE). The mode RENAME_ALTER_COPY is used solely
        during non-native ALTER TABLE in ha_innobase::rename_table().
        Normal ha_innobase::rename_table() will use the mode RENAME_FK.
      
        CREATE OR REPLACE will rename the old table (if one exists) along
        with its FOREIGN KEY constraints into a temporary name. The replacement
        table will be initially created with another temporary name.
        Unlike in ALTER TABLE, all FOREIGN KEY constraints must be renamed
        and not inherited as part of these operations, using the mode RENAME_FK.
      
        dict_get_referenced_table(): Let the callers convert names when needed.
      
        create_table_info_t::create_foreign_keys(): CREATE OR REPLACE creates
        the replacement table with a temporary name table, so for
        self-references foreign->referenced_table will be a table with
        temporary name and charset conversion must be skipped for it.
      
      Reviewed by:
      
        Michael Widenius <monty@mariadb.org>
      93c8252f
    • Aleksey Midenkov's avatar
      MDEV-25292 select_create::create_table removed · 86da0f4e
      Aleksey Midenkov authored
      create_table duplicates select_insert::table_list. Since select_create
      inherits select_insert and the functional role of the members is the
      same we should remove one to eliminate the need of keeping them in
      sync.
      86da0f4e
    • Aleksey Midenkov's avatar
      MDEV-25292 Table_name class for (db, table_name, alias) · d145dda9
      Aleksey Midenkov authored
      TABLE_SHARE, TABLE_LIST inherit Table_name
      
      rename_table_and_triggers(), rename_check_preconditions() use
      Table_name instead TABLE_LIST.
      
      TODO:
        - Table_ident should inherit Table_name too;
        - Use TABLE_SHARE::alias instead of TABLE::alias.
      d145dda9
    • Aleksey Midenkov's avatar
      MDEV-25292 Refactoring: removed TABLEOP_HOOKS · 32d88fae
      Aleksey Midenkov authored
      TABLEOP_HOOKS is a strange interface: proxy interface calls virtual
      interface. Since it is used only for select_create::prepare() such
      complexity is overwhelming.
      32d88fae
    • Aleksey Midenkov's avatar
      MDEV-25292 ha_table_exists() cleanup and improvement · 409b8a86
      Aleksey Midenkov authored
      Removed default values for arguments, added flags argument to specify
      filename flags (FN_TO_IS_TMP, FN_FROM_IS_TMP).
      409b8a86
    • Aleksey Midenkov's avatar
      65e0d0ea
    • Aleksey Midenkov's avatar
      MDEV-25292 Cleanups · 595dad83
      Aleksey Midenkov authored
      ddl_log_write_execute_entry() cleanup
      
      Rename functions renamed:
        do_rename() -> rename_table_and_triggers()
        do_rename_temporary() -> rename_temporary_table()
        check_rename() -> rename_check_preconditions()
      595dad83
    • Aleksey Midenkov's avatar
      MDEV-25292 Refactoring: moved select_field_count into Alter_info. · f02af1d2
      Aleksey Midenkov authored
      There is a need in MDEV-25292 to have both C_ALTER_TABLE and
      select_field_count in one call. Semantically creation mode and field
      count are two different things. Making creation mode negative
      constants and field count positive variable into one parameter seems
      to be a lazy hack for not making the second parameter.
      
      select_count does not make sense without alter_info->create_list, so
      the natural way is to hold it in Alter_info too. select_count is now
      stored in member select_field_count.
      f02af1d2
    • Brad Smith's avatar
      Remove FreeBSD CMake file (#2247) · 5369df74
      Brad Smith authored
      FreeBSD has libexecinfo as a system library.
      5369df74
  2. 30 Aug, 2022 12 commits
    • Marko Mäkelä's avatar
      Merge 10.10 into 10.11 · fe1f8f2c
      Marko Mäkelä authored
      fe1f8f2c
    • Marko Mäkelä's avatar
      Merge 10.9 into 10.10 · e71aca82
      Marko Mäkelä authored
      e71aca82
    • Marko Mäkelä's avatar
      Merge 10.8 into 10.9 · 50d6966c
      Marko Mäkelä authored
      50d6966c
    • Marko Mäkelä's avatar
      Merge 10.7 into 10.8 · c8cd162a
      Marko Mäkelä authored
      c8cd162a
    • Marko Mäkelä's avatar
      Merge 10.6 into 10.7 · b86be02e
      Marko Mäkelä authored
      b86be02e
    • Marko Mäkelä's avatar
      Merge 10.5 into 10.6 · f410974f
      Marko Mäkelä authored
      f410974f
    • Marko Mäkelä's avatar
      Merge 10.4 into 10.5 · 29fa9bce
      Marko Mäkelä authored
      29fa9bce
    • Marko Mäkelä's avatar
      Merge 10.3 into 10.4 · 7e574eb5
      Marko Mäkelä authored
      7e574eb5
    • Marko Mäkelä's avatar
      MDEV-13888: innodb_fts.innodb_fts_plugin failed · 57739ae9
      Marko Mäkelä authored
      Add ORDER BY to make the test deterministic.
      
      Add FLUSH TABLES to avoid crash recovery warnings about the table
      mysql.plugin. This tends to occur on Valgrind, where the server
      shutdown could presumably time out, resulting in a forced kill.
      57739ae9
    • Marko Mäkelä's avatar
      MDEV-29409 Buffer overflow in my_wc_mb_filename() on RENAME TABLE · 422f3204
      Marko Mäkelä authored
      dict_table_rename_in_cache(), dict_table_get_highest_foreign_id():
      Reserve sufficient space for the fkid[] buffer, and ensure that the
      fkid[] will be NUL-terminated.
      
      The fkid[] must accommodate both the database name (which is already
      encoded in my_charset_filename) and the constraint name
      (which must be converted to my_charset_filename) so that we can check
      if it is in the format databasename/tablename_ibfk_1 (all encoded in
      my_charset_filename).
      422f3204
    • anson1014's avatar
      Ensure that source files contain only valid UTF8 encodings (#2188) · 966d22b7
      anson1014 authored
      Modern software (including text editors, static analysis software,
      and web-based code review interfaces) often requires source code files
      to be interpretable via a consistent character encoding, with UTF-8 or
      ASCII (a strict subset of UTF-8) as the default. Several of the MariaDB
      source files contain bytes that are not valid in either the UTF-8 or
      ASCII encodings, but instead represent strings encoded in the
      ISO-8859-1/Latin-1 or ISO-8859-2/Latin-2 encodings.
      
      These inconsistent encodings may prevent software from correctly
      presenting or processing such files. Converting all source files to
      valid UTF8 characters will ensure correct handling.
      
      Comments written in Czech were replaced with lightly-corrected
      translations from Google Translate. Additionally, comments describing
      the proper handling of special characters were changed so that the
      comments are now purely UTF8.
      
      All new code of the whole pull request, including one or several files
      that are either new files or modified ones, are contributed under the
      BSD-new license. I am contributing on behalf of my employer
      Amazon Web Services, Inc.
      Co-authored-by: default avatarAndrew Hutchings <andrew@linuxjedi.co.uk>
      966d22b7
    • Marko Mäkelä's avatar
      MDEV-29258 Failing assertion for name length on RENAME TABLE · b2609038
      Marko Mäkelä authored
      trx_undo_page_report_rename(): Use the correct maximum length of
      a table name. Both the database name and the table name can be up to
      NAME_CHAR_LEN (64 characters) times 5 bytes per character in the
      my_charset_filename encoding. They are not encoded in UTF-8!
      
      fil_op_write_log(): Reserve the correct amount of log buffer for
      a rename operation. The file name will be appended by
      mlog_catenate_string().
      
      rename_file_ext(): Reserve a large enough buffer for the file names.
      b2609038
  3. 29 Aug, 2022 3 commits
  4. 28 Aug, 2022 1 commit
  5. 27 Aug, 2022 1 commit
  6. 26 Aug, 2022 5 commits
    • Alexander Barkov's avatar
    • tmokmss's avatar
      MDEV-18873 Server crashes in Compare_identifiers::operator or in... · 827b049e
      tmokmss authored
      MDEV-18873 Server crashes in Compare_identifiers::operator or in my_strcasecmp_utf8 upon ADD PERIOD IF NOT EXISTS with empty name
      
      empty identifier specified as `` ends up with a NULL LEX_CSTRING::str in lexer.
      This is not considered correct in upper layers, for example in Compare_identifiers::operator().
      Empty column name is usually avoided by a check_column_name() call while parsing,
      and period name matches the column name completely.
      Hence, this fix uses the mentioned call for verification, too.
      827b049e
    • Marko Mäkelä's avatar
      MDEV-29383 Assertion mysql_mutex_assert_owner(&log_sys.flush_order_mutex) failed in mtr_t::commit() · 0fbcb0a2
      Marko Mäkelä authored
      In commit 0b47c126 (MDEV-13542)
      a few calls to mtr_t::memo_push() were moved before a write latch
      on the page was acquired. This introduced a race condition:
      
      1. is_block_dirtied() returned false to mtr_t::memo_push()
      2. buf_page_t::write_complete() was executed, the block marked clean,
      and a page latch released
      3. The page latch was acquired by the caller of mtr_t::memo_push(),
      and mtr_t::m_made_dirty was not set even though the block is in
      a clean state.
      
      The impact of this race condition is that crash recovery and backups
      may fail.
      
      btr_cur_latch_leaves(), btr_store_big_rec_extern_fields(),
      btr_free_externally_stored_field(), trx_purge_free_segment():
      Acquire the page latch before invoking mtr_t::memo_push().
      This fixes the regression caused by MDEV-13542.
      
      Side note: It would suffice to set mtr_t::m_made_dirty at the time
      we set the MTR_MEMO_MODIFY flag for a block. Currently that flag is
      unnecessarily set if a mini-transaction acquires a page latch on
      a page that is in a clean state, and will not actually modify the block.
      This may cause unnecessary acquisitions of log_sys.flush_order_mutex
      on mtr_t::commit().
      
      mtr_t::free(): If the block had been exclusively latched in this
      mini-transaction, set the m_made_dirty flag so that the flush order mutex
      will be acquired during mtr_t::commit(). This should have been part of
      commit 4179f93d (MDEV-18976).
      It was necessary to change mtr_t::free() so that
      WriteOPT_PAGE_CHECKSUM::operator() would be able to avoid writing
      checksums for freed pages.
      0fbcb0a2
    • Daniel Black's avatar
      mariabackup: remove MySQL wording · 0324bde8
      Daniel Black authored
      0324bde8
    • Daniel Black's avatar
      MDEV-23607 MariaBackup - align required GRANTS to cmd options · 79b58f1c
      Daniel Black authored
      Since the 10.5 split of the privileges, the required GRANTs
      for various mariabackup operations has changed.
      
      In the addition of tests, a number of mappings where incorrect:
      
      The option --lock-ddl-per-table didn't require connection admin.
      
      The option --safe-slave-backup requires SLAVE MONITOR even without
      the --no-lock option.
      79b58f1c
  7. 25 Aug, 2022 3 commits
    • Igor Babaev's avatar
      MDEV-29350 Crash when IN predicand is used in eliminated GROUP BY clause · 94e3f02d
      Igor Babaev authored
      This bug affected some queries with an IN/ALL/ANY predicand or an EXISTS
      predicate whose subquery contained a GROUP BY clause that could be
      eliminated. If this clause used a IN/ALL/ANY predicand whose left operand
      was a single-value subquery then execution of the query caused a crash of
      the server after invokation of remove_redundant_subquery_clauses().
      The crash was caused by an attempt to exclude the unit for the single-value
      subquery from the query tree for the second time by the function
      Item_subselect::eliminate_subselect_processor().
      
      This bug had been masked by the bug MDEV-28617 until a fix for the latter
      that properly excluded units was pushed into 10.3.
      
      Approved by Oleksandr Byelkin <sanja@mariadb.com>
      94e3f02d
    • Marko Mäkelä's avatar
      Merge 10.5 into 10.6 · 76bb671e
      Marko Mäkelä authored
      76bb671e
    • Marko Mäkelä's avatar
      Merge 10.4 into 10.5 · 9929301e
      Marko Mäkelä authored
      9929301e