Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MDEV-31541: Optimize calls to build_table_filenames for CREATE TABLE #2696

Open
wants to merge 1 commit into
base: 11.2
Choose a base branch
from

Conversation

an3l
Copy link
Collaborator

@an3l an3l commented Jul 15, 2023

  • In order to optimize the call of ha_table_exists() for CREATE statement that for single statement has 2 paths from mysql_create_table(() that are called sequentually:
sequenceDiagram
    box create table query
        participant mysql_create_table as mysql_create_table
        participant open_and_lock_tables as open&lock tbl
        participant open_tables as open tbl
        participant lock_table_names as lock tbl names
        participant upgrade_lock_if_not_exists as upgrade lock if not exists
        participant ha_table_exists as ha_table_exists
        participant mysql_create_table_no_lock as create without lock
        participant build_table_filename as build tbl filename
        participant create_table_impl as implicit create
    end
    autonumber
    Note left of mysql_create_table:Query
    mysql_create_table->>+open_and_lock_tables: 
    open_and_lock_tables->>open_tables: 
    open_tables->>lock_table_names: 
    lock_table_names->>+upgrade_lock_if_not_exists: 
    upgrade_lock_if_not_exists->>+ha_table_exists: 
    Note over upgrade_lock_if_not_exists, ha_table_exists: pdate HA_CREATE_INFO <br>with table_path and table_exists <br> call here <br> build_table_filename
    ha_table_exists->>+build_table_filename: Optimized
    activate build_table_filename
    deactivate build_table_filename
    build_table_filename-->>ha_table_exists: 
    ha_table_exists-->>-mysql_create_table: Return to caller
    Note over ha_table_exists, mysql_create_table: Path 1
    mysql_create_table->>+mysql_create_table_no_lock: 
    mysql_create_table_no_lock->>+build_table_filename: Optimized
    Note over mysql_create_table_no_lock, build_table_filename: Use HA_CRETE_INFO struct
    activate build_table_filename
    deactivate build_table_filename
    mysql_create_table_no_lock->>create_table_impl: 
    create_table_impl--xha_table_exists: Optimized (no call)
    Note over create_table_impl, ha_table_exists: Use HA_CRETE_INFO struct
    ha_table_exists--x+build_table_filename: Optimized (no call)
    create_table_impl-->+mysql_create_table: Return to caller
    Note over create_table_impl, mysql_create_table: Path 2
  • We are creating the new members of HA_CREATE_INFO that are updated after first call of ha_table_exists() and used in the place where second invocation of function was done.

    • Handling of case for CREATE ...SELECT FROM is added too with early call of ha_table_exists instead from ha_create.
    • Since or replace [like] , if not exists and lock tables, have different paths invocation that are different from Path 1, we are leaving the ha_table_exists() call for that cases, without optimization.
  • To optimize build_table_filename call is done in Path 1 from upgrade_lock_if_not_exists by saving the path and length, that is reused in ha_table_exists(), while there is special handling for views that still need to call the function from within ha_table_exists(). Optimization is done by eliminating the call for Path 2.

    • Special cases are replace or if not exists ddl that do not use Path 1 but Path2 only, without optimization
    • Special case is CREATE..SELECT without optimization.

Reviewer: [email protected]

  • The Jira issue number for this PR is: MDEV-31541

Description

How can this PR be tested?

I have tested the PR using debug traces and noted optimization of calls for CREATE TABLE in ha_table_exists(), as well as build_table_filenames() by comparing the trace files with/without PR.
Here is the test case

--echo # 
--echo # MDEV-31541: Optimize calls to build_table_filenames for CREATE TABLE
--echo # 

--source include/have_debug.inc
--source include/have_debug_sync.inc
select @@debug_dbug;
set @old_debug= @@debug_dbug;
select @old_debug;
set debug_dbug= "d:t:i:o,/tmp/anel.trace";
select @@debug_dbug;
#set debug_sync='create_table_before_check_if_exists SIGNAL parked WAIT_FOR go';
Create table t(t int);
drop table t;

Basing the PR against the correct MariaDB version

  • [ x] This is a new feature and the PR is based against the latest MariaDB development branch.
  • This is a bug fix and the PR is based against the earliest maintained branch in which the bug can be reproduced.

PR quality check

  • [ x] I checked the CODING_STANDARDS.md file and my PR conforms to this where appropriate.
  • For any trivial modifications to the PR, I am ok with the reviewer making the changes themselves.

@an3l an3l added enhancement MariaDB Foundation Pull requests created by MariaDB Foundation labels Jul 15, 2023
@an3l an3l added this to the 11.2 milestone Jul 15, 2023
@an3l an3l requested a review from montywi July 15, 2023 08:59
- In order to optimize the call of `ha_table_exists()` for `CREATE`
statement that for single statement has 2 paths from
`mysql_create_table(()` that are called sequentually:
- Path 1
```
 mysql_create_table
  --> open_and_lock_tables
        --> open_tables
              --> lock_table_names
                    --> upgrade_lock_if_not_exists
                          --> ha_table_exists()
                                --> build_table_filename
```

- Path 2:
```
 mysql_create_table
   --> mysql_create_table_no_lock
         --> build_table_filename
               --> create_table_impl
                     --> ha_table_exists()
```

- We are creating the new members of HA_CREATE_INFO that are updated
after first call of `ha_table_exists()` and used in the place where second
invocation of function was done.
  - Handling of case for `CREATE ...SELECT FROM` is added too with early
    call of `ha_table_exists` instead from `ha_create`.
  - Since `or replace [like]` , `if not exists` and `lock tables`,
    have different paths invocation that are different from Path 1, we are
    leaving the `ha_table_exists()` call for that cases, without
    optimization.

- To optimize `build_table_filename` call is done in Path 1 from
  `upgrade_lock_if_not_exists` by saving the path and length, that is
  reused in `ha_table_exists()`, while there is special handling for
  views that still need to call the function from within
  `ha_table_exists()`. Optimization is done by eliminating the call for
  Path 2.
  - Special cases are `replace` or `if not exists` ddl that do not use
    Path 1 but Path2 only, without optimization
  - Special case is `CREATE..SELECT` without optimization.

Reviewer: <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement MariaDB Foundation Pull requests created by MariaDB Foundation
2 participants