1
0
mirror of https://github.com/MariaDB/server.git synced 2026-01-13 18:02:43 +03:00
Commit Graph

4336 Commits

Author SHA1 Message Date
Sergei Golubchik
956920816e MDEV-37710 ASAN errors in find_type2 upon executing a procedure from sys schema
don't reload stored routines in the middle of the execution
of a routine. we don't want different iterations of a loop
to see diffefent definitions

For this: remember Cversion in THD on the first sp cache lookup,
after that only compare versions with this value not with Cversion.
2025-10-28 17:49:51 +01:00
Monty
72341bc255 Simplify NEXTVAL(sequence) when used with DEFAULT
Instead of adding another TABLE_LIST to
Item_func_nextval->table_list->next_local, update instead
Item_func_nextval->table_list->table with the correct table.

This removes all checking of table_list->table and table_list->next_local
when using sequences.
2025-10-28 17:49:51 +01:00
Sergei Golubchik
516f68af9e MDEV-37345 sequences and prelocking
if a bunch of tables are prelocked, when a table is actually
needed in the routine, open_tables picks one table out of the
prelocked list with a smallest "distance". Distance is simply
a difference between the actual table lock and the requested
table lock. Say, if the prelocked set contains both t1 write-locked
and t1 read-locked, than an UPDATE will prefer write-locked t1
and SELECT will prefer read-locked. if there's only write-locked
table in the set, both UPDATE and SELECT will use it.

this doesn't distingush between UPDATE and INSERT, but INSERT
marks tables with tables->for_insert_data=1, which causes
prelocking to invoke add_internal_tables() and prepare sequences
for execution.

in this bug there were two prelocked t1's, one for INSERT (with
for_insert_data=1) and one for UPDATE.
INSERT picks the second (they both are write-locked, so the distance is
the same), its sequence is not prepared and crashes.

Let's add for_insert_data as the lowest bit into the distance.
2025-10-28 17:49:51 +01:00
Marko Mäkelä
d0afe4b985 Merge 10.6 into 10.11 2025-10-09 13:29:46 +03:00
Hemant Dangi
1dd4889d95 MDEV-25039: MDL BF-BF conflict because of foreign key
Issue:
The Commit: 0584846 'Add TL_FIRST_WRITE in SQL layer for determining R/W'
limits INSERT statements on write nodes to acquire MDL locks on it's all child
tables and thereby wsrep certification keys added, but on applier nodes it does
acquire MDL locks for all child tables. This can result into MDL BF-BF conflict
on applier node when transactions referring to parent and child tables are
executed concurrently. For example:

Tables with foreign keys: t1<-t2<-t3<-t4
Conflicting transactions: INSERT t1 and DROP TABLE t4

Wsrep certification keys taken on write node:
- for INSERT t1: t1 and t2
- for DROP TABLE t4: t4

On applier node MDL BF-BF conflict happened between two transaction because
MDL locks on t1, t2, t3 and t4 were taken for INSERT t1, which conflicted
with MDL lock on t4 taken by DROP TABLE t4.
The Wsrep certification keys helps in resolving this MDL BF-BF conflict by
prioritizing and scheduling concurrent transactions. But to generate Wsrep
certification keys it needs to open and take MDL locks on all the child tables.

The Commit: 0584846 change limits MDL lock to be taken on all child nodes for
read-only FK checks (INSERT t1). But this doesn't works on applier nodes
because Write_rows_log_event event logged for INSERT is also used to record
update (check Write_rows_log_event::get_trg_event_map()), and
therefore MDL locks is taken for all the child tables on applier node
for update and insert event.

Solution:
Additional keys for the referenced/foreign table needs to be added
to avoid potential MDL conflicts with concurrent update and DDLs.
2025-10-07 14:08:35 +05:30
Kristian Nielsen
db20a99587 MDEV-22915: Assertion 'binlog_table_maps == 0 || locked_tables_mode == LTM_LOCK_TABLES' failed in THD::reset_for_next_command
close_thread_tables() would not flush pending row events to the binlog cache
in certain conditions if LOCK TABLES was active. This could result in the
row events being binlogged without STMT_END_F flag, and eventually leave the
THD in an invalid state that triggered assertions later.

Reviewed-by: Monty <monty@mariadb.org>
Signed-off-by: Kristian Nielsen <knielsen@knielsen-hq.org>
2025-10-07 09:40:36 +02:00
Marko Mäkelä
990b44495c Merge 10.6 into 10.11 2025-09-24 12:48:56 +03:00
Monty
6058e02732 MDEV-37172 Server crashes in Item_func_nextval::update_table after INSERT to the table, that uses expression with nextval() as default
The issue was that unpack_vcol_info_from_frm() wrongly linked the used
sequence tables into tables->internal_tables when more than one sequence
table was used.

Other things:
- Fixed internal_table_exists() to take db into account.
  (This is making the code easier to read. As we where comparing
   pointers the old code also worked).
2025-09-14 19:24:07 +03:00
Aleksey Midenkov
a1da6555fb MDEV-16686 DDL in procedure propagates no locking to tables locked by DML
TABLE_LIST parsed from procedure code is transferred into tables to
lock for INSERT. The procedure code is CREATE VIEW so its TABLE_LIST
is parsed as TL_IGNORE, but same view exists and when existing view is
opened mysql_make_view() uses same TABLE_LIST that was initialized
from CREATE VIEW and then added as part of prelocking context. So
existing view is opened and its table is assigned TL_IGNORE from
prelocking context. Finally, INSERT has TABLE_LIST duplication: the
one that was parsed from INSERT; the another one came from procedure
prelocking, its lock_type came from the procedure code and the real
table was found via existing view.

The sequence of execution:

1. Procedure p is compiled as part of open_and_process_routine(), its
   code is parsed and create_or_alter_view_finalize() initializes v
   TABLE_LIST as TL_IGNORE;
2. Procedure p prelocking adds v to prelocking_ctx with TL_IGNORE;
3. DML prelocking adds v from prelocking_ctx;
4. View is opened, mysql_make_view() assigns t lock_type from v;
5. open_and_lock_tables() attempts to lock t with TL_IGNORE.

The fix skips TL_IGNORE at 2. when table list parsed by procedure is
added for prelocking:

        if (my_hash_insert(&m_sptabs, (uchar *)tab))
          return FALSE;

m_sptabs designation was defined as strictly for prelocking:

  /**
    Multi-set representing optimized list of tables to be locked by this
    routine. Does not include tables which are used by invoked routines.

    @note
    For prelocking-free SPs this multiset is constructed too.
    We do so because the same instance of sp_head may be called both
    in prelocked mode and in non-prelocked mode.
  */
  HASH m_sptabs;

The fix was proposed by Sergei Golubchik <serg@mariadb.org>.
2025-09-01 22:18:35 +03:00
Sergei Golubchik
053f9bcb5b Merge branch '10.6' into 10.11 2025-07-28 18:06:31 +02:00
Sergei Golubchik
18f85c8c68 MDEV-37302 Assertion failure in Table_triggers_list::add_tables_and_routines_for_triggers upon attempt to insert DEFAULT into non-insertable view
Only do trigger prelocking for tables that are doing to be
modified (with a write lock). A table can cause prelocking
if its DEFAULT value is used (because DEFAULT can be NEXTVAL),
even if the table itself is only used for reads. Don't process
triggers for such a table
2025-07-24 00:11:48 +02:00
Sergei Golubchik
288db5fa5f MDEV-24981 LOAD INDEX may cause rollback of prepared XA transaction
XAER_RMFAIL means the admin statement was not allowed, it's not a
per-table message, so must fail the whole statement. And must
not rollback, obviously, it's not allowed after prepare.

Also, remove duplicate XAER_RMFAIL in open_tables(),
check_has_uncommitted_xa() already issues it.
2025-07-22 20:58:07 +02:00
Marko Mäkelä
3da36fa130 Merge 10.6 into 10.11 2025-05-26 08:10:47 +03:00
Marko Mäkelä
1c7209e828 Merge 10.6 into 10.11 2025-05-21 07:36:35 +03:00
Hemant Dangi
d38558f99b MDEV-36117: MDL BF-BF conflict on ALTER and UPDATE with multi-level foreign key parents
Issue:
Mariadb acquires additional MDL locks on UPDATE/INSERT/DELETE statements
on table with foreign keys. For example, table t1 references t2, an
UPDATE to t1 will MDL lock t2 in addition to t1.
A replica may deliver an ALTER t1 and UPDATE t2 concurrently for
applying. Then the UPDATE may acquire MDL lock for t1, followed by a
conflict when the ALTER attempts to MDL lock on t1. Causing a BF-BF
conflict.

Solution:
Additional keys for the referenced/foreign table needs to be added
to avoid potential MDL conflicts with concurrent update and DDLs.

Signed-off-by: Julius Goryavsky <julius.goryavsky@mariadb.com>
2025-05-20 20:59:10 +02:00
Sergey Vojtovich
55ddfe1c95 MDEV-36684 - main.mdl_sync fails under valgrind (test for Bug#42643)
Valgrind is single threaded and only changes threads as part of
system calls or waits.

Some busy loops were identified and fixed where the server assumes
that some other thread will change the state, which will not happen
with valgrind.

Based on patch by Monty. Original patch introduced VALGRIND_YIELD,
which emits pthread_yield() only in valgrind builds. However it was
agreed that it is a good idea to emit yield() unconditionally, such
that other affected schedulers (like SCHED_FIFO) benefit from this
change. Also avoid pthread_yield() in favour of standard
std::this_thread::yield().
2025-04-29 15:05:20 +04:00
Sergei Petrunia
cafd22db79 Code cleanup in mark_common_columns(): nj_col_2 is non-NULL here
Done after fix for MDEV-36592
2025-04-28 15:58:16 +03:00
Oleksandr Byelkin
4d41ec081e Merge branch '10.6' into 10.11 2025-04-26 10:47:03 +02:00
Oleksandr Byelkin
19644f6821 Merge branch '10.5' into 10.6 2025-04-26 10:41:52 +02:00
Oleksandr Byelkin
4fc9dc84b0 MDEV-32086 (part 2) Server crash when inserting from derived table containing insert target table
Get rid of need of matherialization for usual INSERT (cache results in
Item_cache* if needed)

- subqueries in VALUE do not see new records in the table we are
  inserting to
- subqueries in RETIRNING prohibited to use the table we are inserting to
2025-04-25 15:10:36 +02:00
Oleksandr Byelkin
9b313d2de1 MDEV-32086 Server crash when inserting from derived table containing insert target table
Use original solution for INSERT ... SELECT - select result buferisation.

Also fix MDEV-36447 and MDEV-33139
2025-04-25 12:58:24 +02:00
Sergei Petrunia
8c7c144f19 MDEV-36592: In JOIN ... USING(columns), query plan depends on join order
"t1 JOIN t2 USING(col1,...)" calls mark_common_columns() to mark the
listed columns as used in both used tables, t1 and t2.

Due to a typo bug, it would mark the wrong column in the second table
(t2): instead of t2.col1 it would mark the last column in t2.

The harmful effects included JOIN_TAB(t2)->covering_keys not being
set correctly. This changed the cost to access the table and then
caused different query plans depending on which table was the second
in the JOIN ... USING syntax.
2025-04-22 14:57:57 +03:00
Oleksandr Byelkin
20b818f45e Merge branch '10.6' into 10.11 2025-04-21 11:23:11 +02:00
Oleksandr Byelkin
a135551569 Merge branch '10.5' into 10.6 2025-04-21 10:43:17 +02:00
Sergei Golubchik
7f1492d0bc cleanup: rename hide_view_error->replace_view_error_with_generic
as requested by Monty
2025-04-17 17:22:56 +02:00
Julius Goryavsky
1a013cea95 Merge branch '10.6' into '10.11' 2025-04-16 03:34:40 +02:00
Julius Goryavsky
88dfa6bcee Merge branch '10.5' into '10.6' 2025-04-15 01:49:48 +02:00
Nikita Malyavin
cb7e39b75b MDEV-36181 Field pointer may be uninitialized in fill_record
Newer gcc reports:
error: 'rfield' may be used uninitialized [-Werror=maybe-uninitialized]
 9041 |     unwind_stored_field_offsets(fields, rfield);

 After investigation, it turned to be an impossible case:

 1. The only way it could be broken is if
 if (!(field= fld->field_for_view_update()))
 line case would succeed from the first time.
 2. Consequent checks initialize rfield.
 fld may return NULL in field_for_view_update() only for views.
 3. Before fill_record, UPDATE first calls check_fields, where
 field_for_view_update() result is already checked. INSERT calls
 check_view_insertability that checks that all view fields are
 updateable.

It all means that field_for_view_update() cannot be NULL in fill_record,
so the if can be converted to DBUG_ASSERT.

This essentially shifts the responsibility on preliminary
field_for_view_update() check to the caller.

In this patch:
1. convert field_for_view_update() check to DBUG_ASSERT
2. harden unwind_stored_field_offsets function so that it can be used
even if field_for_view_update() is NULL
3. As a consequence, `field` is passed instead of `rfield` as a
terminator.
4. Initialize `field` to NULL to bypass a false-positive warning!
2025-04-14 12:15:07 +02:00
Marko Mäkelä
ab0f2a00b6 Merge 10.6 into 10.11 2025-03-27 08:01:47 +02:00
Aleksey Midenkov
4c695c85bd MDEV-34775 Wrong reopen of already open routine due to auto-create in SP
MDEV-34171 denied removing indirect routines/tables after
recover_from_failed_open() for auto-create partition case. Now we are
going further and keep them for any failed table reopen.

MDEV-34171 did not handle correctly open_and_process_routine() after
that skip of sp_remove_not_own_routines(). Now it is fixed by
sroutine_to_open correct usage.
2025-03-24 09:01:07 +03:00
Julius Goryavsky
e3d7d5ca26 Merge branch '10.5' into '10.6' 2025-02-27 04:02:33 +01:00
Yuchen Pei
0fa141ebb4 MDEV-36138 Server null-pointer crash at startup when tmptables left in --tmpdir
Fix a regression introduced in MDEV-35840 78157c4765

Also tested compiling with -O3 that the -Warray-bounds fixed in
MDEV-35840 does not resurface
2025-02-24 12:10:32 +11:00
Marko Mäkelä
feadfd9d9c MDEV-27769 fixup: conditionally define a function 2025-02-11 14:06:15 +02:00
Sergei Golubchik
e69f8cae1a Merge branch '10.6' into 10.11 2025-01-30 11:55:13 +01:00
Sergei Golubchik
066e8d6aea Merge branch '10.5' into 10.6 2025-01-29 11:17:38 +01:00
Nikita Malyavin
e33064e0fc MDEV-27769 Assertion failed in Field::ptr_in_record upon UPDATE in ORACLE mode
table->move_fields has some limitations:
1. It cannot be used in cascade
2. It should always have a restoring pair

In this case, an error has occurred before the field ptr was restored, returning
from the function in that state. Even in case of an error, the table can be
reused afterwards and table->field[i]->ptr is not reset in between.

The solution is to restore the field pointers immanently whenever they've been
deviated.

Also add an assertion that ensures that table fields are restored after the use
in close_thread_tables.
2025-01-26 16:15:46 +01:00
Marko Mäkelä
98dbe3bfaf Merge 10.5 into 10.6 2025-01-20 09:57:37 +02:00
Sergei Golubchik
a69da0c31e MDEV-19761 Before Trigger not processed for Not Null Columns if no explicit value and no DEFAULT
it's incorrect to zero out table->triggers->extra_null_bitmap
before a statement, because if insert uses an explicit field list
and omits a field that has no default value, the field should
get NULL implicitly. So extra_null_bitmap should have 1s for all
fields that have no defaults

* create extra_null_bitmap_init and initialize it as above
* copy extra_null_bitmap_init to extra_null_bitmap for inserts
* still zero out extra_null_bitmap for updates/deletes where
  all fields definitely have a value
* make not_null_fields_have_null_values() to send
  ER_NO_DEFAULT_FOR_FIELD for fields with no default and no value,
  otherwise creation of a trigger with an empty body would change the
  error message
2025-01-17 23:42:56 +01:00
Yuchen Pei
78157c4765 MDEV-35840 Eliminate -warray-bounds triggered by TABLE_SHARE::db_type()
The warnings are triggered with -O3
2025-01-16 10:48:11 +11:00
Marko Mäkelä
420d9eb27f Merge 10.6 into 10.11 2025-01-08 12:51:26 +02:00
Marko Mäkelä
f20ee931d8 Merge 10.5 into 10.6
Note: Changes to the test innodb.stats_persistent
in commit e5c4c0842d (MDEV-35443)
are not merged, because the test scenario is impossible
due to commit e66928ab28 (MDEV-33462).
2025-01-03 09:10:25 +02:00
Marko Mäkelä
3f914afd3a Merge 10.6 into 10.11 2025-01-02 12:39:56 +02:00
Oleg Smirnov
24e5d56400 MDEV-35680 Table number > MAX_TABLES causes overflow of table_map at main.join test
Fix a regression introduced by commit d98ac851 (MDEV-29935, MDEV-26247) causing
MAX_TABLES overflow in `setup_table_map()`. The check for MAX_TABLES was moved
outside of the loop that increments table numbers, allowing overflows during
loop iterations. Since setup_table_map() operates on a 64-bit bitmap, table
numbers exceeding 64 triggered the UBSAN check.
This commit returns the overflow check within the loop and adds a debug
assertion to `setup_table_map()` to ensure no bitmap overrun occurs.
2024-12-24 15:54:56 +07:00
Yuchen Pei
671f80c738 Merge branch '10.5' into 10.6 2024-12-17 11:06:09 +11:00
Oleg Smirnov
d98ac8511e MDEV-26247 MariaDB Server SEGV on INSERT .. SELECT
This problem occured for statements like `INSERT INTO t1 SELECT 1`,
which do not have tables in the SELECT part. In such scenarios
SELECT_LEX::insert_tables was not properly set at `setup_tables()`,
and this led to either incorrect execution or a crash

Reviewer: Oleksandr Byelkin <sanja@mariadb.com>
2024-12-14 14:04:21 +07:00
Oleg Smirnov
e640373389 Revert "MDEV-26427 MariaDB Server SEGV on INSERT .. SELECT"
This reverts commit 49e14000ee
as it introduces regression MDEV-29935 and has to be reconsidered
in general
2024-12-14 13:08:17 +07:00
Dmitry Shulga
54c1031b74 MDEV-34958: after Trigger doesn't work correctly with bulk insert
This bug has the same nature as the issues
  MDEV-34718: Trigger doesn't work correctly with bulk update
  MDEV-24411: Trigger doesn't work correctly with bulk insert

To fix the issue covering all use cases, resetting the thd->bulk_param
temporary to the value nullptr before invoking triggers and restoring
its original value on finishing execution of a trigger is moved to the method
  Table_triggers_list::process_triggers
that be invoked ultimately for any kind of triggers.
2024-12-13 16:19:39 +07:00
Oleksandr Byelkin
3d0fb15028 Merge branch '10.6' into 10.11 2024-10-29 15:24:38 +01:00
Oleksandr Byelkin
f00711bba2 Merge branch '10.5' into 10.6 2024-10-29 14:20:03 +01:00
Sergei Golubchik
3a1cf2c85b MDEV-34679 ER_BAD_FIELD uses non-localizable substrings 2024-10-17 21:37:37 +02:00