1
0
mirror of https://github.com/MariaDB/server.git synced 2026-10-23 18:49:29 +03:00

3150 Commits

Author SHA1 Message Date
Kristian Nielsen
46561d92f1 Merge branch 'knielsen_log_event_read_validation_base_12.3' into 13.1
This merges the	patch series that fixes	a lot of missing validation
checks for read_log_event(). The merge includes a few added fixes that
are needed in new code introduced in 13.1.

Signed-off-by: Kristian Nielsen <knielsen@knielsen-hq.org>
2026-10-22 16:01:38 +02:00
Kristian Nielsen
ffaba7b55c Merge branch 'knielsen_log_event_read_validation_base_11.8' into 12.3
This merges the	patch series that fixes	a lot of missing validation
checks for read_log_event(). The merge includes a few added fixes that
are needed in new code introduced in 12.3.

Signed-off-by: Kristian Nielsen <knielsen@knielsen-hq.org>
2026-10-22 12:23:06 +02:00
Marko Mäkelä
8136047738 Merge 11.4 into 11.8 2026-10-15 07:47:24 +03:00
Marko Mäkelä
7ee06258b5 Merge 10.11 into 11.4 2026-10-13 07:04:14 +03:00
Kristian Nielsen
5dd6b9252b MDEV-35691: Invalid access, use-after-free, on rli->description_event_for_exec
This commit rewrites the rpl_master_has_bug() mechanism to solve a problem
with invalid memory access. The rpl_master_has_bug() mechanism detects
certain bugs depending on the master version, and uses that to enable
specific work-arounds on the slave. The problem was that
rpl_master_has_bug() accessed Relay_log_info::description_event_for_exec
that is not valid to access from concurrent parallel replication worker
threads, only from the SQL driver thread. Thus it could use the wrong event
or access invalid/freed memory.

This patch instead computes a bitmask of detected bugs when the SQL driver
thread processes the format description event, and reads that bitmask with
an atomic load from the worker threads. The bitmask of bugs can only change
when the master restarts with a new version, and we do not replicate events
concurrently across a format description event from a master restart. Thus,
the bitmask is safe to read concurrently from the Relay_log_info object
without locking.

This also avoids an expensive match of each entry in the bug list against
the master server version done for every single call to
rpl_master_has_bug(), which could be quite expensive when done eg. per field
in row events as in Field_string::compatible_field_size().

Also remove redundant conditional in table_def::compatible_with().

Thanks to Andrei Elkin for the idea to safely read the bitmask
concurrently from the Relay_log_info.

Reviewed-by: Andrei Elkin <andrei.elkin@pp.inet.fi>
Signed-off-by: Kristian Nielsen <knielsen@knielsen-hq.org>
2026-09-03 08:16:29 +02:00
Jan Lindström
1bc9eca856 MDEV-40929 : CREATE TABLE ... AS SELECT is not replicated in Galera when the table is partitioned
Problem was that check for partitioned tables was missing
because then partition implementing handlerton should be used in
condition instead.

Thanks to Roel Van de Paar <roel.vandepaar@mariadb.com> for
providing test case and fix candidate.
2026-09-02 07:47:30 +03:00
forkfun
b8dbc264f0 Merge branch '13.0' into 'main' 2026-08-03 13:42:39 +02:00
forkfun
1a4bb1bbfd Merge branch '12.3' into '13.0' 2026-07-30 16:15:40 +02:00
forkfun
33240f3c96 Merge branch '11.8' into '12.3' 2026-07-30 11:41:55 +02:00
forkfun
eaca80bf32 Merge branch '11.4' into '11.8' 2026-07-29 12:27:46 +02:00
forkfun
08eeb6a417 Merge branch '10.11' into '11.4' 2026-07-28 13:14:38 +02:00
Aleksey Midenkov
4c7b53f997 MDEV-38854 Assertion table->vers_write fails upon ODKU into table with versioned column
In MDEV-25644 vers_check_update() sets vers_write to false in case it
returns false. It is ok for UPDATE but is not correct for ODKU is bulk
insert requires vers_write on next tuple.

The fix return vers_write value back when vers_check_update() and
related vers_insert_history_row() are done in ODKU.
2026-07-27 21:39:41 +03:00
Raghunandan Bhat
113630fdfa MDEV-40099: MSAN: use-of-uninitialized-value in TABLE::delete_row<true>(bool)
Problem:
  REPLACE DELAYED into a system-versioned table read an uninitialized
  lex->vers_conditions.delete_history in TABLE::delete_row().

  Delayed_insert has its own THD, and hence its own LEX, of which the
  constructor copies only a few fields from the parser LEX.
  vers_conditions was not copied, so it stayed uninitialized. It is read
  when a REPLACE resolves a duplicate on a versioned table.

Fix:
  Copy vers_conditions from the parser LEX in the Delayed_insert
  constructor.
2026-07-17 18:51:52 +05:30
Oleksandr Byelkin
d195db57ff Merge branch '13.0' 2026-05-27 12:49:36 +02:00
Oleksandr Byelkin
9f98f82b14 Merge branch '11.8' into 12.3 2026-05-26 21:15:58 +02:00
Bill Jin
5a9af15a2c MDEV-39548 Cleanup MDL_request boilerplate with ACQUIRE_LOCK macro
Add new acquire_lock() overloads on MDL_context that combine MDL_request
initialization and lock acquisition into a single call, returning
MDL_ticket* directly. Convert applicable call sites across the codebase
to use the new ACQUIRE_LOCK macro.

All new code of the whole pull request, including one or several files
that are either new files or modified ones, are contributed under the
BSD-new license. I am contributing on behalf of my employer Amazon Web
Services, Inc.
2026-05-26 20:00:43 +04:00
Oleksandr Byelkin
f572addcc1 Merge branch '12.3' into 13.0 2026-05-22 09:52:05 +02:00
Oleksandr Byelkin
3f388a1cce Merge branch '11.8' into 12.3 2026-05-22 09:27:18 +02:00
Oleksandr Byelkin
9cb70f0220 Merge branch '11.4' into 11.8 2026-05-08 08:11:03 +02:00
Oleksandr Byelkin
7598e4e95d Merge branch '10.11' into 11.4 2026-05-08 08:00:01 +02:00
Marko Mäkelä
e13d89949c Merge 12.3 into main 2026-05-05 13:14:42 +03:00
Rucha Deodhar
6a7a44aba0 MDEV-5092: Implement UPDATE with result set (UPDATE ... RETURNING)
The patch introduces the OLD_VALUE() expression to reference the value
of a column before it was updated. The parser is extended to support
RETURNING and OLD_VALUE(), and RETURNING expressions are stored in a
separate returning_list in SELECT_LEX with independent wildcard tracking.
RETURNING is rejected for multi-table UPDATE.

During setup of RETURNING fields, THD::is_setting_returning is used
when resolving fields, particularly for updates through views.
When resolving view fields, Item_direct_view_ref may point to the
view's item_list, losing the information about whether the value
should be old or new. The original item in returning_list still
contains the correct is_old_value_reference flag, which is copied
back to the resolved item.

OLD_VALUE() is implemented by extending Item_field with a new
Item_old_field class. Item_field::set_field() initializes
Field::ptr_old to the corresponding location in record[1],
which stores the old row during UPDATE execution.

When sending result rows, Item_old_field::send() temporarily switches
the field pointer from record[0] (current row) to ptr_old so
OLD_VALUE() returns the value before the update.

The UPDATE execution path is modified to send a result set when
RETURNING is present instead of an OK packet.
2026-04-30 09:41:26 -04:00
Mikhail Pochatkin
cbcff6324a MDEV-39173 Replace sprintf with snprintf, remove deprecated pragma
Remove the unscoped #pragma GCC diagnostic ignored
"-Wdeprecated-declarations" from include/violite.h and replace all
sprintf/vsprintf calls with snprintf/vsnprintf across the codebase.

Where possible, pass actual buffer sizes as function parameters
instead of using hardcoded constants or recomputing strlen().
Notable API changes:
- get_date(): added to_len parameter for buffer size
- nice_time(), end_timer() in client/mysql.cc: added buff_size
- generate_new_name(): added name_size parameter
- calc_md5(): added buffer_size parameter (fixes off-by-one)
- MD5_HASH_TO_STRING macro: added _size parameter
- Added MYSQL_UDF_MAX_RESULT_LENGTH constant in mysql_com.h

Also fixed a pre-existing bug in sql/rpl_mi.cc where the ellipsis
"..." was written to the wrong buffer (dbuff instead of buff).

Vendored code is excluded: extra/readline, extra/wolfssl,
wsrep-lib, libmariadb, storage/mroonga/vendor, zlib.
2026-04-16 19:00:12 +10:00
Marko Mäkelä
55b3dced05 Merge 11.8 into 12.3 2026-04-02 09:15:17 +03:00
Marko Mäkelä
1a144f713a Merge 11.4 into 11.8 2026-04-01 15:03:59 +03:00
Marko Mäkelä
7c5cac0d51 Merge 10.11 into 11.4 2026-04-01 10:49:05 +03:00
Vladislav Vaintroub
a56158b819 MDEV-33083 AFTER UPDATE trigger sometimes does not fire "ON DUPLICATE KEY UPDATE"
Prior to this change, AFTER UPDATE did not fire, if data was unchanged.

Now this is fixed. Also added a test to verify that trigger behavior for
on-duplicate-update is the same as normal update, in case data does not
change.
2026-03-27 13:09:23 +02:00
Marko Mäkelä
02aedc1065 Merge 11.8 into 12.3 2026-03-24 09:49:17 +02:00
Marko Mäkelä
e6b8cacfb9 Merge 11.4 into 11.8 2026-03-23 11:57:44 +02:00
Marko Mäkelä
a6c9013965 Merge 10.11 into 11.4 2026-03-11 14:18:49 +02:00
Amodh Dhakal
d477356e5b MDEV-38349 Fix assert thd->abort_on_warning == 0 in mysql_insert
When prepare_for_replace() fails, the code returned early via
DBUG_RETURN(1), bypassing the abort label which resets
thd->abort_on_warning to 0. This left the THD in a dirty state,
triggering the dispatch_command assertion at end of command dispatch.

Signed-off-by: Amodh Dhakal <amodhakal@gmail.com>
2026-03-03 11:56:45 +11:00
Thirunarayanan Balathandayuthapani
e5fed9eaf4 MDEV-36436 Assertion "unexpected references" == 0 after ALTER IGNORE TABLE
Problem:
=========
An assertion failure occurs in InnoDB during consecutive
ALTER TABLE operations using the COPY algorithm. The crash
happens during the table rename phase because the
source table (dict_table_t::n_ref_count) is non-zero, despite
the thread holding an exclusive Metadata Lock (MDL).

Reason:
========
When ALTER IGNORE TABLE is executed via the COPY algorithm,
it generates undo logs for every row inserted into the
intermediate table (e.g., #sql-alter-...). The background Purge
Thread, responsible for cleaning up these undo logs, attempts
to take an MDL on the table to prevent the table from
being dropped while in use.

Race condition:
==================
First ALTER: Creates #sql-alter-, copies data, and renames it to t1.

Purge Activation: The Purge thread picks up the undo logs from step 1.
It takes an MDL on the temporary name (#sql-alter-) and increments
the table's n_ref_count.

Identity Shift: InnoDB renames the physical table object to t1, but
the Purge thread still holds a reference to this object.

Second ALTER: Starts a new copy process. When it attempts to rename
the "new" t1 to a backup name, it checks if n_ref_count == 0.
Because the Purge thread is still "pinning" the object to
clean up logs from the first ALTER, the count is > 0,
triggering the assertion failure.

Solution:
========
ALTER IGNORE TABLE needs row-level undo logging to easily
roll back the last inserted row in case of duplicate key errors.
By discarding the last undo log record after inserting each row,
purge will not process any log records generated by
ALTER IGNORE TABLE, preventing unexpected access from the purge
subsystem during subsequent DDL operations.

Make skip_alter_undo (1-bit) to (2-bit enum)
to support different ALTER operation modes:

- NO_UNDO (0): Normal mode with standard undo logging
- SKIP_UNDO (1): ALTER mode that skips undo logging
- IGNORE_UNDO (2): ALTER IGNORE mode that rewrites undo blocks

trx_undo_report_row_operation(): Add ALTER IGNORE undo
rewriting logic. Store old undo record info before writing
new records for IGNORE_UNDO mode. Reset undo top_offset
to maintain only latest insert undo

row_ins_clust_index_entry_low(): Prevent ALTER IGNORE from
using bulk insert optimization. since it requires to write
undo log for each row operation that's incompatible with
existing bulk operation.
2026-02-26 13:18:23 +05:30
Brandon Nesterenko
f5460983d3 MDEV-38726 Assertion `table->default_field != dfield_ptr' failed in bool parse_vcol_defs(THD *, MEM_ROOT *, TABLE *, bool *, vcol_init_mode)
A new assertion added by MDEV-36290 is correct in trying to identify
default_fields that weren't correctly accounted in parse_vcol_defs.
It caught a case for INSERT DELAYED on tables using TIMESTAMP and
DATETIME types with ON UPDATE default values. That is, the insert
delayed logic opens the table in one thread, and then copies the
field info to another table in the user thread. This copy loses most
flag metadata for these fields though. In this case, the flag
ON_UPDATE_NOW_FLAG was dropped, and the parse_col_defs() logic was
unable to properly account for that default field, and the assertion
fired.

This patch fixes this by restoring the ON_UPDATE_NOW_FLAG during the
field copy. Also, a comment is added to Field::make_new_field() to
explain the state of the returned field.

Reviewed-by: Monty <monty@mariadb.com>
Signed-off-by: Brandon Nesterenko <brandon.nesterenko@mariadb.com>
2026-02-09 11:03:26 -07:00
Sergei Golubchik
d653fcb564 Merge branch '11.8' into 12.2 2026-02-03 14:53:15 +01:00
Sergei Golubchik
9bfea48ce1 Merge branch '11.4' into 11.8 2026-01-31 14:08:54 +01:00
Sergei Golubchik
40f7084661 Merge branch '10.11' into 11.4 2026-01-28 21:52:18 +01:00
Sergei Golubchik
b29d3779e4 Merge branch '10.6' into 10.11 2026-01-28 14:22:20 +01:00
Thirunarayanan Balathandayuthapani
5b6ad325d2 MDEV-38667 Assertion in diagnostics area on DDL stats timeout
Reason:
======
 During InnoDB DDL, statistics updation fails due to lock wait
timeout and calls push_warning_printf() to generate warnings
but then returns success, causing the SQL layer
to attempt calling set_ok_status() when the diagnostics area
is already set.

Solution:
=========
By temporarily setting abort_on_warning to false around operations
that prevents warning to error escalation and restore the original
setting after calling HA_EXTRA_END_ALTER_COPY for alter operation.
2026-01-27 13:51:32 +05:30
Sergei Golubchik
387fe5ecc3 MDEV-36787 Error 153: No savepoint with that name upon ROLLBACK TO SAVEPOINT, assertion failure
1. InnoDB should return HA_ERR_ROLLBACK if it aborts a transaction internally
2. the server should recognize it and perform an automatic rollback
2026-01-26 10:01:31 +01:00
Sergei Golubchik
b9ae75d661 MDEV-37998 (Column) CHECK constraints can cause CREATE TABLE (SELECT) queries to fail
don't copy field default values and check constraints in
CREATE ... SELECT.

CREATE ... SELECT means a table is created from a *result set*
not from some other table.

For backward compatibility, though, let's keep copying constant
default values and the "compressed" attribute.
2026-01-14 19:44:30 +01:00
Oleksandr Byelkin
ba00960fda Merge branch 'bb-11.8-release' into bb-12.1-release 2025-11-05 08:58:12 +01:00
Sergei Golubchik
f230c0ff6e Merge branch '10.11' into 11.4 2025-11-04 13:44:16 +01:00
Sergei Golubchik
5ce9a03602 Merge branch '11.4' into 11.8 2025-11-04 12:39:27 +01:00
Sergei Golubchik
1093a2f3b8 Merge branch '10.11' into 11.4 2025-11-03 14:23:51 +01:00
Sergei Golubchik
2bf1d089cf MDEV-37906 Server crash or UBSAN errors in Item_func_nextval::update_table upon INSERT DELAYED
sequences, just as triggers or check constraints, disable DELAYED
2025-10-28 10:49:42 +01:00
Oleksandr Byelkin
c976b527db Merge branch '11.8' into bb-12.1-release 2025-10-08 09:05:38 +02:00
Aleksey Midenkov
ff33f49d9a Merge 11.4 into 11.8 2025-09-29 18:25:09 +03:00
Marko Mäkelä
e8ef8c0055 Merge 10.11 into 11.4 2025-09-24 13:40:09 +03:00
Aleksey Midenkov
1e7d451e99 MDEV-37404 InnoDB: Failing assertion: node->pcur->rel_pos == BTR_PCUR_ON
Caused by optimization done in 2e2b2a0469.

Cannot use lookup_handler in default branch of locate_dup_record() as
InnoDB update depends on positioned record and update is done in table
main handler.

The patch reverts some non-pure changes done by 2e2b2a0469 to
original logic from 72429cad. There was no long_unique_table condition
to init search on table->file, so we get into default branch with long
unique and table->file search uninitialized.

ha_rnd_init_with_error() on demand for HA_DUPLICATE_POS branch was
original logic as well.

More info: 2e2b2a0469 reverts 5e345281e3, but it seems to be OK as
MDEV-3888 test case passes. mysql-5.6.13 has the original code with
HA_WHOLE_KEY as well.
2025-09-19 12:44:08 +03:00
Nikita Malyavin
8001679af6 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.
2025-09-17 18:29:47 +03:00