1. 26 Jul, 2022 12 commits
    • Brandon Nesterenko's avatar
      MDEV-20122: Deprecate MASTER_USE_GTID=Current_Pos to favor new MASTER_DEMOTE_TO_SLAVE option · 90c3b283
      Brandon Nesterenko authored
      New Feature:
      ========
      This feature adds a safe replacement to the
      MASTER_USE_GTID=Current_Pos option for CHANGE MASTER TO as
      MASTER_DEMOTE_TO_SLAVE=<bool>. The use case of Current_Pos is to
      transition a master to become a slave; however, can break
      replication state if the slave executes local transactions due to
      actively updating gtid_current_pos with gtid_binlog_pos and
      gtid_slave_pos.
      
      MASTER_DEMOTE_TO_SLAVE changes this use case by forcing users to set
      Using_Gtid=Slave_Pos and merging gtid_binlog_pos into gtid_slave_pos
      once at CHANGE MASTER TO time. Note that if gtid_slave_pos is more
      recent than gtid_binlog_pos (as in the case of chain replication),
      the replication state should be preserved.
      
      Additionally, deprecate the `Current_Pos` option of MASTER_USE_GTID
      to suggest the safe alternative option MASTER_DEMOTE_TO_SLAVE=TRUE.
      
      Reviewed By:
      ============
      Andrei Elkin <andrei.elkin@mariadb.com>
      90c3b283
    • Brandon Nesterenko's avatar
      MDEV-19801: Change defaults for CHANGE MASTER TO so that GTID-based... · 5ab5ff08
      Brandon Nesterenko authored
      MDEV-19801: Change defaults for CHANGE MASTER TO so that GTID-based replication is used by default if master supports it
      
      This commit makes replicas crash-safe by default by changing the
      Using_Gtid value to be Slave_Pos on a fresh slave start and after
      RESET SLAVE is issued. If the primary server does not support GTIDs
      (i.e., version < 10), the replica will fall back to Using_Gtid=No on
      slave start and after RESET SLAVE.
      
      The following additional informational messages/warnings are added:
      
       1. When Using_Gtid is automatically changed. That is, if RESET
      SLAVE reverts Using_Gtid back to Slave_Pos, or Using_Gtid is
      inferred to No from a CHANGE MASTER TO given with log coordinates
      without MASTER_USE_GTID.
       2. If options are ignored in CHANGE MASTER TO. If CHANGE MASTER TO
      is given with log coordinates, yet also specifies
      MASTER_USE_GTID=Slave_Pos, a warning message is given that the log
      coordinate options are ignored.
      
      Additionally, an MTR macro has been added for RESET SLAVE,
      reset_slave.inc, which provides modes/options for resetting a slave
      in log coordinate or gtid modes. When in log coordinates mode, the
      macro will execute CHANGE MASTER TO MASTER_USE_GTID=No after the
      RESET SLAVE command. When in GTID mode, an extra parameter,
      reset_slave_keep_gtid_state, can be set to reset or preserve the
      value of gtid_slave_pos.
      
      Reviewed By:
      ===========
      Andrei Elkin <andrei.elkin@mariadb.com>
      5ab5ff08
    • Sergei Petrunia's avatar
      MDEV-28929: Plan selection takes forever with MDEV-28852 ... · 8c2faad5
      Sergei Petrunia authored
      Part #2: Extend heuristic pruning to use multiple tables as the
      "Model tables".
      
      Before the patch, heuristic pruning uses only one "Model table":
      The table which had the best cost AND record became the "Model table".
      After that, if a table's cost and record were both worse than
      those of the Model Table, the table would be pruned away.
      
      This didn't work well when the first table (the optimizer sorts them
      by record_count) had low record_count but relatively high cost: nothing
      could be pruned afterwards.
      
      The patch adds the two additional "Model tables": one with the least
      cost and the other with the least record_count.
      (In both cases, a table can be pruned away if BOTH its cost and
      record_count are worse than those of a Model table)
      
      The new pruning is active when the number of tables to consider for
      the prefix is higher than @@optimizer_extra_pruning_depth.
      
      One can see the new pruning in the Optimizer Trace as
      - "pruned_by_heuristic":"min_record_count", or
      - "pruned_by_heuristic":"min_read_time".
      Old heuristic pruning shows as "pruned_by_heuristic":1.
      8c2faad5
    • Oleg Smirnov's avatar
      MDEV-28881 Fix memory leak caused by STL usage · afadd58e
      Oleg Smirnov authored
      Dep_analysis_context::create_unique_pseudo_key_if_needed() was using
      std::set which allocated memory outside MEM_ROOT and so required
      explicit deallocation. This has been solved by replacing std::set with
      MY_BITMAP which is allocated on MEM_ROOT
      afadd58e
    • Oleg Smirnov's avatar
      MDEV-28881 Server crash in Dep_analysis_context::create_table_value · c03d50fc
      Oleg Smirnov authored
      SELECT_LEX::first_select()->join is NULL for degenerate derived tables
      which are known to have just one row and so were already materialized
      by the optimizer.
      This commit adds a check for this.
      c03d50fc
    • Oleg Smirnov's avatar
      MDEV-26278 Add functionality to eliminate derived tables from the query · 7f0201a2
      Oleg Smirnov authored
      Elimination of unnecessary tables from SQL queries is already present
      in MariaDB. But it only works for regular tables and not for derived ones.
      
      Imagine we have a view:
        CREATE VIEW v1 AS SELECT a, b, max(c) AS maxc FROM t1 GROUP BY a, b
      
      Due to "GROUP BY a, b" the values of combinations {a, b} are unique,
      and this fact can be treated as like derived table "v1" has a unique key
      on fields {a, b}.
      
      Suppose we have a SQL query:
        SELECT t2.* FROM t2 LEFT JOIN v1 ON t2.a=v1.a and t2.b=v1.b
      
      1. Since {v1.a, v1.b} is unique and both these fields are bound to t2,
         "v1" is functionally dependent on t2.
         This means every record of "t2" will be either joined with
         a single record of "v1" or NULL-complemented.
      2. No fields of "v1" are present on the SELECT list
      
      These two facts allow the server to completely exclude (eliminate)
      the derived table "v1" from the query.
      7f0201a2
    • Monty's avatar
      Reduced size of POSITION · 1f0187ff
      Monty authored
      Replaced Cost_estimate prefix_cost with a double as prefix_cost was
      only used to store and retrive total prefix cost.
      
      This also speeds up things (a bit) as don't have to call
      Cost_estimate::total_cost() for every access to the prefix_cost.
      
      Sizeof POSITION decreased from 304 to 256.
      1f0187ff
    • Monty's avatar
      Added current_cost and best_cost to optimizer trace when pruning by cost · fbbc6345
      Monty authored
      This helps a lot when trying to find out why a table combination was pruned
      fbbc6345
    • Monty's avatar
      Added EQ_REF chaining to the greedy_optimizer · 515b9ad0
      Monty authored
      MDEV-28073 Slow query performance in MariaDB when using many table
      
      The idea is to prefer and chain EQ_REF tables (tables that uses an
      unique key to find a row) when searching for the best table combination.
      This significantly reduces row combinations that has to be examined.
      This is optimization is enabled when setting optimizer_prune_level=2
      (which is now default).
      
      Implementation:
      - optimizer_prune_level has a new level, 2, which enables EQ_REF
        optimization in addition to the pruning done by level 1.
        Level 2 is now default.
      - Added JOIN::eq_ref_tables that contains bits of tables that could use
        potentially use EQ_REF access in the query.  This is calculated
        in sort_and_filter_keyuse()
      
      Under optimizer_prune_level=2:
      - When the greedy_optimizer notices that the preceding table was an
        EQ_REF table, it tries to add an EQ_REF table next. If an EQ_REF
        table exists, only this one will be considered at this level.
        We also collect all EQ_REF tables chained by the next levels and these
        are ignored on the starting level as we have already examined these.
        If no EQ_REF table exists, we continue as normal.
      
      This optimization speeds up the greedy_optimizer combination test with
      ~25%
      
      Other things:
      - I ported the changes in MySQL 5.7 to greedy_optimizer.test to MariaDB
        to be able to ensure we can handle all cases that MySQL can do.
      - I have run all tests with --mysqld=--optimizer_prune_level=1 to verify that
        there where no test changes.
      515b9ad0
    • Monty's avatar
      Remove unnecessary testing of join dependency when sorting tables · 6e7376eb
      Monty authored
      The dependency checking is not needed when using
      best_extension_by_limited_search() as this function ensures
      that we don't use tables that are depending on any of the remaning
      tables.
      6e7376eb
    • Monty's avatar
      Added get_allowed_nj_tables() to speed up gready_search() · 318a74f1
      Monty authored
      "Get the tables that one is allowed to have as the next table in the
      current plan"
      
      Main author: Sergei Petrunia <sergey@mariadb.com>
      Co author: Monty
      318a74f1
    • Monty's avatar
      Improve pruning in greedy_search by sorting tables during search · b3c74bdc
      Monty authored
      MDEV-28073 Slow query performance in MariaDB when using many tables
      
      The faster we can find a good query plan, the more options we have for
      finding and pruning (ignoring) bad plans.
      
      This patch adds sorting of plans to best_extension_by_limited_search().
      The plans, from best_access_path() are sorted according to the numbers
      of found rows.  This allows us to faster find 'good tables' and we are
      thus able to eliminate 'bad plans' faster.
      
      One side effect of this patch is that if two tables have equal cost,
      the table that which was used earlier in the query is preferred.
      This allows users to improve plans by reordering eq_ref tables in the
      order they would like them to be uses.
      
      Result changes caused by the patch:
      - Traces are different as now we print the cost for using tables before
        we start considering them in the plan.
      - Table order are changed for some plans. In most cases this is because
        the plans are equal and tables are in this case sorted according to
        their usage in the original query.
      - A few plans was changed as the optimizer was able to find a better
        plan (that was pruned by the original code).
      
      Other things:
      
      - Added a new statistic variable: "optimizer_join_prefixes_check_calls",
        which counts number of calls to best_extension_by_limited_search().
        This can be used to check the prune efficiency in greedy_search().
      - Added variable "JOIN_TAB::embedded_dependent" to be able to handle
        XX IN (SELECT..) in the greedy_optimizer.  The idea is that we
        should prune a table if any of the tables in embedded_dependent is
        not yet read.
      - When using many tables in a query, there will be some additional
        memory usage as we need to pre-allocate table of
        table_count*table_count*sizeof(POSITION) objects (POSITION is 312
        bytes for now) to hold the pre-calculated best_access_path()
        information.  This memory usage is offset by the expected
        performance improvement when using many tables in a query.
      - Removed the code from an earlier patch to keep the table order in
        join->best_ref in the original order.  This is not needed anymore as we
        are now sorting the tables for each best_extension_by_limited_search()
        call.
      b3c74bdc
  2. 25 Jul, 2022 1 commit
    • Sergei Petrunia's avatar
      Revert the commit with MDEV-28926: Add time spent on query optimizer to JSON ANALYZE · 213772f9
      Sergei Petrunia authored
      It will go into 10.11.
      
      Author: Luis Eduardo Oliveira Lizardo <108760288+mariadb-LuisLizardo@users.noreply.github.com>
      Date:   Mon Jul 18 17:48:01 2022 +0200
      
          MDEV-28926 Add time spent on query optimizer to JSON ANALYZE (#2193)
      
          * Add query optimizer timer to ANALYZE FORMAT=JSON
      
          * Adapt tests and results
      
          * Change logic to always close the writer after printing query blocks
      213772f9
  3. 18 Jul, 2022 1 commit
  4. 08 Jul, 2022 1 commit
  5. 29 Jun, 2022 5 commits
  6. 28 Jun, 2022 8 commits
  7. 27 Jun, 2022 12 commits