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
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-37596 enforce_storage_engine has an effect on child global temporary tables

Ignore the option when creating child global temporary tables.
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-37958 SIGSEGV in ha_mroonga::storage_create_foreign_key on INSERT

More a mroonga bug, but doesn't reproduce otherwise.
Use a correct alter_info, not the one stored in lex.
Nikita Malyavin
MDEV-38151 GTT: missing FUNCTION support

open_temporary_table[s] defaulted to searching only local temporary
tables (Tmp_table_kind::TMP). When in function, a temporary table was
"carefully re-opened": it was closed and then opened again, with
open_temporary_table. This resulted in "table not found".

The correct key in most cases is Tmp_table_kind::ANY.
In some cases it should be Tmp_table_kind::TMP:
* When operation is not supported for GTT (ANALYZE/REPAIR)
* When a global handle should be opened (CREATE VIEW)
* If it's a re-open

Apart from this bug, it caused a global temporary table to be always
opened through open_tables, meaning that tdc was queried first. This
means that the earlier code never relied on pre-opening
temporary tables.

This means that all the commands that follow the default
open_temporary_tables path in mysql_execute_command (the standard
temporary tables pre-opening) should be able to handle child GTT share.

This wasn't so for TRUNCATE, hence the changes in sql_truncate.cc.

Also, this broke the lookup order: first a local temporary table should
be looked up. If it doesn't exist, only then a global temporary table
should be looked up.
To fix the latter -- push back global temporary tables' local shares and
push front local temporary tables.

To support push_front, All_tmp_tables_list declaration is changed. It
should use I_P_List_fast_push_back adapter, which adds T **m_last to the
list body.
Nikita Malyavin
MDEV-37896 global_temporary_table tests are not stable on 2nd run

replace con_id and purge logs
Nikita Malyavin
MDEV-37871 SIGSEGV in I_P_List_iterator on DROP DATABASE test

Happens on dropping the database on a newly created conneciton.

temporary_tables can be NULL in THD::global_tmp_drop_database.
Nikita Malyavin
MDEV-37681 SIGSEGV on TRUNCATE GTT after failed RENAME under LOCK TABLE

WHILE RENAME was covered in the reference counting feature,
ALTER TABLE REMANE was missed, as it's turned to be a different code
path.

Exit earlier in mysql_alter_table, if global temporary table is opened
in this connection, or in the other connection. Add timeout argument to
simple_rename_or_index_change, which can be 0 to conform Oracle behavior.
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-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-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-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-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.
Nikita Malyavin
MDEV-37798 Incomplete savepoint support with global temporary tables

Add empty savepoint support callbacks to global_temporary_tp
Nikita Malyavin
MDEV-37382 crash on CREATE OR REPLACE GTT under LOCK TABLES

The rules of opening become uneasy in CREATE TABLE for global
temporary tables:
* CREATE OR REPLACE t means that global handle of t should be opened
for the first time;
* CREATE ... SELECT t means that local handle of t should be opened;
* LOCK TABLES adds an extra complexity layer:
  1. It re-opens the tables a
  few times, not in a single operation (so we couldn't rely on the
  order of table_list),
  2. MDL on the SELECT tables is not necessarily MDL_READ, and so
  table lock is.
  3. CREATE OR REPLACE needs to open a global handle to substitute old
  table in locked_tables_list
  4. CREATE...SELECT additionally needs to open a local handle to
  insert into a correct sink.

This patch presents the following solution:
* Provide a way to distinguish tables to be opened: extend
TABLE_LIST::enum_open_strategy with a new item,
OPEN_FOR_LOCKED_TABLES_LIST.
* Every locked_table_list item, i.e. TABLE_LIST, will have
open_strategy=OPEN_FOR_LOCKED_TABLES_LIST.
* GTT tables with OPEN_FOR_LOCKED_TABLES_LIST are always opened as
global handles. The same applies to OPEN_STUB -- it represents the old
table in OR REPLACE case, opened for the first time (comes from
parser). Importantly, OPEN_STUB tables don't reach open_table(), nor
open_global_temporary_table, unless it's in locked tables mode.

* In CREATE...SELECT, open both global and local handles:
the former is for replacing the old table in locked_tables_list and
the latter is for inserting the data.

* Add check_global_temporary_tables_for_create to report if a table to
replace is GTT and has open handles. Since there are three different
implementations for CREATE, it has to be called from different places.

Also fixes MDEV-37395
Nikita Malyavin
MDEV-37929 Assertion !thd->rgi_slave' failed on REPAIR TABLE on replica

1. REPAIR TABLES is logged even if open_table is failed. In this case,
we cannot determine whether it was opened for a global temporary table,
so we cannot make sure it is not replicated.

2. Also REPAIR/ANALYZE/CHECK can include more that one table, and has no
ability co control statement logging per-table, so anyway relying on
that it's not logged is incorrect.

Hence, enable writing to binlog for these three statements. Keep replica
to be able to handle these commands.
As such, force REPAIR/ANALYZE/CHECK to open a parent handle of global
temporary table.

Extract sql_command_flags flag CF_USE_PARENT_GTT_SHARE for global
temporary tables, as a critical mass of statements has been reached.

Also fixes:
MDEV-37929 Assertion !thd->rgi_slave' failed on REPAIR TABLE on replica
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-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-38266 Infinite loop after LOCK+REPAIR

Case:
1. Two tables are locked, one of them is GTT
2. Invoke REPAIR on the last table in the list (not GTT)
3. SELECT from gtt

How the bug works:
1. REPAIR sets tdc->flushed=true
2. LOCK TABLE will prevent eviction
3. In SELECT, open_table will go by locked_tables_mode path
4. GTT is found, goto get_new_table (bug!).
5. This is true: thd->open_tables && thd->open_tables->s->tdc->flushed
6. ot_ctx->request_backoff_action
7. open_table retry (infinite).

Fix:
Straighten the flow.
We shouldn't check thd->open_tables->s->tdc->flushed in LTM, but
actually we should do none under get_new_table label right until
open_global_temporary_table.

get_new_table would access tdc and search for TABLE_SHARE, but actually
we already have it. We also shouldn't configure it from scratch - it's
already done. Overall, we can jump directly to opening GTT, with setting
a few variables.

Because TABLE_SHARE will not be opened through tdc (where acquire would
happen), we shouldn't release it in open_global_temporary_table under
locked_tables_mode+MYSQL_OPEN_GET_NEW_TABLE.
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-37693 use-after-free in mysql_ha_flush after 2nd HANDLER OPEN execution

An error arises due to early deny after open_table in mysq_admin_table,
taken place in-between two handler opens, preceeding by SELECT in an
open transaction.

Analysis:
The crash happens when another mysql_ha_flush call (for example, in the
beginning of SELECT) writes table->mdl_ticket, which wasn't cleaned up
after release.
The ticket release happens normally, at mysql_ha_close_table call. This
could be another HANDLER CLOSE call, but it happens implicitly by LOAD
INDEX.
There are certain circumstances, under which table->mdl_ticket is
accessed by the handler:
  if (table_list->mdl_request.ticket &&
      thd->mdl_context.has_lock(mdl_savepoint, table_list->mdl_request.ticket))
in mysql_ha_open,
meaning that the lock should have had existed in the transaction during
open.
This condition is true for the first HANDLER OPEN, because of
preceeding SELECT * FROM t, which is supposed to hold a lock during the
whole transaction.
However, killed LOAD INDEX releases that lock, resulting in skipping a
write into table_list->table->mdl_ticket durind a second HANDLER OPEN.

This doesn't happen for local temporary tables, because they don't hold
table_list->mdl_request.ticket.
This doesn't happen for normal tables, because table->mdl_ticket is
cleaned up during close_thread_table.

Solution:
Clean up table->mdl_ticket on mysql_ha_close_table, as that is the only
case when it's supposed to be set.
Nikita Malyavin
MDEV-37817 DROP TABLE GTT doesn't succeed for ON COMMIT DELETE ROWS

Drop child GTTs on pre-statement impllicit commit stage.

We can't do that inside trans_commit_implicit, because some implicit
commits are fake and part of a bigger logic, where we'd want to preserve
open GTTs.

We can't call mark_tmp_tables_as_free_for_reuse either, since there
could be tables just opened for this transaction, so only drop
exactly what's needed, assuming that tables were marked for reuse in
prev statement, but not dropped yet. One place where mark for reuse is
still required is after closing HANDLER tables.
Kristian Nielsen
Binlog-in-engine: Update docs with upgrading info

Signed-off-by: Kristian Nielsen <[email protected]>
Nikita Malyavin
MDEV-37956 use-after-free in mysql_ha_close_table on DROP DATABASE

Drop global temporary tables after dropping handlers.
Nikita Malyavin
MDEV-37934 Assertion `thd->transaction->stmt.is_empty()...' in GRANT

...on GTT failed

Open a parent handle for GTT on GRANT.
ON COMMIT PRESERVE ROWS does not register handlerton, so it will work
fine.
Nikita Malyavin
MDEV-37718 Assertion '!thd->rgi_slave' failed on GTT DML

Assertion '!thd->rgi_slave' failed in open_global_temporary_table on
CREATE/ANALYZE GTT, also a SIGSEGV in the release build.

This is a result of a fact that some operations led to opening a child
table on slave. The bug can be split in two parts:

1. SELECT part of CREATE...SELECT is replicated. It was binlogged,
despite table_creation_was_logged=0 explicitly set. To avoid, fall to
the row logging path of create_select, i.e. log SHOW CREATE output, but
don't actually log rows.
The relevant changes are in sql_insert.cc

2. Admin commands like ANALYZE TABLE still create a child table on open,
but are binlogged. Binlogging them would be otherwise harmless, but
better to avoid it, until the commands are fully supported and make
sense.
For now, avoid binlogging them with lex->no_write_to_binlog=false.
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-37872 SIGSEGV on some GTT operations under pseudo_thread_id changed

Deny pseudo_thread_id changing when there are some GTTs are open.
pseudo_thread_id is only used for replication testing. Since GTT child
tables are never opened on replicas, it's fine to do so -- there is no
case to test.
Nikita Malyavin
MDEV-38125 Assertion !thd->rgi_slave failed on INSERT under LOCK TABLES

Locking a global temporary table causes a crash on slave,
even if the table wasn't used in the statement, but just locked.

The crash, and an inappropriate open of global temporary table happens
because its table mapping was replicated. Rows_log_event opens all the
tables that were aggregated by Table_map_log_event.

THD::binlog_write_table_maps aggressively logs all the tables that
were write-locked, even if they will never be used.

Solution: We should never log table maps for global temporary tables
Nikita Malyavin
MDEV-37668 SIGSEGV on DROP TABLE GTT under LOCK TABLES and
different server_id

Fixed per MDEV-37673.

This commit only includes test.
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-37850 Wrong error on DROP TABLE GTT after DROP DATABASE

Turns out that temporary tables are not dropped as part of DROP
DATABASE.

This patch implements dropping child global temporary tables for the
currently dropping database.

That is, if the child table was opened in this connection, it will be
dropped together with the parent table.

If another connection attempts to drop the database, it will wait while
the table is in use.
Andrei Elkin
MDEV-38212 MDEV-37686 Breaks Parallel Replication

Re-fixing MDEV-37686.

NULLifying `THD::rgi_slave` pointer in `start_new_trans` ctor harmed
the parallel slave conflict detection.
Now instead of `NULL`ifying of this member a finer approach is taken to
optionally screen `THD::rgi_slave` when it is attempted to be accessed
within `start_new_trans` context, that is when such out-of-band
transaction is run by a slave thread.

The start_new_trans is allowed of course to access server local
non-replicated temporary tables, should it ever need that.

The original MDEV-37686 aspect is tested with 12.3 branch's
rpl.create_or_replace_mix2.
Any possible side effects to temporary table replication is controlled
by existing rpl suite tests.
There is no need for a specific mtr test to prove the parallel slave
side is back to normal, as `THD::rgi_slave` is again available to concurrent
transactions.
Rucha Deodhar
MDEV-33640: Server crashes at my_hash_free

Analysis:
While parsing the json schema, we dont initialize the hash that stores
properties, but we try to free hash while cleanup. This happend because
the variable that checks whether hash is initialized has garbage value.
So the check becomes true and we end up deleting the uninitialized hash.

Fix:
Initialize the is_hash_inited to false.
Nikita Malyavin
MDEV-37720 use-after-free on CREATE OR REPLACE GTT under pseudo_slave_mode

... and LOCK TABLES.

Global temporary tables data is not replicated, and pseudo_slave_mode is
used internally for partial replication testing.

Hence forbid opening GTT (i.e. create child GTT handles) under
pseudo_slave_mode, and forbid setting pseudo_slave_mode=1 whenever child
GTT handles are open.
Nikita Malyavin
MDEV-37941 Assertion !thd->rgi_slave failed on INSERT w/ parallel slave

Replicas can't crash on the incorrect/unexpected data. It should react
with an error.

Change the assertion to if and return error if the relay log contains
query with GTT access.
Nikita Malyavin
MDEV-37957 Assertion lock_type >= TL_READ_SKIP_LOCKED failed on HANDLER

...READ

Don't set lock_type to TL_IGNORE: open_temporary_table intentionally
sets it to TL_WRITE to "simulate locking".
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-37667 SIGSEGV on ALTER on locked GTT in low memory env

Alter table, as one of its stages, creates a temporary table from a
given table. If something goes wrong, this table will be freed.

We never distinguished a child table of global temporary table and a
temporary table created from parent for internal purposes, as this one:
They are even added to the temporary_tables list as a normal tmp table.

This commit denotes a difference for global temporary tables as with
share->mdl_request.ticket set to NULL.

Fix:
If it's a temporary table created from global temporary table for
internal purposes,
1. do not free mdl_ticket
2. do not alter global_temporary_tables_count
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.