Home - Waterfall Grid T-Grid Console Builders Recent Builds Buildslaves Changesources - JSON API - About

Console View


Categories: connectors experimental galera main
Legend:   Passed Failed Warnings Failed Again Running Exception Offline No data

connectors experimental galera main
Dave Gosselin
MDEV-36125 Cleanup ahead of [NO_]INDEX_MERGE

Introduces code cleanup and small refactorings, such as:

  - Flip keys_to_use.is_clear_all() and de-dent
  - Rename best_trp to best_read_plan
  - Fix key_parts assignment spacing
  - find_shortest_key now keeps happy path to the left
  - Cleanup in the get_best_ror_intersect, remove_nonrange_trees,
    and restore_nonrange_trees functions
  - Reorganization of locals within test_quick_select
Nikita Malyavin
MDEV-37394 SIGSEGV in handler::ha_external_lock on CREATE GTT ... INNODB SELECT

The local table handler of GTT wasn't properly unlocked before drop on
transaction commit.

It should normally happen in THD::free_temporary_table:
mysql_lock_remove(this, lock, table)

But THD::lock is not the one containing this table's lock - it's m_plock
of select_create.

Only transactional tmp tables are locked, so it wasn't a problem for
myisam.

Solution:
Unlock the tables before implicit commit.
Nikita Malyavin
rename HA_LEX_CREATE_GLOBAL_TMP_TABLE -> HA_LEX_CREATE_SHARED_ACCESS_TMP_TABLE
Sergei Petrunia
MDEV-36125 Cleanup ahead of [NO_]INDEX_MERGE, part 2.

change
if (key)
{
  LOTS-OF-CODE;
}

into

  if (!key)
    continue;
  LOTS-OF-CODE;

Also some endspace removal.
Nikita Malyavin
MDEV-37673 Changing server_id results in ignoring past created temporary tables

A table definition key is constructed as db+name+server_id+connection_id
for temporary tables.

Since the key is stored in each table, it results in a failed lookup
under different server_id assigned.

server_id, in context of table definition key, is important for parallel
replication, but is meaningless on user connections, so we have to
ignore it.

An easy way to ignore it is to construct tmp_table_def_key with
server_id=0 on user connections, since valid server_id values start from
1.
Nikita Malyavin
MDEV-37395 SIGSEGV on CREATE TABLE ... SELECT where source table is a GTT

select_create::send_eof commits a transaction, leaving a dangling
pointer to a ON COMMIT DELETE ROWS table (TABLE*).

There is a lot of access to that pointer after send_eof (also in
transaction error handling, namely abort_result_set), making it very
problematic to build a flow which would work correctly with
ON COMMIT DELETE ROWS.

So this is worked around by manually calling commit_global_tmp_tables in
the create table code in the select case.
Nikita Malyavin
MDEV-35915 Global temporary tables: ignore GTT in FLUSH TABLE
Nikita Malyavin
MDEV-37673 Changing server_id results in ignoring past created temporary tables

A table definition key is constructed as db+name+server_id+connection_id
for temporary tables.

Since the key is stored in each table, it results in a failed lookup
under different server_id assigned.

server_id, in context of table definition key, is important for parallel
replication, but is meaningless on user connections, so we have to
ignore it.

An easy way to ignore it is to construct tmp_table_def_key with
server_id=0 on user connections, since valid server_id values start from
1.
Nikita Malyavin
MDEV-15990 Refactor write_record and fix idempotent replication

See also MDEV-30046.

Idempotent write_row works same as REPLACE: if there is a duplicating
record in the table, then it will be deleted and re-inserted, with the
same update optimization.

The code in Rows:log_event::write_row was basically copy-pasted from
write_record.

What's done:
REPLACE operation was unified across replication and sql. It is now
representred as a Write_record class, that holds the whole state, and allows
re-using some resources in between the row writes.

Replace, IODKU and single insert implementations are split across different
methods, reluting in a much cleaner code.

The entry point is preserved as a single Write_record::write_record() call.
The implementation to call is chosen on the constructor stage.

This allowed several optimizations to be done:
1. The table key list is not iterated for every row. We find last unique key in
the order of checking once and preserve it across the rows. See last_uniq_key().
2. ib_handler::referenced_by_foreign_key acquires a global lock. This call was
done per row as well. Not all the table config that allows optimized replace is
folded into a single boolean field can_optimize. All the fields to check are
even stored in a single register on a 64-bit platform.
3. DUP_REPLACE and DUP_UPDATE cases now have one less level of indirection
4. modified_non_trans_tables is checked and set only when it's really needed.
5. Obsolete bitmap manipulations are removed.

Also:
* Unify replace initialization step across implementations:
  add prepare_for_replace and finalize_replace
* alloca is removed in favor of mem_root allocation. This memory is reused
  across the rows.
* An rpl-related callback is added to the replace branch, meaning that an extra
check is made per row replace even for the common case. It can be avoided with
templates if considered a problem.
Nikita Malyavin
post-review fixes
Brandon Nesterenko
MDEV-34705/MDEV-37487: Binlog-in-engine rpl_mysqlbinlog_slave_consistency tests

This patch creates binlog-in-engine MTR test equivalents for
rpl_mysqlbinlog_slave_consistency. One new test is a basic variant,
which tests the exact same behavior as the rpl test version, and the
other uses out-of-band binlogging to ensure the slave and mysqlbinlog
event replay is consistent. The rpl.rpl_mysqlbinlog_slave_consistency
test validates that the domain and server id filtering logic of
mariadb-binlog matches that of a replica server. The purpose of this
patch is then to ensure that the expected filtering behavior is still
consistent when using binlog-in-innodb.

Changes to the replication-side of tests are as follows:
1. So the binlog_in_engine tests can find the correct include files,
    the paths to the files from the `source` commands are made absolute
2. To support the out-of-band binlogging variant, the
    tables/transactions in sql_multisource.inc and
    sql_out_of_order_gtid.inc are extended with a configurable size
    longblob, so the OOB test can use large transactions.
3. To add some complexity for the OOB testing, the transactions in
    sql_multisource.inc and sql_out_of_order_gtid.inc are staggered
    using different connections and run concurrently so the OOB data
    is overlapping. This is done for cases using different domain ids
    as well as the same domain id (though commit order is still
    enforced).
Sergei Petrunia
MDEV-36125 [NO_]INDEX_MERGE Hint: Make code in best_access_path() cleaner
Nikita Malyavin
MDEV-37382 crash on CREATE OR REPLACE GTT under LOCK TABLES.

CREATE OR REPLACE GTT under LOCK TABLES was forbidden in the original
commit, as a result of rebase, however not in all the relevant places.

Crash analysis reveals that a failure is a result of a wrong TABLE
handle choice:

CREATE can open another table when CREATE...SELECT is
used, i.e. for a purpose of data reading. This is why the heuristic is
choosing to open a local table handle of Global temporary table in
CREATE TABLE.

It turns out, that CREATE OR REPLACE is another special case, when the
original table can be opened several times. Moreover, LOCK TABLES
collides with the latter as another corner case.

The solution in this patch is non-uniform: it tries to handle
unsupported cases and report error, but even that wasn't trivial.

a) CREATE OR REPLACE requires a careful decision on whether to open a
parent (global) TABLE handle, or a child (local).
It should choose a child when AS SELECT is used, for both source and
sink.
b) It also shouldn't end up in creating a new child,
if the table to replace is opened (in MDL_SHARED_UPGRADEABLE mode).

c) Additionally, LOCK TABLES + CREATE OR REPLACE end up re-opening
tables a few times with cumbersome locking rules. This becomes a big
problem, when a table was categorized as normal, and then it
re-opened as a temporary table. From open_tables, it's hard to
determine, which table should be opened in every case.

d) At the same time, CREATE OR REPLACE ends up in starting/ending a
transaction more than once, making it hard to work
with ON COMMIT DELETE ROWS (ending up with dangling pointers).

Overall in this commit:
1. Learn to determine the table to REPLACE is opened. We need a parent
table. This can be hackishly determined by MDL lock type,
see is_open_for_create_replace.
This fixes case (b).

2. Forbid CREATE OR REPLACE with ON COMMIT DELETE ROWS tables, even if
they are a part of AS SELECT.
This addresses (d)

3. Open a parent table if MYSQL_OPEN_GET_NEW_TABLE (a part of
MYSQL_OPEN_REOPEN) is in flags.

4. Forbid using global temporary tables under
LOCK TABLES + CREATE OR REPLACE + SELECT/VALUES

3 and 4 together address (c).

In all the rest cases, (a) is supported.
Sergei Petrunia
MDEV-36125 [NO_]INDEX_MERGE Hint: Remove the Insufficient ROR scans warning

Review input: the warning is redundant. Neither MariaDB nor MySQL
produce warnings for similar reasons, so remove it.
Nikita Malyavin
MDEV-37666 Global temporary table can be created w/ versioning using CREATE LIKE

Turns out, alter_info->flags is not set by mysql_prepare_alter_table.
* Use create_info->options instead.

The same problem affects foreign keys. There is no single field to
check, so we'd need to loop through the keys in this case.
The same is already done for partitioning.
* Extraxt the key check-loop into Alter_info::has_foreign_keys
* Use it for partitions and global temporary tables check
Nikita Malyavin
MDEV-15990 REPLACE on a precise-versioned table returns ER_DUP_ENTRY

We had a protection against it, by allowing versioned delete if:
trx->id != table->vers_start_id()

For replace this check fails: replace calls ha_delete_row(record[2]), but
table->vers_start_id() returns the value from record[0], which is irrelevant.

The same problem hits Field::is_max, which may have checked the wrong record.

Fix:
* Refactor Field::is_max to optionally accept a pointer as an argument.
* Refactor vers_start_id and vers_end_id to always accept a pointer to the
record. there is a difference with is_max is that is_max accepts the pointer to
the
field data, rather than to the record.

Method val_int() would be too effortful to refactor to accept the argument, so
instead the value in record is fetched directly, like it is done in
Field_longlong.
Nikita Malyavin
MDEV-37595 Assertion '...' failed using HANDLER+mrg_myisam+GTT

Assertion `thd->transaction->stmt.is_empty()' failed in mysql_ha_open
when using mrg_myisam GTT.

mysql_ha_open invokes close_thread_tables itself per error handling,
even though it should be done globally in mysql_parse after statement
execution.

The right order is:
1. commit/rollback transaction
2. close tables
3. unlock

Since mysql_parse does it, there is no sense in doing this, unless it's
a sub-statement, where we might've wanted a better grain of tables
locked in case of sub-statement failure.

See also MDEV-37368 with the same fix for multi-stmt UPDATE.
Nikita Malyavin
MDEV-15990 innodb: change DB_FOREIGN_DUPLICATE_KEY to DB_DUPLICATE_KEY

during row insert

DB_FOREIGN_DUPLICATE_KEY in row_ins_duplicate_error_in_clust was
motivated by handling the cascade changes during versioned operations.

It was found though, that certain row_update_for_mysql calls could
return DB_FOREIGN_DUPLICATE_KEY, even if there's no foreign relations.

Change DB_FOREIGN_DUPLICATE_KEY to DB_DUPLICATE_KEY in
row_ins_duplicate_error_in_clust.

It will be later converted to DB_FOREIGN_DUPLICATE_KEY in
row_ins_check_foreign_constraint if needed.

Additionally, ha_delete_row should return neither. Ensure it by an
assertion.
Nikita Malyavin
MDEV-37368 Assertion failed in close_thread_tables on UPDATE referring bad field

open_tables_for_query makes a redundant cleanup, closing and
unlocking tables. This is not really needed, since a cleanup is done
globally in mysql_execute_command.

However, we might think that is can be useful in a failing substatement,
if it doesn't lead to failing a parent statement (if that is possible).

The problem with global temporary tables arises because it injects a
transaction_participant after successful open, and close_thread_tables
expects a commit before its call *unless* it's a substatement.

Solution: do a redundant cleanup after open only in substatements.
Nikita Malyavin
MDEV-37597 InnoDB: Failing assertion: table->get_ref_count() == 0 on UPDATE

close_thread_tables is called *after* ending the transaction. There is
one case when it is important - it is lookup_handler, which holds the
reference released on ha_reset(). We could just call the latter, but
better to attempt a more wholesome initialization.

Fix: call mark_tmp_table_as_free_for_reuse on trx end.
Nikita Malyavin
MDEV-37381 SIGSEGV in mysql_ha_close_table after HANDLER OPEN of GTT

The crash happens because of HANDLER CLOSE happened after GTT was
deleted on commit, which, by the way, happened implicitly after
HANDLER OPEN.

The consequences of using open handler after commit, i.e. across
different transactions, are truly unclear for any table:
the handler should require at least calling ha_reset() to re-assign to a
new transaction handler. Probably, that's not the only questionable
consequence.

For Global temporary tables, we should either close the handlers
implicitly on commit, or fail committing if an open handler exists.

If to fail committing, then global_temporary_tp has to be transformed
into 2pc, which would potentially slow the transactions.

This patch favors implicitly closes the handlers sacrificing strictness
of the behavior in favor of leaving global_temporary_tp 1pc-capable.
Nikita Malyavin
MDEV-37578 Assertion failed in flush() on ALTER TABLE GTT DISCARD TABLESPACE

IMPORT/DISCART TABLESPACE should have no effect for GTT. There is a
possibility to add a specific semantic, but for now it's Not supported.
Nikita Malyavin
MDEV-37576 Assertion `!global_table.versioned()' failed after ADD SYS VERSIONING

Assertion `!global_table.versioned()' failed
after ALTER TABLE GTT ADD SYSTEM VERSIONING.

HA_CREATE_INFO::options is only set by lexer. ALTER TABLE et al only has
table_options (though it's set a bit later).

Fix: use HA_CREATE_INFO::table_options
Nikita Malyavin
MDEV-35915 Implement Global temporary tables

Global temporary table (GTT) is a table with globally defined metadata,
but per-session data.

That is, the life duration of this data is limited with session
duration. Here we have two options:

1. ON COMMIT DELETE ROWS: a default option. The life duration of data is
transaction duration.
2. ON COMMIT PRESERVE ROWS: The life duration of data is session
duration.

# Implementation

The implementation consists of the following fundamental parts.

## Part 1: CREATE TABLE + frm format

1. Store GLOBAL TEMPORARY and ON COMMIT bits in
  create_info->table_options
2. Store higher word of create_info->table_options in frm header
3. Also disallow ON COMMIT keyword for (local) temporary tables

As a result, the bits will be available in share->db_create_options.

New Table_type enum element: TABLE_TYPE_GLOBAL_TEMPORARY (datadict.h)

## Part 2: open_table: a local data table is created on demand

On open, a session-local temporary table copy is created from a global
TABLE_SHARE. Let us refer to the former as "local data table of GTT",
and the latter as "global metadata table of GTT".

There is a number of cases, when a global metadata table is opened
instead, like ALTER, DROP, SHOW CREATE

A local data table holds:

1. A reference to that share, and holds the increased
tdc reference count.
2. An explicit MDL lock to the duration of local copy's
existence.

While at least one local data table exists
(2) guarantees that ALTER, DROP or RENAME will not happen.
(1) guarantees that a global metadata table will not be flushed

At an implementation level, a local data table is a temporary table,
invisible for a user and augmented with (1) and (2).

The reference and lock are released upon dropping this local data table,
which happens due to:
a) TRUNCATE TABLE
b) Connection close
c) If ON COMMIT DELETE ROWS is used, then on transaction commit/rollback

## Part 3: ALTER, DROP, RENAME

These operations always open a real global temporary table.

ALTER, RENAME and DROP TABLE require all local data tables to be
destroyed, thus, having no references to a modified/deleted table.
For that, they:
1. acquire an EXCLUSIVE MDL lock. To match oracle behavior,
lock_wait_timeout is 0 in ALTER TABLE.
2. Check that there is no matching local temporary table in the same
connection (which is not guaranteed by 1)

## Part 4 ON COMMIT DELETE ROWS

This clause is assumed by default, i.e. it is implicit.

When ON COMMIT DELETE ROWS, the local data table is dropped on
commit/rollback.

On table open, global_temporary_tables handlerton is injected,
implementing this behavior.

# Limitations

The following is forbidden for GTT:
system versioning
partitioning
fk
ONLINE ALTER
CREATE GLOBAL TEMPORARY under LOCK TABLES
FLUSH TABLE on Global temporary table is no-op for now

# Refactorings, details

1. Extract drop_tmp_table_share (temporary_tables.cc)
2. Extract THD::open_temporary_table_impl (temporary_tables.cc)
3. information_schema support:
x) "GLOBAL TEMPORARY" type is show in information_schema.tables
y) an artifical temporary table is hidden from SHOW TABLE STATUS

4. VIEWs are supported.
5. AS SELECT support

x) Made in Oracle style, so that the data is only inserted in the
session that creates GTT
y) ON COMMIT DELETE ROWS inserts the data for real, and then deletes
the data table on implicit commit

6. CREATE TABLE ... LIKE is supported.

7. Replication support
x) Set share->table_creation_was_logged to 0 to make the table ignored
for replication.
y) Statements with GTT involved will be logged in Row-based style
(RBR)
z) Global temporary table creation and alter/drop will be logged.
Nikita Malyavin
MDEV-15990 handle timestamp-based collisions as well

Timestamp-versioned row deletion was exposed to a collisional problem: if
current timestamp wasn't changed, then a sequence of row delete+insert could
get a duplication error. A row delete would find another conflicting history row
and return an error.

This is true both for REPLACE and DELETE statements, however in REPLACE, the
"optimized" path is usually taken, especially in the tests. There, delete+insert
is substituted for a single versioned row update. In the end, both paths end up
as ha_update_row + ha_write_row.

The solution is to handle a history collision somehow.

From the design perspective, the user shouldn't experience history rows loss,
unless there's a technical limitation.

To the contrary, trxid-based changes should never generate history for the same
transaction, see MDEV-15427.

If two operations on the same row happened too quickly, so that they happen at
the same timestamp, the history row shouldn't be lost. We can still write a
history row, though it'll have row_start == row_end.

We cannot store more than one such historical row, as this will violate the
unique constraint on row_end. So we will have to phisically delete the row if
the history row is already available.

In this commit:
1. Improve TABLE::delete_row to handle the history collision: if an update
  results with a duplicate error, delete a row for real.
2. use TABLE::delete_row in a non-optimistic path of REPLACE, where the
  system-versioned case now belongs entirely.
Rucha Deodhar
MDEV-30277: Assertion failure in Diagnostics_area::set_error_status
/ Reprepare_observer::report_error

Analysis:
Error is not reported when we hit invalid default parameter error
Fix:
Return appropriate value on error.
Nikita Malyavin
Remove parent table reference from Global temporary tables

A reference to parent table causes connection hangs in some situations.
While these situations usually signify some problem behind, it's not a
convenient behavior for users, even in case of bugs.

The only place where the parent share was accessed is checking the table
version match in TABLE_LIST::is_the_same_definition. Instead of
substituting the table to check, assign a parent tabledef_version on a
child table creation in open_global_temporary_table.

Also fixes MDEV-37594, MDEV-37656.

This commit should be squashed with a base feature commit after review.
Nikita Malyavin
MDEV-37379 Assertion `index->is_readable()' failed on REPLACE DELAYED

The assertion was failing because innodb was initialized with the trash
memory caused by incomplete LEX initialization in Delayed_indert,
particularly LEX::create_info.

We could catch that error with access to poisoned memory as well.

Tables are not used to be created in delayed insert background, so this
incompleme initialization was enough.

Solution:
1. Make a better initialization by calling lex_start in the master
thread.
2. Delayed inserts still won't work for GTTs, so forbid them.
Nikita Malyavin
MDEV-37579 use-after-free in MDL_context::release_lock on FLUSH TABLE GTT

use-after-free happens after HANDLER OPEN and two LOCK TABLES.

HANDLER locks are moved to MDL_EXPLICIT duration to avoid unlocking at
transaction end. There is a little inconsistency in operation:
1. handler->mdl_request.ticket is populated from table_list in
  mysql_ha_open
2. allegedly, it should match table_list->table->mdl_ticket
3. in mysql_ha_set_explicit_lock_duration,
  hash_tables->table->mdl_ticket was used to fix duration
4. in mysql_ha_close_table, as a result of FLUSH TABLES,
  handler->mdl_request.ticket is released.

For global temporary tables child handle, (2) is violated. There is no
lock in table->mdl_ticket, just as in any temporary table.

However, there is a lock ticket in table_list->mdl_request, because of
locked tables mode.

Solution:
use hash_tables->mdl_request.ticket in mysql_ha_set_explicit_lock_duration.
Nikita Malyavin
MDEV-37657 SIGSEGV in mysql_ha_flush on SHOW CREATE TABLE after HANDLER OPEN GTT

If handler opened with alias not matching table name:
1. commit failed (because table not found)
2. the next operation crashes if it calls mysql_ha_flush.

Fix: replace mysql_ha_close with mysql_ha_rm_tables.
Also remove error suppression, since mysql_ha_rm_tables doesn't provoke
errors.
Dave Gosselin
MDEV-36125 [NO_]INDEX_MERGE Hint

Introduces NO_INDEX_MERGE and INDEX_MERGE, which control whether or
not index merge strategies are used during query optimization.  Here
is an example query from the tests:

  SET optimizer_switch='index_merge_intersection=off';
  EXPLAIN SELECT /*+ INDEX_MERGE(t1 f4, f2) */ COUNT(*) FROM t1
  WHERE f4 = 'h' AND f2 = 2;

with the hint in place, the query plan will employ the index_merge
intersect strategy (abbreviated EXPLAIN output):

  type Extra
  index_merge Using intersect(f2,f4); Using where; Using index

The presence of the [NO_]INDEX_MERGE hint overrides the optimizer's
choice of keys during the index merge optimization.  As we see in
the above example, keys f2 and f4 and given and the optimizer will
consider only those keys for this query.

When the hint is given without any particular keys, as in
INDEX_MERGE(table), then all keys are considered.  In this case, the
cheapest index merge among the keys should be used.  When
NO_INDEX_MERGE(table) is given, then index merge is disabled for
that table.

When the hint is given with one or more keys, then only those keys
are considered.  In the case of NO_INDEX_MERGE, those keys are
excluded.  This can lead to no merged indexes at all, because
there may not be sufficient row-ordered read columns available for
consideration.

The index merge strategies of intersection, union, and sort union
cannot themselves be directly controlled via the hints.  In combination
with the optimizer switches for the same, the strategy may be
indirectly controlled but this is not guaranteed.

When the hint directs the optimizer such that insufficient ROR scans
are available, thus leading to a situation where the INDEX_MERGE hint
cannot be honored, the server will emit a warning to that effect.

In the hints module (opt_hints*{cc,h}), this commit adds some
index merge-specific functionality to make interpreting hint state
at callsites in the optimizer cleaner and more intuitive.
Particularly, we add a bit field to the table hints class which
indicates the keys that are marked by an [NO_]INDEX_MERGE hint, if
present.  A new function, index_merge_hint (and associated new
helper functions) relies on this field when interpreting index merge
hint state for the optimizer.

If there are no index merges available prior to attemping to find
a suitable union/sort union, then the optimizer will not attempt
it.  This change results in optimizer trace output which does not
include the 'analyzing_index_merge_union' block when there are no
merges.

Parts of this implementation based on MySQL commit
ebcb981807e3d91a64782e89d48e1a25622eafea
Nikita Malyavin
MDEV-35915 Global temporary tables: Enable XA

XA COMMIT/ROLLBACK is implemented. The only side-effect is a warning if
a storage engine is not transactional, like myisam.
Nikita Malyavin
MDEV-37369 SIGSEGV on NEXTVAL from Global temporary table

A check for sequence was missing during a Global temporary table open.
This check is already copy-pasted in a few places. To reduce the number
of copies, goto an existing check in open_table.
Nikita Malyavin
MDEV-37379 UBSAN invalid-bool-load on INSERT DELAYED GTT

THD::tmp_table_binlog_handled wasn't initialized, but used in
THD::mark_tmp_table_as_free_for_reuse.

Call thd.reset_for_next_command() in Delayed_insert().
Nikita Malyavin
MDEV-37378 SIGSEGV or Assertion failed on CREATE TRIGGER

SIGSEGV in MDL_ticket::has_stronger_or_equal_type and
Assertion `!table->s->tmp_table' failed in wait_while_table_is_used on
CREATE TRIGGER.

Forbid using triggers with Global temporary tables.
Nikita Malyavin
MDEV-15990 versioning: don't allow changes in the past
Nikita Malyavin
MDEV-37384 SIGSEGV on CREATE GTT ... LIKE partitioned table

Fix Global temporary tables partitioning handling.

lex->part_info is not always set, amid alter_info->partition_flags.
In normal CREATE, we have alter_info->partition_flags. In CREATE LIKE,
mysql_prepare_create_alter_table doesn't set it, but we still can guess
partitions by thd->work_part_info.
Nikita Malyavin
MDEV-35915 Global temporary tables: support LOCK TABLES and mariabackup

Locked tables list stores a global GTT descriptor.

Statements ignore it and as usual during table open.
Nikita Malyavin
MDEV-37383 crash in end_read_record after REPAIR of Global temporary table

Admin commands need a better thought support, so for now they will be
left unimplemented.
Nikita Malyavin
MDEV-35915 Global temporary tables: separate the tmp tables namespace

Global temporary tables will exist solely in global tables namespace.
This should allow creating and using local temporary tables while open
global temporary tables' descriptors with the same name exist.