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
Georgi (Joro) Kodinov
MDEV-39572: Fix small typos in COMMUNITY_CONTRIBUTIONS.md

Fixed some minor header typos in the document.
Alexander Barkov
Cleanup for MDEV-39518 Allow PS in SF in assignment right hand

Fixing the "End of 13.1 tests" to "End of 13.2 tests",
as the task got into 13.2 release only.
Daniel Black
MDEV-40949 Missing space after how-to-produce-a-full-stack-trace-for-mariadb link
Vladislav Vaintroub
MDEV-39533 my_realpath and MY_NOSYMLINKS on Windows

On Windows, my_realpath() only called GetFullPathName(), which
canonicalizes '.', '..' and drive letters but does not resolve NTFS
symlinks, junctions or mount points, unlike POSIX realpath(). At the
same time, my_open() and my_delete() ignored MY_NOSYMLINKS entirely,
so the symlink-attack protection used for MyISAM/Aria's DATA
DIRECTORY/INDEX DIRECTORY (mi_open()/ma_open(),
my_handler_delete_with_symlink()) was silently absent on Windows.

Fix my_realpath() to actually resolve reparse points: open the
(syntactically canonicalized) path with CreateFile(), which follows
them, and read back the handle's fully resolved path with
GetFinalPathNameByHandle(). A not-found path still gets the same
ENOENT/fallback contract as before.

Make my_open() and my_delete() honor MY_NOSYMLINKS on Windows.
Windows has no per-path-component O_NOFOLLOW equivalent, so instead
this mirrors the realpath()-equality branch of the POSIX
NOSYMLINK_FUNCTION_BODY macro: the caller-supplied name (expected to
already be my_realpath()-resolved) is compared against the actually
opened handle's resolved path, and rejected with ENOTDIR -- the same
errno POSIX uses for this exact "not already canonical" condition --
on a mismatch, whether caused by a TOCTOU symlink swap or by the name
never having been fully resolved to begin with.

Add a my_symlink-t.c test that creates a real NTFS junction to verify
resolution and enforcement.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
Daniel Bartholomew
Merge branch 'bb-10.11-bumpversion' of github.com:MariaDB/server into bb-10.11-bumpversion
Marko Mäkelä
MDEV-40410: Tight innodb_buffer_pool_size_max on ThreadSanitizer

bur_pool_t::size_in_bytes_max_default: Define as 0 also on
ThreadSanitizer. The symbol __SANITIZE_THREAD__ is predefined
starting with Clang 22 or GCC 7 when building with -fsanitize=thread.
Vladislav Vaintroub
MDEV-39533 my_realpath and MY_NOSYMLINKS on Windows

On Windows, my_realpath() only called GetFullPathName(), which
canonicalizes '.', '..' and drive letters but does not resolve NTFS
symlinks, junctions or mount points, unlike POSIX realpath(). At the
same time, my_open() and my_delete() ignored MY_NOSYMLINKS entirely,
so the symlink-attack protection used for MyISAM/Aria's DATA
DIRECTORY/INDEX DIRECTORY (mi_open()/ma_open(),
my_handler_delete_with_symlink()) was silently absent on Windows.

Fix my_realpath() to actually resolve reparse points: open the
(syntactically canonicalized) path with CreateFile(), which follows
them, and read back the handle's fully resolved path with
GetFinalPathNameByHandle(). A not-found path still gets the same
ENOENT/fallback contract as before.

Make my_open() and my_delete() honor MY_NOSYMLINKS on Windows.
Windows has no per-path-component O_NOFOLLOW equivalent, so instead
this mirrors the realpath()-equality branch of the POSIX
NOSYMLINK_FUNCTION_BODY macro: the caller-supplied name (expected to
already be my_realpath()-resolved) is compared against the actually
opened handle's resolved path, and rejected with ENOTDIR -- the same
errno POSIX uses for this exact "not already canonical" condition --
on a mismatch, whether caused by a TOCTOU symlink swap or by the name
never having been fully resolved to begin with.

Add a my_symlink-t.c test that creates a real NTFS junction to verify
resolution and enforcement.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
Hemant Dangi
MDEV-40501: Assertion `info->type == READ_CACHE || info->type == WRITE_CACHE' failed in reinit_io_cache upon CHANGE MASTER

Issue:
CHANGE MASTER ... FOR CHANNEL with a channel name within
MAX_CONNECTION_NAME can still overflow the OS file name limit once
escaped into the relay log file name. Relay_log_info::init() then
fails to open the relay log, leaving its index file unopened, but
Master_info_index::remove_master_info() unconditionally calls
reset_logs() on it during CHANGE MASTER's error cleanup, which hits
the assertion in reinit_io_cache().

Solution:
Guard the reset_logs() call in remove_master_info() with is_open(),
so a relay log that was never opened is never passed to it. Also use
MY_SAFE_PATH in open_index_file() so an over-length name fails
deterministically instead of silently falling back to a mangled one.
Daniel Black
MDEV-40921 Large allocations Use MMAP_NORESERVE (but not large_pages)

The default innodb_buffer_pool_size_max of 8TiB cannot be reserved on
Illumos because anonymous mappings reserve backing store (swap) when they
are created, irrespective of the page protections. Pass MAP_NORESERVE when
reserving the buffer pool address range; swap is still properly reserved,
and out-of-memory reported, when ranges are committed.

commit message by Andy Fiddaman.

On Linux MAP_NORESERVE has similar meaning in that no swap space is
reserved. In the Linux case per manual(mmap), mariadbd may SEGV if there
isn't the swap space available. This quick kill seems preferable to
attempting to run a buffer pool from swap.

Note MAP_NORESERVE isn't used for large pages as we want the allocation
failure to be early. Having failure on a first access here is
unrecoverable while an large page allocation failure can fall back to
a non-large page.

Place -1 ptr constant with MAP_FAILED. Its used elsewhere in code and
matches mmmap documentation.

Other BSDs and MacOS appear to not implement the flag.
Jaeheon Shim
MDEV-40698 Fix ROLLUP query results with empty result set

ROLLUP is defined as the UNION of grouping by every prefix of fields in
the original GROUP BY list. A ROLLUP query with an empty result set
returned zero rows when it should return a summary NULL, since grouping
by the empty prefix returns a single summary row.

The empty row case is handled in two separate locations. First, if the
optimizer is able to determine that no rows will be produced, e.g. due
to the table being empty or the WHERE condition resolving to false,
JOIN::send_row_on_empty_set is used to determine whether or not to send
an empty result row. Therefore, send_row_on_empty_set is modified to
include select_lex->olap == ROLLUP_TYPE.

Second, it may be the case that the absence of rows is not confirmed
until the execution phase. For instance when the WHERE condition is not
constant, or in the case of InnoDB where an empty table is not detected
during optimization. This is handled in both end_send_group and
end_write_group by this expression

    join->first_record ||
        (end_of_records && !join->group && !join->group_optimized_away)

The condition is extracted into need_empty_set_row and a second variable
empty_set_send_rollup_total is recorded to prevent running the default
rollup_send_data/rollup_write_data on the empty row case. This is
because the null summary row is already handled by send_data_with_check.
KhaledR57
MDEV-37167 Nested BEGINs (4600+) cause a segmentation fault

Each nested BEGIN adds one sp_pcontext. Two walks over the finished
tree recursed once per nesting level and overran the thread stack.

~sp_pcontext() freed its children recursively. sp_head now threads a
single linked list through the contexts and frees them iteratively, so
teardown depth is constant and a context no longer frees its children.

retrieve_field_definitions() descends the children to build the
run-time frame. It emits them in run-time offset order, so it stays
recursive, but it now checks the stack and returns an error instead
of crashing.
Jan Lindström
MDEV-41017 : Galera test failure galera.galera_toi_alter_auto_increment

New warning was added in MDEV-33660 commit bd127faa. Re-record
test result file.
VasuBhakt
MDEV-40174 Remove unnecessary double parsing JSON document in `json_normalize`

`json_normalize`/`json_equals` unnecessary
double parsing JSON document

Removed the redundant `json_valid_engine` pre-check to eliminate
double-parsing, and integrated error handling directly into the
normalization engine:

* Catch Empty Strings: Return an error directly in
  `json_normalize_engine` if the root type is `JSON_VALUE_UNINITIALIZED`.

* Catch Trailing Garbage on Scalars: Updated `json_norm_build`
  to enforce a full scan to the end of the document for scalar values.
  This prevents edge cases (e.g., raw date strings like 2026-07-17...)
  from being falsely accepted as a valid JSON number without checking
  the remainder of the string for syntax errors.

* Propagate Syntax Errors: Updated `json_normalize_engine` to
  explicitly check the engine's error flag after the build phase.

* Add Edge Case Tests: Added tests in `json_normalize.test` for
  empty strings, whitespace, and trailing garbage on scalars to
  ensure correct error generation.

Testing:
Verified locally using MTR
(`main.json_normalize` and `main.json_equals`).

Signed-off-by: VasuBhakt <[email protected]>
Jan Lindström
MDEV-40281 : galera.galera_wsrep_new_cluster test failure

Rejoining with an emptied datadir requires a full SST, which on a loaded
machine does not finish within the 60 seconds galera_wait_ready.inc allowed,
aborting the test while the SST was still running. Let the readiness wait
take an optional $galera_wait_ready_timeout and give that restart 300
seconds.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
Marko Mäkelä
MDEV-40985 row_end access out of bounds in ALTER TABLE

ha_innobase_inplace_ctx::create_key_defs():
In the assignment that had been introduced in
commit e056efdd6cfa62cc4c978fce5730af0b8d4c3c6b (MDEV-25004),
account for virtual columns. Until MDEV-22363 hopefully lands
some day, InnoDB maintains two arrays of columns, which
complicates the mapping between TABLE_SHARE::fields and
dict_table_t::cols. This complication was not accounted for here.

Reviewed by: Thirunarayanan Balathandayuthapani
Jan Lindström
MDEV-41028 : Galera appliers deadlock on a foreign key referencing a CHAR column in a multi-byte character set

The write set key of a row is built from the MySQL record by
wsrep_store_key_val_for_row(), and the key of a foreign key parent row from
the InnoDB record by wsrep_rec_get_foreign_key(). A CHAR is not padded the
same way in the two formats: the MySQL record pads it to n_chars * mbmaxlen
bytes, while InnoDB strips that padding down to, but not below, n_chars
bytes. That compares a byte count with a character count, so a value holding
a multi byte character and shorter than the column was left with a different
number of characters on the two paths, and the keys differed. A child INSERT
then had no dependency on its parent row and the appliers ran it in parallel
with a change of that very row. The two paths did not agree on the strnxfrm
buffer length either, 3072 on one and 3500 on the other.

Both now go through wsrep_store_string_key_val(), which brings a CHAR to
exactly the number of characters the column holds and always normalizes with
WSREP_MAX_SUPPORTED_KEY_LENGTH, so that the key of a column does not depend
on how much room the columns before it happened to leave. Only the copy into
the caller's buffer is bounded by the space that is left, which also stops
wsrep_rec_get_foreign_key() from writing past its key buffer.

This changes the write set keys, so it is done from protocol version 5 on
and the old encoding is kept below that.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
sjaakola
MDEV-38869 sequence conflicts with streaming replication

Sequence access conflicts with streaming replication could cause the
server to hang, as shown in MDEV-38869.

A sequence table is written from SEQUENCE::next_value() while
SEQUENCE::mutex is held. For a streaming transaction the row write in
handler::ha_write_row() would then replicate a fragment and block waiting
for certification and commit order, while an applier may be waiting for
the same mutex in SEQUENCE::set_value(). Neither side can proceed, the
node deadlocks and the BF abort of the local transaction can never be
delivered.

This commit avoids the deadlock by skipping the streaming replication
step for sequence table rows. The row is already in the write set and is
replicated with the following fragment, or at commit.

Only that one step is skipped. The skip is passed down as a parameter to
wsrep_after_row() and wsrep_after_row_internal() rather than by not
calling them at all, so the row is still counted against
wsrep_max_ws_rows and wsrep_check_pk() still runs. A transaction using
sequences heavily therefore cannot silently exceed the configured write
set row limit.

The commit has also a new mtr test for three sequence/SR conflict
scenarios: galera.galera_sequences_bf_kill_sr

- a streaming transaction and an applier competing for SEQUENCE::mutex,
  where both are expected to commit

- the same, but with the applier also BF aborting the local transaction
  over a gap lock. A streaming transaction cannot be replayed, so it is
  rolled back and the client gets ER_LOCK_DEADLOCK. The applier is held
  at the abort_trx_end sync point until the abort has been issued, so
  that the local transaction cannot finish its fragment first

- twelve row inserts on both nodes with wsrep_trx_fragment_unit=rows, so
  that each node reserves several sequence cache ranges and the sequence
  table writes land inside fragments carrying several rows. The values
  the two nodes hand out must not overlap
Kristian Nielsen
MDEV-22848: SET GLOBAL gtid_slave_pos leaves dangling partial transaction

When AUTOCOMMIT=0, SET GLOBAL gtid_slave_pos did not properly commit the
(full) transaction, leaving the InnoDB hton registrered in the ha_list. This
could then later assert when InnoDB was called upon to eg. prepare() a
transaction that it does not participate in.

This patch makes rpl_slave_state::load() properly commit the (full)
transaction to solve the issue.

Reviewed-by: Brandon Nesterenko <[email protected]>
Reviewed-by: Monty <[email protected]>
Signed-off-by: Kristian Nielsen <[email protected]>
Thirunarayanan Balathandayuthapani
MDEV-41022 Wildcard term returns no rows when combined with a phrase in boolean mode search

Problem:
========
MATCH(..) AGAINST('"zzzz" aut*' IN BOOLEAN MODE) fails to return
the rows which match the wildcard term when the matching word is still
in the FTS cache. fts_query_phrase_search() sets query->flags to
FTS_PHRASE or FTS_PROXIMITY, but never resets it before returning.
The subsequent wildcard term of the same query then finds the stale
flag in fts_query_cache() and fts_query_difference(), takes the
exact word lookup path instead of fts_cache_find_wildcard()
and misses the words present in the cache.

Solution:
=========
- Reset query->flags in fts_query_phrase_search() before returning,
so that the phrase or proximity state doesn't leak into the terms
evaluated later in the same query.
Brandon Nesterenko
Disable rpl_parallel_multi_domain_xa

MDEV-34104 describes why this test fails. It was filed 2 years ago, but
the fix is complex, and we keep this failing test around hurting all
other devs. The fix is planned, once finished, we can re-enable this
test.

Signed-off-by: Brandon Nesterenko <[email protected]>
Vladislav Vaintroub
MDEV-38918 Make large pages an explicit per-caller opt-in

my_large_malloc() attempted large pages whenever --large-pages was
enabled, silently rounding the size up and reporting it back via an
in/out parameter. ut_malloc_dontdump() never passed that adjusted
size on to its own callers (the InnoDB redo log buffer and
recv_sys_t::tmp_buf), so freeing later used the original, smaller
size, causing the reported "faux memory leak".

Only the buffer pool and the MyISAM/Aria key caches are documented
to benefit from large pages. Everything else that ended up calling
my_large_malloc() only wanted its "do not dump to core" property and
picked up large pages as an undocumented side effect; those buffers
are also small and sequentially accessed, so they would have gained
little from large pages anyway.

Add MY_TRY_LARGE_PAGES: my_large_malloc() and my_large_virtual_alloc()
now only attempt large pages when a caller passes this flag, instead
of always trying whenever the global option is set. Only the buffer
pool and the key caches pass it. The redo log buffer, tmp_buf, and
row0log.cc's crypt buffers no longer request large pages at all,
which removes the size-rounding bug for them without touching that
code.

my_large_virtual_alloc()'s fallback (no usable large page size) must
also return read-write memory right away, like the Windows large-pages
fallback already does, since my_virtual_mem_commit() is a no-op for
MY_TRY_LARGE_PAGES. my_large_pages_flag is now set once, in
my_init_large_pages(), and never changed thereafter, on any platform.

Both my_virtual_mem_commit() and my_virtual_mem_decommit() are now
no-ops, aside from accounting, whenever large pages are requested.

Also fix a broken mtr suppression regex in main.large_pages that
would fail the test on Windows.
Akshat Nehra
MDEV-40867 CONNECT writes unvalidated data from remote filter into fixed-len buffer

TestFil() in storage/connect/tabtbl.cpp uses unbounded sscanf
format specifiers to parse TABID filter values pushed from
ha_connect::CheckCond(). When a WHERE tabname='...' filter
exceeds NAME_LEN bytes (192), sscanf overflows the
stack-allocated tn[NAME_LEN] buffer, corrupting the stack
and crashing mysqld with SIGSEGV.

Fix: add width specifiers to bound all sscanf writes:
- %7s for op[8]
- %192[^'] for tn (NAME_LEN bytes + null terminator)

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.
Kristian Nielsen
MDEV-39774: Assertion on slave with binlog_row_image=MINIMAL

When finding the row to modify for a row event, and when not using
rnd_pos_by_record() to locate the row, the code would use
table->use_all_columns(), which makes the read_set and write_set point
to the table->s->all_set in the table share. This caused problems when
other code later modified bits in the read_set or write_set, which
ends up wrongly modifying the table share.

We can just use bitmap_set_all(table->read_set) to mark to read all
columns and leave the possibility to later change the bits as needed.

This code changes in this patch must be null-merged from 10.11 to
11.4, as there the problem is fixed differently.

Signed-off-by: Kristian Nielsen <[email protected]>
Kristian Nielsen
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 <[email protected]>
Signed-off-by: Kristian Nielsen <[email protected]>
Monty
MDEV-40454 UBSAN: maria.aria_pack_mdev invalid-shift-exponent

Shifting with 64 is no-op in the the code (no ill effects).

Added a test to not do anything if shift with 64 would happen.
Tested with ma_test_all that test aria_pack.
Daniel Bartholomew
bump the VERSION
ParadoxV5
MDEV-40996 Support `--sync_with_master 0, $variable` in mysqltest

`--sync_with_master` uses `get_string()`,
which has `$variable` support, but it only uses the read buffer,
which is written with the unexpanded string and not the variable value.

Reviewed-by: KhaledR57 <[email protected]>
sjaakola
MDEV-41012 Galera appliers hang with foreign key of types UUID, INET4, INET6

For direct row writes, the certification key for MYSQL_TYPE_STRING and
MYSQL_TYPE_VARSTRING is built by collating the column value and taking the
collation from Field::charset().

The data types implemented on Field_fbt - UUID, INET6 and INET4
report MYSQL_TYPE_STRING, and their charset() is my_charset_numeric,
which is latin1. Their values are however plain binary and accordingly
innodb maps them to DATA_FIXBINARY. Their keys were therefore run through
latin1_swedish_ci, which folds them. That corrupts the key in two ways:

1. A key mismatch for the same row. The FK constraint's referenced key
that is appended for the parent of a child INSERT is
built from the InnoDB record and is not collated, and it does not match
the primary key appended due to the parent row's direct write.
Certification saw no dependency between a child INSERT and a concurrent
parent UPDATE, and two appliers could apply them in parallel causing
a hang or crash.

2. A key collision between distinct rows. The folding is many to one, so
different values collapse onto one key, Certification compares keys byte
for byte, so unrelated rows were treated as the same row. Concurrent
transactions on them certified as a conflict and one was aborted with
ER_LOCK_DEADLOCK.

Fix is for  wsrep_store_key_val_for_row() to skip the collation for
fields that InnoDB stores as binary, using the same condition as
get_innobase_type_from_mysql_type(). This is a no-op for the types that
worked before.

This change requires to bump the application protocol version to level 5.

The commit has also two mtr tests for regression testing.
Daniel Bartholomew
bump the VERSION
Kristian Nielsen
MDEV-40575: Sporadic failure of rpl.rpl_gtid_crash

The test fails because the slave is configured in the test with the flaky
--init-rpl-role=slave option by default. As the test case is crashing the
slave at various points, this option occasionally causes the slave to
*truncate* away a transaction during crash recovery, which is surely not
intended for this test.

The use of init-rpl-role=slave by default goes back to 2007(!), when this
option did not have any functionality, and when the option was re-purposed
for the flaky truncate-binlog-at-recovery functionality this default was
overlooked and not removed. The tests that want to test this marginal
functionality should (and do) enable it explicitly.

So remove the use of init-rpl-role=slave by default in the mtr --suite=rpl.

Signed-off-by: Kristian Nielsen <[email protected]>
Jacob Williams
MDEV-38757 Fix EXCHANGE PARTITION with generated columns containing AND/OR conditions

EXCHANGE PARTITION fails with ERROR 1736 (Tables have different definitions)
when tables contain generated columns with AND/OR conditions, even when the
expressions are logically equivalent. This occurs because when expressions are
re-parsed (e.g., via CREATE TABLE ... LIKE), the order of arguments in AND/OR
conditions may change, but the comparison was order-sensitive.

The Item_cond::eq() method was implemented to perform set-based comparison
for commutative AND/OR operations. The set-based comparison algorithm ensures
that two Item_cond expressions are considered equal if they contain the same set
of equivalent arguments, regardless of order.

Added comprehensive test case covering:
- Generated columns with OR conditions
- Generated columns with AND conditions
- Multiple generated columns with different AND/OR combinations
- Nested AND/OR conditions

The fix allows EXCHANGE PARTITION to succeed when expressions are logically
equivalent but have different argument ordering, which is correct behavior
since AND/OR operations are commutative.

MDEV-38757 Limit unordered vcol condition comparison to EXCHANGE PARTITION

Review follow-up to the previous commit, which made Item_cond::eq()
compare AND/OR argument lists as sets for every caller. That changed
equality semantics globally and broke main.derived_cond_pushdown, where
conditions that eq() started reporting as equal were dropped from
attached_condition. Reordering AND/OR operands also changes evaluation
order, which is observable when operands are functions, so the relaxed
comparison must not be the default.

Item::Eq_config gains an unordered_conditions flag, defaulting to false,
next to the existing binary_cmp and omit_table_names flags.
Item_cond::eq() compares its argument lists as sets only when that flag
is set, and otherwise reports two distinct Item_cond objects as unequal,
as it did before this patch series. The flag is threaded through
Virtual_column_info::is_equal() and a new mysql_compare_tables()
parameter, and only Sql_cmd_alter_table_exchange_partition passes it as
true, so the relaxed comparison stays confined to the EXCHANGE PARTITION
metadata check.

The set comparison tests containment in both directions rather than
comparing element counts, so an expression also matches a form that
repeats one of its terms, for example

  col1 > 10 and col2 < 100 or col3 > 50
  col3 > 50 or col1 > 10 and col2 < 100 or col3 > 50

Test 5 of parts.partition_exchange_generated_columns covers that case.
Alexander Barkov
Cleanup for MDEV-39518 Allow PS in SF in assignment right hand

Fixing the "End of 13.1 tests" to "End of 13.2 tests",
as the task got into 13.2 release only.
Hemant Dangi
MDEV-40944: Galera test failure on galera_sst_mariabackup_ssl_role_certs

Issue: mariadb-backup SST unconditionally passes socat's "commonname="
option; some socat builds don't register it, so parseopts() rejects
it as unknown regardless of value, breaking all SSL-encrypted SST.

Solution: probe the socat binary once for commonname support and
drop the option when unsupported.
Otto Kekäläinen
Promote getting GitHub stars in client prompt

Ask users to give MariaDB a star by having an extra line in the MariaDB
client prompt:

    Welcome to the MariaDB monitor.  Commands end with ; or \g.
    Your MariaDB connection id is X
    Server version: Y
    Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

    Help others discover MariaDB. Star it on GitHub: https://github.com/MariaDB/server

    Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

    MariaDB [(none)]>

Test file updated with:
nano --noconvert --nonewlines mysql-test/main/mysql-interactive.result

This change is similar to 346c7afe9b7071ce9c47892a83d69944b608b3da
applied on 'main', but without the SERVER_MATURITY_LEVEL check in order
to have this text visible in stable releases and actually help get the
GitHub star count up, and without the server log entry.
Marko Mäkelä
MDEV-40571 fixup: -Wmaybe-uninitialized

The local variable key_part_end that was introduced in
commit 3b1c2e58abab5571bec4ff52773ddc75b1738da9 (MDEV-40571)
would trigger a GCC warning. The warning is bogus; in fact,
before the variable will be read, it will have been initialised
when either keys==0 or i==0, which covers each code path
that does not lead to a return.
Daniel Black
MDEV-39285: dtrace to check for sys/sdt.h on Linux

Buildbot SRPM builders show it is possible to have dtrace
(the program) installed without the sys/sdt.h.

The dtrace program using -h generated source code that
includes the sys/sdt.h header so lets make sure it exists.

To make sure that SRPM picks up all include headers,
we check that in cmake/build_depends.cmake and let
the discovery of all the include headers contribute
to the build dependencies. Where there is multiple assume
that all header files original from the same package
and search for the last one.
Jan Lindström
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 <[email protected]> for
providing test case and fix candidate.
Vladislav Vaintroub
Rocksdb - suppress MSVC warning in external code

ribbon_impl.h(879,1): warning C4723: potential divide by 0
on VS2025
Vladislav Vaintroub
MDEV-33959 mysqldump: dump sequences before tables across databases

mariadb-dump --all-databases (or --databases with several databases)
dumps databases in SHOW DATABASES order. If a table in one database
defaults a column to nextval() of a sequence living in a different
database, and that database sorts later, the resulting dump fails to
reload with "Table 'db.seq' doesn't exist" -- the table gets created
before the sequence it depends on.

MDEV-21785 already dumps sequences before tables within a single
database, but that alone doesn't help when the dependency crosses a
database boundary.

Fix by adding a sequences-first pre-pass (dump_all_sequences_in_db)
that runs over every database being dumped before any of them reaches
the existing per-database table-dump pass, mirroring the "dump all
tables, then all views" two-pass shape already used in this file for
views. To keep output byte-for-byte unchanged for the common case of a
database with no sequences, the pre-pass only creates a database if it
turns out to actually own a sequence, and threads that fact through to
the table-dump pass so it skips re-creating the database and
re-dumping the sequences it already handled.

The pre-pass leaves --xml and the "mysql" system database to the
unchanged single-pass path: get_sequence_structure() isn't XML-aware,
and "mysql" never owns user sequences in practice but has a LOG_OUTPUT
save/restore that only closes in the table pass.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
Alessandro Vetere
MDEV-38056 Assertion 'bpage->state() >= buf_page_t::UNFIXED' in buf_page_get_zip()

Three callers reconstruct old versions of a clustered index record, derive
secondary index entries from them, and dereference the BLOB pointers of
externally stored columns: row_vers_impl_x_locked_low() for the implicit lock
check, row_undo_mod_sec_is_unsafe() for rollback, and row_check_index() for
CHECK TABLE ... EXTENDED. purge_sys.view is what keeps those pages allocated,
but purge_sys_t::view_guard froze it only for the duration of
trx_undo_prev_version_build(), and the dereference happens after. On
ROW_FORMAT=COMPRESSED this trips the assertion above; in a release build the
freed page is read anyway, which is silent corruption.

All three now hold purge_sys.latch across the dereference, and only where the
version has externally stored columns, since row_build() dereferences nothing
otherwise. In row_check_index() the freeze spans the whole comparison, which
fetches one field at a time and may evaluate a virtual column expression; for
the latest version it is also confined to a delete-marked record, the only
kind that need not own what it points at. Freezing that late means the view
may have advanced since the walk decided a version was reachable, so each
caller re-establishes that under the freeze; trx_undo_prev_version_build()
states the condition and why testing the oldest writer applied suffices.

The first two callers can treat that test as an invariant and end the walk
where it fails. row_check_index() cannot, because it decides reachability from
the lagging purge_sys.end_view on purpose, and that lag is how it finds orphan
secondary index records: where the test fails it stops and reports nothing
rather than treating the record as an orphan, and no report is lost for good,
end_view eventually reaching the same point. Its two purge_sys.is_purgeable()
tests now read the frozen view wherever a fetch follows, which makes them
atomic with the fetch they guard.

trx_undo_prev_version_build(): remove the gate that was meant to stop CHECK
TABLE ... EXTENDED from fetching BLOBs it may no longer own, and
view_guard::is_extended() with it, which no guard mode could satisfy. That
decision belongs to the caller, the only one that knows whether it will
dereference anything.

row_log_table_get_pk(): document why the online ALTER path may dereference
without a freeze.

Debug-only keywords. purge_hold_cleanup parks a purge batch between its last
purged record and purge_sys_t::batch_cleanup(), the window in which a reader
that goes by purge_sys.end_view can still reach history the batch has removed;
a batch opens and closes it without ever returning to the test.
purge_no_blob_freeze sends a version that does have externally stored columns
down the path one without any takes, which is what all four call sites did
before this change, and reproduces the assertion above.
row_vers_impl_x_locked_purgeable, row_undo_mod_sec_is_unsafe_purgeable and
row_check_index_purgeable force the re-validation to fail, reaching exits that
purge_sys.view advancing mid-walk otherwise produces. The first reports no
implicit lock for a row that a live transaction still holds, so a test may
only check that nothing breaks; the other two make the server more cautious.

Tests. old_blob and old_blob_updel cover the implicit lock check,
old_blob_rollback the rollback, old_blob_check CHECK TABLE ... EXTENDED. Each
parks a walk at a dereference, makes the BLOB freeable, and asserts that the
counter of purged update records, which is what would free it, stays at zero
while parked and advances once the walk is over. old_blob_updel covers an undo
log record that stores only the 20-byte reference and needs purge_hold_cleanup
to reach it; old_blob_rollback parks at a reference that the version merely
inherited. All four fail with the original assertion under
debug_dbug=+d,purge_no_blob_freeze, and skip above a 16k page size, which
ROW_FORMAT=COMPRESSED requires. old_blob_purgeable drives the three
re-validation exits, needs no synchronisation, and runs at every page size.