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
bsrikanth-mariadb
MDEV-40220: Add server version to optimizer context

Additionaly, include Version_source_revision as well.
These are read only informative sya variables. So, they are included as
comments instead of SET commands.
Alexander Barkov
MDEV-39518 Allow prepared statements in stored functions in assignment right hand

Allowing prepared statements in stored functions when
a stored function is used in an assignment right hand.

Both DEFALT clause of a variable initialization and
the right side of the SET statement are supported:

  CREATE PROCEDURE p1()
  BEGIN
    -- case 1: DEFAULT clause
    DECLARE spvar1 INT DEFAULT f1_with_ps(); -- OK

    -- case 2: SP variable assignment statement
    DECLARE spvar2 INT;
    SET spvar= f1_with_ps(); -- OK
  END;

- The parser now does not reject PS statements in stored functions.
  PS applicability in stored functions is now detected as run time.
  Note, PS statements in triggers are still prohibited by the parser.

- Functions with PS do not acquire MDL locks on tables.
  They work like procedures in terms of table opening.

- Functions with PS are not replicated as a single `SELECT f1()` call.
  They are replicated per-statement, like procedures.
bsrikanth-mariadb
MDEV-39916: Crash with having filter when being pushed down

When Item_func_not::fix_fields() is invoked, there are several instances where
ref argument being passed is NULL. One such instance is from the method
st_select_lex::pushdown_from_having_into_where().

Since a null ref is being accessed, a crash occurs.

This PR fixes the problem by not passing null to
Item_func_not::fix_fields() when caling it from
st_select_lex::pushdown_from_having_into_where()
bsrikanth-mariadb
MDEV-16462: explain format=json produces illegal json text

The attached_condition field of the produced json text had
"String with illegal unicode symbol" instead of the proper unicode
value.

The reason is that, the item field when being written to the json
writer in write_item(), used a String with charset my_charset_bin,
and that prevented the string from being escaped.

Solution is to change the charset to system_charset_info, and also use
writer->add_str(str), instead of writer->add_str(str.c_ptr_safe());
Sergei Golubchik
MDEV-28743 MDEV-28743 Roles without grants are handled wrong

In propagate_role_grants_action() (called by grant_reload() on startup
and FLUSH PRIVILEGES), role privilege merging uses a counter-based
bottom-up ordering: each role's counter tracks how many of its granted
sub-roles still need to be processed, and merge_role_privileges() merges
a role only once its counter reaches zero.

The bug: when an intermediate role such as org_role_1 (which inherits
only from a USAGE-only app_role_1) was merged with no privilege changes,
merge_role_privileges() returned 1 as an optimisation to stop upward
traversal.  This prevented the traversal from ever reaching user_role_1
to decrement its counter.  A second leaf traversal (from app_role_2)
could decrement user_role_1's counter only once, leaving it at 1
instead of 0, so user_role_1 was never merged and had no effective
privileges.

The "stop if nothing changed" optimisation is valid for incremental
propagate_role_grants() calls (after a single GRANT/REVOKE), where
every ancestor was already correctly merged.  It is not valid for the
full-reload case, where the counters must be decremented by every leaf
traversal to guarantee correct bottom-up ordering.

Fix: add an initial_load flag to PRIVS_TO_MERGE.  When set (only in
propagate_role_grants_action), the early-stop optimisation is disabled
so traversals always visit all ancestors.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
Brandon Nesterenko
MDEV-39710: Update git modules WSREP Links to mariadb-corporation

The .gitmodules file still uses the old Codership Github repo link. This
redirects to the mariadb-corporation repo, so it isn't a functional
problem, but it should still be updated to the correct repo.
Sergei Golubchik
MDEV-23486 RBR can bypass secure_timestamp=YES

fix TIMESTAMP DEFAULT NOW() and ON UPDATE NOW()

Caveat: rbr cannot work without an index - if the slave overwrites
timestamp columns, before-image won't match in full, this is expected.
Alexander Barkov
MDEV-39518 Allow prepared statements in stored functions in assignment right hand

Allowing prepared statements in stored functions when
a stored function is used in an assignment right hand.

Both DEFALT clause of a variable initialization and
the right side of the SET statement are supported:

  CREATE PROCEDURE p1()
  BEGIN
    -- case 1: DEFAULT clause
    DECLARE spvar1 INT DEFAULT f1_with_ps(); -- OK

    -- case 2: SP variable assignment statement
    DECLARE spvar2 INT;
    SET spvar= f1_with_ps(); -- OK
  END;

- The parser now does not reject PS statements in stored functions.
  PS applicability in stored functions is now detected as run time.
  Note, PS statements in triggers are still prohibited by the parser.

- Functions with PS do not acquire MDL locks on tables.
  They work like procedures in terms of table opening.

- Functions with PS are not replicated as a single `SELECT f1()` call.
  They are replicated per-statement, like procedures.
Vladislav Vaintroub
MDEV-39343 Restoring from a mysqldump from older version makes mysql_upgrade version test fail

Do not skip the whole upgrade when mysql_upgrade_info is up to date.
System tables can still be from an older version, e.g when a dump from
an older server was restored. Only checks of user tables are skipped.
Alexander Barkov
MDEV-39518 Allow prepared statements in stored functions in assignment right hand

Allowing prepared statements in stored functions when
a stored function is used in an assignment right hand.

Both DEFALT clause of a variable initialization and
the right side of the SET statement are supported:

  CREATE PROCEDURE p1()
  BEGIN
    -- case 1: DEFAULT clause
    DECLARE spvar1 INT DEFAULT f1_with_ps(); -- OK

    -- case 2: SP variable assignment statement
    DECLARE spvar2 INT;
    SET spvar= f1_with_ps(); -- OK
  END;

- The parser now does not reject PS statements in stored functions.
  PS applicability in stored functions is now detected as run time.
  Note, PS statements in triggers are still prohibited by the parser.

- Functions with PS do not acquire MDL locks on tables.
  They work like procedures in terms of table opening.

- Functions with PS are not replicated as a single `SELECT f1()` call.
  They are replicated per-statement, like procedures.
Alexander Barkov
MDEV-39518 Allow prepared statements in stored functions in assignment right hand

Allowing prepared statements in stored functions when
a stored function is used in an assignment right hand.

Both DEFALT clause of a variable initialization and
the right side of the SET statement are supported:

  CREATE PROCEDURE p1()
  BEGIN
    -- case 1: DEFAULT clause
    DECLARE spvar1 INT DEFAULT f1_with_ps(); -- OK

    -- case 2: SP variable assignment statement
    DECLARE spvar2 INT;
    SET spvar= f1_with_ps(); -- OK
  END;

- The parser now does not reject PS statements in stored functions.
  PS applicability in stored functions is now detected as run time.
  Note, PS statements in triggers are still prohibited by the parser.

- Functions with PS do not acquire MDL locks on tables.
  They work like procedures in terms of table opening.

- Functions with PS are not replicated as a single `SELECT f1()` call.
  They are replicated per-statement, like procedures.
Sergei Golubchik
MDEV-24598 Duplicate CHECK constraint names are allowed

Column-level CHECK constraints derive their effective name from the column's
field name when read from frm (name_length=0 fallback in
init_from_binary_frm_image). An explicit table-level constraint with the same
name as a column that carries a column-level check creates a duplicate in
information_schema.check_constraints.

Two cases:
1. CREATE TABLE t (a INT CHECK (a>2), CONSTRAINT a CHECK (a<5)) -- both
  end up named "a".
2. JSON columns auto-receive a JSON_VALID column check named after the field.
  CREATE TABLE t (json_c1 JSON, CONSTRAINT json_c1 CHECK (...)) produces
  a duplicate "json_c1".

Fix in mysql_prepare_create_table_finalize: when validating explicit
table-level constraint names, also check them against field names of columns
that carry column-level check constraints (ER_DUP_CONSTRAINT_NAME).

Fix in make_unique_constraint_name / fix_constraints_names: pass the column
list so that auto-generated names (CONSTRAINT_1, CONSTRAINT_2, ...) skip
names already taken by column-level checks.

Update check_constraint.test: the MDEV-16630 test relied on the now-rejected
duplicate (column check "b" + table constraint "b"). Rename the table-level
constraint to "b_and_a" to preserve the intent: verifying that field
constraints and table constraints produce distinct error-message formats.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
jmestwa-coder
MDEV-40200 bound shift width in dyncol integer readers

The dynamic column integer decoders derive the shift exponent from the
data interval length without bounding it to the 64-bit type width.

dynamic_column_uint_read() loops over the interval doing
value+= data[i] << (i*8). A record whose integer column has an interval
longer than 8 bytes drives i*8 to 64 and past it, which is undefined and
aborts under -fsanitize=shift. dynamic_column_var_uint_get(), used for the
charset id of a string value and for the intg/frac of a decimal, has the
same defect: length*7 grows without bound over a run of 0x80 continuation
bytes.

Reject integers longer than 8 bytes with ER_DYNCOL_FORMAT, propagate that
through dynamic_column_sint_read(), and cap the varint loop at 10 groups.

To reproduce, build with -fsanitize=shift and read with COLUMN_GET() a
record whose integer column data interval exceeds 8 bytes; the shift
exponent reaches 64 in dynamic_column_uint_read(). A new case in the
ma_dyncol unit test crafts such a record and checks it is rejected.
Alexey (Holyfoot) Botchkov
MDEV-40008 sql_error.cc:357: void Diagnostics_area::set_ok_status after CHECK (XMLISVALID..

Two things fixed. Firstly the error returns proper ::fix_length_and_dec
result.
Then the XML Schema allows elements with no type specified. The element
should has no value at all or only whitespaces as a value.
Sergei Golubchik
MDEV-37951 SHOW TABLES allows users with only GRANT OPTION privilege to read all table names in the database "mysql"

GRANT_ACL bleeds into thd->col_access via check_access()'s
"*save_priv |= db_access" path (db_access inherits master_access).
Two guards that relied on the absence of any privilege bit then
failed to treat GRANT_ACL as exceptional:

1. check_show_access() (sql_parse.cc): the fallback
  "!col_access && check_grant_db()" was bypassed when col_access
  held only GRANT_ACL, letting a global-GRANT-OPTION user pass the
  outer gate for SHOW TABLES / SHOW TABLE STATUS / SHOW TRIGGERS.
  Fix: use !(col_access & ~GRANT_ACL) so any real privilege still
  bypasses check_grant_db while GRANT_ACL alone does not.

2. get_all_tables() (sql_show.cc): the per-table shortcut
  "!(col_access & TABLE_ACLS)" was taken for col_access == GRANT_ACL
  because GRANT_ACL is part of TABLE_ACLS, skipping per-table checks
  and exposing all table names.
  Fix: use TABLE_ACLS & ~GRANT_ACL so that only genuine table-access
  bits suppress the per-table privilege check.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
Alexey Yurchenko
MDEV-40179 Found N prepared transactions after mariabackup SST

With log_bin=ON a transaction is committed via two-phase commit (the
binary log is the second participant), so it passes through the InnoDB
XA-prepare state. While a donor is held in BLOCK_COMMIT for a mariabackup
backup, its parallel appliers (wsrep_slave_threads > 1) leave one or more
such writesets prepared-but-not-yet-committed, and the snapshot captures
them. On a freshly SST'd joiner nothing resolves these prepared
transactions: binlog crash recovery does not run (the joiner has no in-use
binlog to recover from), and the wsrep continuity-based commit is inactive
because wsrep_emulate_bin_log is FALSE when log_bin is ON. The leftover
prepared transactions then abort startup with "Found <N> prepared
transactions!". Note this does not depend on the prepared set being
non-contiguous - even a contiguous run aborts, because nothing commits
or rolls it back.

Rollback these transactions in xarecover_handlerton(). If rollback fails
flag error to cause unireg_abort().
Rex Johnston
MDEV-26940 Item_cond::remove_eq_conds leaves corrupt Item_equal

pushdown_cond_for_derived/merge_into_list/remove_eq_conds leaves
an Item_equal in an invalid state.  This Item_equal is later used
by find_producing_item causing an assert in debug builds and perhaps
incorrect results in a release build.

Affected queries will likely have an outer condition pushed down into
2 different derived tables based on the same base table.
Sergei Golubchik
MDEV-23486 RBR can bypass secure_timestamp=YES

Add tests for system versioning.
INSERT is fixed, but UPDATE is still broken.
Rucha Deodhar
MDEV-40125: OLD_VALUE crashes on a view with an expression

Analysis:

When OLD_VALUE() is used on a view, field resolution creates an
Item_direct_view_ref instead of an Item_field. Item_old_field::fix_fields()
continued assuming that a Field object was available, but view references
do not have a field pointer, which resulted in a crash.

Fix:
Store the real referenced item in Item_old_field::expr and use it when
the OLD_VALUE() reference does not have a Field object. This allows
OLD_VALUE() to work with view fields and avoids dereferencing a NULL
field pointer. Fix relevant methods accordingly.
Vladislav Vaintroub
MDEV-37996 CMake: MariaDB:: targets for bundled-or-system libraries

Stop overwriting the standard find_package() result variables (ZLIB_FOUND,
ZLIB_LIBRARIES, ZLIB_INCLUDE_DIR(S), ...), this breaks vcpkg.

Provide namespaced INTERFACE targets that point at either the bundled or
the system library and carry their include directories (and, for SSL, the
compile definitions):

  MariaDB::zlib, MariaDB::OpenSSL, MariaDB::pcre2-8, MariaDB::pcre2-posix,
  MariaDB::fmt, MariaDB::readline

Link these consistently instead of the scattered ${*_LIBRARIES} and
${*_INCLUDE_DIR(S)} variables sprinkled across the tree.
Sergei Golubchik
MDEV-30555 The server does not detect changes in NULL-ability of system table columns

Table_check_intact::check() validated column names, types, and charsets but
not NULL-ability. Altering a system table column (e.g. mysql.proc.definer)
to drop NOT NULL would pass the check undetected, silently corrupting data
stored through that column.

Add a CAN_BE_NULL flag bit in the high bit of TABLE_FIELD_TYPE::type.length.
Set it on nullable column entries; the check now validates nullability in both
directions. NOT NULL columns need no annotation (the common case). The flag
is encoded as `{ STRING_WITH_LEN("type") + CAN_BE_NULL }` which keeps the
intent readable at the definition site.

Apply CAN_BE_NULL annotations to all TABLE_FIELD_TYPE arrays:
mysql.proc, mysql.event, mysql.table_stats, mysql.column_stats,
mysql.index_stats.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
Alexey (Holyfoot) Botchkov
MDEV-40019 Xmlisvalid shows wrong result if calling it multiple times from query with UNION ALL.

Call the validation_prepare() for the tail of the list.
Teemu Ollakka
MDEV-40179 Simplify wsrep XA recovery: drop the seqno-continuity check

wsrep_order_and_check_continuity() sorted recovered prepared XIDs by
wsrep seqno and used the contiguous run from the SE checkpoint to
decide which prepared transactions could be committed locally when no
binlog was available for recovery. This was mostly dead weight:

- With a real local binlog, recovery is already fully binlog-
  coordinated (XID_EVENT presence decides commit/rollback); the
  continuity result was computed but never consulted.
- Without one (log_bin=OFF, or a fresh SST joiner with no local
  binlog), any transaction still prepared at recovery time was never
  committed on this node, so rolling it back is always safe - the
  cluster redelivers it via IST/SST, regardless of whether the
  prepared set was contiguous.

Drop wsrep_order_and_check_continuity() and the wsrep_limit-gated
commit path. The final dry-run recovery pass now unconditionally rolls
back any wsrep-tagged prepared transaction when a provider is loaded
(previously only done for the SST-joiner case); the TC_LOG_MMAP path
(log_bin=OFF) takes the same unconditional-rollback fallback instead
of committing a "safe" contiguous prefix. Also remove the now-unused
wsrep_sort_xid_array() and wsrep_is_xid_gtid_undefined() helpers and
the discontinuity-message test suppression.
Daniel Black
MDEV-37869 binlog.binlog_unsafe fails on Windows

And macos.

The order of the Table_map events don't actually matter in this test.
The important aspect is the Annotate_rows and Write_rows_v1 events.

Lets exclude the Table_map events in the show_binlog_events.inc
aspect of this test.

The show_events.inc has been extended to support this
$skip_tablemap_events=1 variable. $skip_checkpoint_event only has
two usages so we haven't tried to support both together until
needed.
Pekka Lampio
MDEV-40279  Further improvements

Removed unnecessary --enable/disable_query_log statements.
Pekka Lampio
MDEV-40279 galera.tmp_space_usage test failure

The MTR test galera.tmp_space_usage printed the exact Tmp_space_used /
Max_tmp_space_used byte counts. These come from the binlog cache
temporary file, whose size depends on binary log event encoding and
thus varies across platforms and builds, making the test fail
(e.g. 101706 vs the recorded 102054).

Rewrite the test to check only the invariants the fix is about, as is
already done in main.tmp_space_usage: after the inserts Tmp_space_used
is non-zero and equals Max_tmp_space_used, and after change_user
Tmp_space_used is reset to 0 while Max_tmp_space_used is preserved.

Co-Authored-By: Claude Opus 4.8
Jaeheon Shim
MDEV-39932 Accept aggregated outer columns in subquery

Under ONLY_FULL_GROUP_BY, a query that aggregates an outer column inside
a subquery is wrongly rejected. This is fixed in
Item_field::fix_outer_field by not appending the field to
select->join->non_agg_fields when thd->lex->in_sum_func is not null.

Furthermore, in Item_sum::check_sum_func, for all outer fields that are
not aggregated at their SELECT_LEX's nest level, we append these fields
to sel->join->non_agg_fields in order to ensure that
ER_WRONG_FIELD_WITH_GROUP is still raised for invalid aggregation.
Vladislav Vaintroub
MDEV-37996 update libmariadb to use server's MariaDB::zlib

Remove hack in cmake/mariadb_connector_c.cmake that sets variables
to make connectors FIND_PACKAGE(ZLIB) use server's zlib.
it is not necessary anymore, and is expressed more directly.
Sergei Golubchik
MDEV-30041 don't set utf8_is_utf8mb3 by default in the old-mode
Vladislav Vaintroub
MDEV-39047 Impossible to create DB grant for long escaped DB name

The database name in GRANT is stored in mysql.db.Db, which holds 64
characters. Escaping '_' or '%' with a backslash to match them literally
can make the stored name longer than 64 characters, and it was silently
truncated into a non-functional grant. Reject it with ER_WRONG_DB_NAME
instead, the same error CREATE DATABASE gives for an over-long name.
forkfun
MDEV-23444 ASAN dynamic-stack-buffer-overflow or Assertion `precision > 0'
failed in decimal_bin_size with div_precision_increment=0

A signed numeric value of display length 1 (WEEKDAY(), DAYOFWEEK(), @v:=<int>)
had decimal_precision() == 0: my_decimal_length_to_precision() subtracted a
digit for the sign with no lower bound. Turning such a value into a DECIMAL
(division, AVG(), a UNION column) produced precision 0, which tripped the
`precision > 0' assertion in decimal_bin_size() on store, GROUP BY or filesort.

Clamp my_decimal_length_to_precision() to a minimum of 1 so precision is never 0.

Side effect: in a query CREATE TABLE t1 SELECT * FROM (SELECT 1 as a,(SELECT a)) a;
`(SELECT a)` column now reports width 2 (digit + sign).
It's an invalid query that's supported for historical reasons, and all valid queries
did not change their results
Yuchen Pei
MDEV-15621 [to-squash] Follow some gemini review comments

Also removed table_rows in a SELECT, to avoid an unrelated flaky failure
Dave Gosselin
MDEV-39323 Fix Item_func_between::get_mm_tree()

simplification of prior commit with additional test cases
Alexey (Holyfoot) Botchkov
MDEV-40054 Assertion `0' failed in XMLSchema_item::validate_tag with element name "xml".

That check for the 'xml' tag makes no sence after we have the processing
instruction handler.
forkfun
MDEV-30295 mysqldump produces syntactically incorrect statement

Remove version-specific executable comments, that were used for backward compatibility
with old MySQL versions (3.2, 4.0, 4.1, 5.0).
Thirunarayanan Balathandayuthapani
MDEV-19574: innodb_stats_method is not honored when innodb_stats_persistent=ON

Problem:
=======
When persistent statistics are enabled (innodb_stats_persistent=ON),
the innodb_stats_method setting is not properly utilized during
statistics calculation.

The statistics collection functions always use a hardcoded default
behavior for NULL value comparison instead of respecting the
configured stats method (NULLS_EQUAL, NULLS_UNEQUAL, or
NULLS_IGNORED). This affects the accuracy of n_diff_key_vals
(distinct key count) and n_non_null_key_val estimates, particularly
for indexes with nullable columns containing NULL values. This
impacts the query optimizer, which makes decisions based on
inaccurate cardinality estimates.

Solution:
========
Introduced IndexLevelStats to collect statistics at a specific
B-tree level during index analysis.

Introduced PageStats to collect statistics for leaf page analysis.

Refactored the following functions:
dict_stats_analyze_index_level() to IndexLevelStats::analyze_level()
dict_stats_analyze_index_for_n_prefix() to IndexLevelStats::sample_leaf_pages()
dict_stats_analyze_index_below_cur() to PageStats::scan_below()
dict_stats_scan_page() to PageStats::scan()

Add the stats method name to stat_description when innodb_stats_method
has a non-default value.

Added the new stat name n_nonnull_fld01, n_nonnull_fld02, etc. with a
stats description, to indicate how many non-null values exist for the
nth field of the index. This value is retrieved and stored in the index
statistics in dict_stats_fetch_index_stats_step().

rec_get_n_blob_pages(): Calculate the number of externally stored pages
for a record. It uses ceiling division with the actual usable blob page
space (blob_part_size) and now correctly handles both compressed and
uncompressed table formats for accurate BLOB page counting.

When InnoDB scans the leaf page directly, assign the leaf page count as
the number of pages scanned for a multi-level index. For single-page
indexes, use 1. This change leads to multiple changes in existing
test cases.

Non-null values are only counted at the leaf level, since only leaf
pages hold actual records. Both nullable and NOT NULL columns are
estimated with the same leaf-sampling formula:

  n_ordinary_leaf_pages * (n_non_null_all_analyzed_pages
                          / n_leaf_pages_to_analyze)

For a NOT NULL column every record is counted, so this yields the
estimated record count (no NULLs).

dict_stats_save(): now static function in dict0stats.cc that
takes the innodb_stats_method value, and is removed from dict0stats.h.

Replaced btr_rec_get_externally_stored_len() with rec_get_n_blob_pages()
in dict0stats.cc. btr_rec_get_field_ref_offs() and btr_rec_get_field_ref(),
together with the BTR_BLOB_HDR_* macros, were moved from btr0cur.cc
to btr0cur.h so that rec_get_n_blob_pages()
can reuse them;

btr_rec_get_field_ref_offs() is now a noexcept function returning size_t.

Changed stat_n_diff_key_vals and stat_n_non_null_key_vals from
ib_uint64_t* to uint64_t*

Removed the unused UNIV_STATS_DEBUG build macro (univ.i) and turned the
DEBUG_PRINTF() helper in dict0stats.cc into an unconditional no-op.
Vladislav Vaintroub
MDEV-37996 CMake: MariaDB:: targets for bundled-or-system libraries

Stop overwriting the standard find_package() result variables (ZLIB_FOUND,
ZLIB_LIBRARIES, ZLIB_INCLUDE_DIR(S), ...), this breaks vcpkg.

Provide namespaced INTERFACE targets that point at either the bundled or
the system library and carry their include directories (and, for SSL, the
compile definitions)

  MariaDB::zlib, MariaDB::OpenSSL, MariaDB::pcre2-8, MariaDB::pcre2-posix,
  MariaDB::fmt, MariaDB::readline

Link these consistently instead of the scattered ${*_LIBRARIES} and
${*_INCLUDE_DIR(S)} variables sprinkled across the tree.

Update libmariadb to latest 3.3 that is already prepared to handle MariaDB::zlib
Alexey Yurchenko
MDEV-38147 error 1950 after mariabackup SST with gtid_strict_mode=ON

After a mariabackup SST the joiner could fail with

  ER_GTID_STRICT_OUT_OF_ORDER (error 1950)

while re-binlogging transactions received over IST.

The cause is that the binary log copied from the donor carries a
Gtid_list whose position can be ahead of the storage-engine snapshot:
BACKUP STAGE BLOCK_COMMIT blocks the engine commit (2PC step 3) but not
the binary log write (step 2), so transactions can be present in the
copied binlog that are not committed in the copied engine snapshot.
After the SST the joiner reports the (committed) engine position to the
cluster, IST resends those transactions, and re-binlogging them under
gtid_strict_mode=ON collides with the ahead Gtid_list -> error 1950.
(MDEV-34483 made the engine snapshot stop short of the binlog, which is
what exposed this.)

The copied binary log carries no transactions the joiner needs - only a
Gtid_list - so instead of shipping and then having to truncate/reconcile
it, the joiner now starts a fresh binary log and seeds its GTID position
from the storage-engine checkpoint during recovery. That checkpoint is
the committed cluster position, i.e. exactly where IST resumes, so the
joiner's binary log stays in lockstep with the rest of the cluster and
no out-of-order GTID can occur.

This works for both wsrep_gtid_mode settings; only the binlog domain of
the cluster stream differs:

  - wsrep_gtid_mode=ON : wsrep_gtid_domain_id (cluster writes are
    re-tagged to it), which is the domain stored in the checkpoint;
  - wsrep_gtid_mode=OFF: gtid_domain_id (cluster writes keep the node's
    configured domain).

Async-replica positions (mysql.gtid_slave_pos) are part of the engine
snapshot and survive the SST unchanged, so a Galera node can still serve
as an async master or replica across the SST.

This commit:
- sql/log.cc: adds wsrep_seed_binlog_gtid_state(), called from
  do_binlog_recovery() when the joiner has no binary log, seeding the
  binlog GTID state for the cluster domain to the SE checkpoint position.
- scripts/wsrep_sst_mariabackup.sh: no longer moves the donor's binary
  log into place on the joiner.
- extra/mariabackup: backward compatibility: keep shipping binlog file
  in SST but
  - on donor fix the race between rotation and shipping so that the file
    shipped is the one that had been rotated;
  - on joiner discard shipped binlog in favour of one generated by
    wsrep_seed_binlog_gtid_state().
- sql/wsrep_sst.cc: logs the position actually adopted from storage
  (the authoritative post-SST position) rather than the script-reported
  one.
- sql/handler.cc: downgrades the "Discovered discontinuity in recovered
  wsrep transaction XIDs" message in wsrep_order_and_check_continuity()
  from warning to debug level. With parallel appliers a snapshot
  routinely captures prepared XIDs that are not contiguous with the
  engine checkpoint, so this is normal during SST recovery and of no
  value in regular operation; the transactions past the checkpoint are
  re-delivered by the cluster (IST/SST) regardless.
- Adds an MDEV-38147 MTR test reproducing the issue.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
Alexey (Holyfoot) Botchkov
MDEV-40008 sql_error.cc:357: void Diagnostics_area::set_ok_status after CHECK (XMLISVALID..

Two things fixed. Firstly the error returns proper ::fix_length_and_dec
result.
Then the XML Schema allows elements with no type specified. The element
should has no value at all or only whitespaces as a value.