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
ParadoxV5
Merge branch '10.11' into px5.simulate_find_log_pos_error
Thirunarayanan Balathandayuthapani
MDEV-38412 System tablespace fails to shrink due to legacy tables

Problem:
=======
- InnoDB system tablespace fails to autoshrink when it contains
legacy internal tables. These are non-user tables and internal
table exist from older version. Because the current shrink logic
does recognize these entries as user table, they block the
defragmentation process required to reduce the tablespace size.

Solution:
=========
To enable successful shrinking, InnoDB has been updated to
identify and remove these legacy entries during the startup:

drop_all_orphaned_tables(): A new function that scans the InnoDB
system tables for entries lacking the / naming convention.
It triggers the removal of these table objects from InnoDB system
tables and ensures the purge thread subsequently drops any
associated index trees in SYS_INDEXES.

scan_system_tablespace_metadata(): Scan SYS_TABLES or SYS_INDEXES
and invoke callback for non-system entries in system tablespace.
This function scans either SYS_TABLES or SYS_INDEXES (based on the
table parameter) and invokes the provided callback for each non-system
table or index found in the system tablespace (SPACE=0).

dict_drop_table_metadata(): Function is to remove specific
table IDs from internal system tables.

fsp_system_tablespace_truncate(): If legacy tables are detected,
InnoDB prioritizes their removal. To ensure data integrity and
complete the shrink, a two-restart sequence may be required:
1) purge the legacy table
2) Defragment the system tablespace and shrink the
system tablespace further

Thanks Marko Mäkelä for the contribution of your patch in
drop_orphaned_tables()
Thirunarayanan Balathandayuthapani
MDEV-39261 MariaDB crash on startup in presence of indexed virtual columns

Problem:
========
A single InnoDB purge worker thread can process undo logs from different
tables within the same batch. But get_purge_table(), open_purge_table()
incorrectly assumes that a 1:1 relationship between a purge worker thread
and a table within a single batch. Based on this wrong assumtion,
InnoDB attempts to reuse TABLE objects cached in thd->open_tables for
virtual column computation.

1) Purge worker opens Table A and caches the TABLE pointer in thd->open_tables.
2) Same purge worker moves to Table B in the same batch, get_purge_table()
retrieves the cached pointer for Table A instead of opening Table B.
3) Because innobase::open() is ignored for Table B, the virtual column
template is never initialized.
4) virtual column computation for Table B aborts the server

Solution:
========
- Introduced purge_table class which has the following
purge_table: Stores either TABLE* (for tables with indexed virtual
columns) or MDL_ticket* (for tables without) in a single union
using LSB as a flag.
For tables with indexed virtual columns: opens TABLE*, accesses
MDL_ticket* via TABLE->mdl_ticket
For tables without indexed virtual columns: stores only MDL_ticket*.

trx_purge_attach_undo_recs(): Coordinator opens both dict_table_t*
and TABLE* with proper MDL protection. Workers access cached
table pointers from purge_node_t->tables without opening
their own handles

purge_sys.coordinator_thd: Distinguish coordinator from workers
in cleanup logic. Skip innobase_reset_background_thd() for
coordinator thread to prevent premature table closure during
batch processing. Workers still call cleanup to release their
thread-local resources

trx_purge_close_tables():
Rewrite for purge coordinator thread
1) Close all dict_table_t* objects first
2) Call close_thread_tables() once for all TABLE* objects
3) Release MDL tickets last, after tables are closed

Added table->lock_mutex protection when reading (or) writing
vc_templ->mysql_table and mysql_table_query_id. Clear cached
TABLE* pointers before closing tables to prevent stale pointer
access

Declared open_purge_table() and close_thread_tables() in trx0purge.cc
Declared reset_thd() in row0purge.cc and dict0stats_bg.cc.
Removed innobase_reset_background_thd()
Alexey Botchkov
MDEV-15479 Empty string is erroneously allowed as a GEOMETRY column value.

Empty string disallowed.
ParadoxV5
MDEV-38600: Annotate the binlogging of recreating MEMORY tables

The data in MEMORY tables is temporary and is lost when the server
restarts. Thus, it is well-intentioned to record TRUNCATE statements
to the binary log when these tables are rediscovered empty. However,
as entries with no explicit user query associated (especially the lack
of SHUTDOWN on crashes), those unaware of this mechanism can find them
unexpected, not to mention their significance downstream in replication.

This commit adds a comment to these automatically generated
TRUNCATE entries to briefly self-describe their source and purpose.
As a part of the generated query, this comment is visible together
with the TRUNCATE itself in SHOW BINLOG EVENTS and `mariadb-binlog`,
while maintaining seamlessness in replication.

There are no other changes in behaviour or storage engine API.

Reviewed-by: Andrei Elkin <[email protected]>
Vladislav Vaintroub
new HeidiSQL 12.17

Fix HeidiSQL download URL

HeidiSQL is now released on github, fix the portable ZIP URL to point
to new download location

HeidiSQL - prevent stale download by providing expected hash
Varun Deep Saini
MDEV-39013: Fixed flaky main.tmp_space_usage

A concurrent processlist read observed tmp_space_used before the preceding statement had finished cleanup, because SELECT results reached the client before statement cleanup completed.

Used --ping before switching connections and reading information_schema.processlist.
ParadoxV5
MDEV-38600: Warn when recreating MEMORY tables on read-only slaves

The data in MEMORY tables is temporary and is lost when the server
restarts. Thus, when these tables are rediscovered empty,
it’s well-intentioned to record TRUNCATE statements to
the binary log, complete with an increment to the `@@gtid_binlog_pos`.
However, those unaware of this mechanism may not expect this increment
and its sign of replication divergence, namely in `@@gtid_strict_mode`.

This commit adds a binary log warning
when such a table is found `implicit_emptied`.

Since general uses of memory tables may already expect this effect,
to avoid unnecessary verbosity, this warning only emits from
`@@read_only` servers with CHANGE MASTER configured. `@@read_only`
indicates that the server should not receive changes; for a slave,
it means it only expects replication to binlog changes with GTID.

Reviewed-by: Brandon Nesterenko <[email protected]>
Rucha Deodhar
MDEV-39212: JSON_MERGE_PATCH depth crash

Analysis:
The crash happens because we run out of stack space

Fix:
Add a stack overflow check.
Rex Johnston
MENT-2483 Degrading performance with CTE query with spatial index

Enabling derived keys optimization for derived.col = const pushed
conditions.

Estimating records per key in derived key for the optimizer
based on form and/or size of components of a derived table.

Consider a derived table of the form

SELECT ..., ROW_NUMBER ()  OVER (PARTITION BY c1,c2 order by ...)
FROM t1, t2, t3 ...
WHERE ...

If the optimizer generates a key on this derived table because of
a constraint being pushed into it, it currently will not consider key
components of the form  col = const

We lift this constraint and add code to TABLE::add_tmp_key to search
for a window function ROW_NUMBER().  From the partition list c1, c2 we
can in infer an estimate of the number of rows we expect to see for
each key value.  The optimizer can then use this number to determine
a better table join order.
Geng Tian
Fix bug where master_ssl_verify_server_cert value is not set correctly on replica

In the major release of MariaDB 12.3.1, MariaDB this change to
refactor ssl_verify_server_cert to master_ssl_verify_server_cert in
commit in 89bd6b00.

However, these values are different types. While ssl_verify_server_cert
is my_bool
type, the master_ssl_verify_server_cert is trilean type which accepts
three possible values (Yes/No/Default). When reading the value of the
argument using !*(my_bool*)arg in mysql_options, trilean type value
can't be retrieved because it accesses the wrong memory address by just
passing the master_ssl_verify_server_cert, causing the
master_ssl_verify_server_cert still behaves as "ON" when it's set to
"OFF".

This commit changes the implementation to
`master_ssl_verify_server_cert.value` retrieve the correct value.

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.

Reviewed-by: Jimmy Hú <[email protected]>
Reviewed-by: Georgi Kodinov <[email protected]>
Reviewed-by: Brandon Nesterenko <[email protected]>
Aleksey Midenkov
MDEV-27569 Valgrind/MSAN errors in ha_partition::swap_blobs

row_sel_store_mysql_field() does:

3113                    mysql_rec[templ->mysql_null_byte_offset]
3114                            &= static_cast<byte>(~templ->mysql_null_bit_mask);

but mysql_rec[] which is prefetch buffer was allocated without
initialization. Prefetch buffers are allocated by
row_sel_prefetch_cache_init():

3881            ptr = static_cast<byte*>(ut_malloc_nokey(sz));

and then it initializes the buffers with the magic numbers.

The fix initializes the buffers with null bytes as well for nullable
fields.
Thirunarayanan Balathandayuthapani
MDEV-38412 System tablespace fails to shrink due to legacy tables

Problem:
=======
- InnoDB system tablespace fails to autoshrink when it contains
legacy internal tables. These are non-user tables and internal
table exist from older version. Because the current shrink logic
does recognize these entries as user table, they block the
defragmentation process required to reduce the tablespace size.

Solution:
=========
To enable successful shrinking, InnoDB has been updated to
identify and remove these legacy entries during the startup:

drop_all_orphaned_tables(): A new function that scans the InnoDB
system tables for entries lacking the / naming convention.
It triggers the removal of these table objects from InnoDB system
tables and ensures the purge thread subsequently drops any
associated index trees in SYS_INDEXES.

scan_system_tablespace_metadata(): Scan SYS_TABLES or SYS_INDEXES
and invoke callback for non-system entries in system tablespace.
This function scans either SYS_TABLES or SYS_INDEXES (based on the
table parameter) and invokes the provided callback for each non-system
table or index found in the system tablespace (SPACE=0).

dict_drop_table_metadata(): Function is to remove specific
table IDs from internal system tables.

fsp_system_tablespace_truncate(): If legacy tables are detected,
InnoDB prioritizes their removal. To ensure data integrity and
complete the shrink, a two-restart sequence may be required:
1) purge the legacy table
2) Defragment the system tablespace and shrink the
system tablespace further
Alexey Botchkov
MDEV-39124 XMLTYPE: allow only well-formed XML.

Necessary checks added to the XMLTYPE.
OmarGamal10
MDEV-7270 cannot slave_skip_errors for 1677

Setting slave_skip_errors to 1677 (ER_SLAVE_CONVERSION_FAILED) doesn't work
as intended. The slave aborts replication on column mismatch. This fix
makes it log a warning and set the problematic field to the default
value gracefully.
Reviewed-by: Brandon Nesterenko <[email protected]>
Rex Johnston
MENT-2483 Degrading performance with CTE query with spatial index

Enabling derived keys optimization for derived.col = const pushed
conditions.

Estimating records per key in derived key for the optimizer
based on form and/or size of components of a derived table.

Consider a derived table of the form

SELECT ..., ROW_NUMBER ()  OVER (PARTITION BY c1,c2 order by ...)
FROM t1, t2, t3 ...
WHERE ...

If the optimizer generates a key on this derived table because of
a constraint being pushed into it, it currently will not consider key
components of the form  col = const

We lift this constraint and add code to TABLE::add_tmp_key to search
for a window function ROW_NUMBER().  From the partition list c1, c2 we
can in infer an estimate of the number of rows we expect to see for
each key value.  The optimizer can then use this number to determine
a better table join order.
Marko Mäkelä
Revert "Create the spare archive a second after checkpoint"

This reverts commit 4c3af6ae5e648c64c724b11d55b16df92dd095c6.
Thirunarayanan Balathandayuthapani
MDEV-39261 MariaDB crash on startup in presence of indexed virtual columns

Problem:
========
Purge threads computing virtual columns could crash due to:
1. Stale TABLE* pointers when tables are flushed/rebuilt during purge
2. open_purge_table() called close_thread_tables() on failure, making
MDL tickets invalid before purge could release them
3. Purge coordinator opened TABLE* but workers accessed it with wrong
TABLE->in_use
4. No retry mechanism when open_purge_table() failed due to concurrent
FLUSH TABLES, BACKUP STAGE, or ALTER TABLE operations

Solution:
========
1. Removed close_thread_tables() from open_purge_table(). Purge
coordinator thread should close explicitly in close_and_reopen()

2. Added retry logic: when open_purge_table() returns NULL due to
table flush/rebuild, set must_wait() flag and retry in
close_and_reopen()

3. Update close_and_reopen() with purge_table parameter to
close the failed table. Pass it to trx_purge_close_tables()
for proper cleanup

4. Properly set and reset TABLE::in_use during purge operations:
- Set to coordinator_thd in row_purge_parse_undo_rec() when opening
- Reset in trx_purge_close_table() when closing

5. The auto_increment initialization now happens unconditionally for
purge threads , ensuring the auto_increment counter is always
properly initialized when purge opens tables with virtual columns
Rex Johnston
MENT-2483 Degrading performance with CTE query with spatial index

Enabling derived keys optimization for derived.col = const pushed
conditions.

Estimating records per key in derived key for the optimizer
based on form and/or size of components of a derived table.

Consider a derived table of the form

SELECT ..., ROW_NUMBER ()  OVER (PARTITION BY c1,c2 order by ...)
FROM t1, t2, t3 ...
WHERE ...

If the optimizer generates a key on this derived table because of
a constraint being pushed into it, it currently will not consider key
components of the form  col = const

We lift this constraint and add code to TABLE::add_tmp_key to search
for a window function ROW_NUMBER().  From the partition list c1, c2 we
can in infer an estimate of the number of rows we expect to see for
each key value.  The optimizer can then use this number to determine
a better table join order.
Rucha Deodhar
MDEV-39179: Incorrect NULL handling in UPDATE ... RETURNING result

Analysis:
OLD_VALUE() swapped only field->ptr, leaving null_ptr pointing to the
current record. This caused incorrect NULL results.

Fix:
Store null_ptr_old for record[1] and swap it together with ptr to
preserve correct NULL semantics.
Daniel Black
MDEV-38817: innodb.skip_locked_nowait fails: SELECT NOWAIT gets ER_LOCK_WAIT_TIMEOUT

MDEV-38019 added an optimization in select_send::send_eof() that
sends the OK packet to the client before the server finishes cleanup,
allowing the client to process results sooner. The guard
!thd->transaction->stmt.is_trx_read_write() was intended to exclude
write transactions, but mark_trx_read_write() is only called for DML
(INSERT/UPDATE/DELETE), not for locking reads.

This caused SELECT ... FOR UPDATE with autocommit to send OK before
external_lock(F_UNLCK) committed and released locks, creating a race
where another connection using NOWAIT could see still-held locks and
immediately fail with ER_LOCK_WAIT_TIMEOUT.

We fix this in the case case by inserting --ping, that ensures the
cleanup on the same server thread occurs completing the
external_lock(F_UNLCK).

Thanks Arcadiy Ivanov for the analysis that formed the majority of
this commit message.
ParadoxV5
Fix fault injection `simulate_find_log_pos_error`

`DBUG_EXECUTE_IF` is a macro that uses
the infamous `do {…} while(0)` “idiom”.
This detail causes the `break` in the code block to terminate the
`while(0)` behind the macro instead of the `for (;;)` outside.
Consequently, this fault simulation does not terminate the normal flow,
which in turn overwrites the simulated fault with a non-fault outcome.

Since this fault simulation is the first step of the loop,
this commit fixes the fault injection by moving it before the loop.
Thirunarayanan Balathandayuthapani
MDEV-39261 MariaDB crash on startup in presence of indexed virtual columns

Problem:
========
A single InnoDB purge worker thread can process undo logs from different
tables within the same batch. But get_purge_table(), open_purge_table()
incorrectly assumes that a 1:1 relationship between a purge worker thread
and a table within a single batch. Based on this wrong assumtion,
InnoDB attempts to reuse TABLE objects cached in thd->open_tables for
virtual column computation.

1) Purge worker opens Table A and caches the TABLE pointer in thd->open_tables.
2) Same purge worker moves to Table B in the same batch, get_purge_table()
retrieves the cached pointer for Table A instead of opening Table B.
3) Because innobase::open() is ignored for Table B, the virtual column
template is never initialized.
4) virtual column computation for Table B aborts the server

Solution:
========
- Introduced purge_table class which has the following
purge_table: Stores either TABLE* (for tables with indexed virtual
columns) or MDL_ticket* (for tables without) in a single union
using LSB as a flag.
For tables with indexed virtual columns: opens TABLE*, accesses
MDL_ticket* via TABLE->mdl_ticket
For tables without indexed virtual columns: stores only MDL_ticket*.

trx_purge_attach_undo_recs(): Coordinator opens both dict_table_t*
and TABLE* with proper MDL protection. Workers access cached
table pointers from purge_node_t->tables without opening
their own handles

purge_sys.coordinator_thd: Distinguish coordinator from workers
in cleanup logic. Skip innobase_reset_background_thd() for
coordinator thread to prevent premature table closure during
batch processing. Workers still call cleanup to release their
thread-local resources

trx_purge_close_tables():
Rewrite for purge coordinator thread
1) Close all dict_table_t* objects first
2) Call close_thread_tables() once for all TABLE* objects
3) Release MDL tickets last, after tables are closed

Added table->lock_mutex protection when reading (or) writing
vc_templ->mysql_table and mysql_table_query_id. Clear cached
TABLE* pointers before closing tables to prevent stale pointer
access

Declared open_purge_table() and close_thread_tables() in trx0purge.cc
Declared reset_thd() in row0purge.cc and dict0stats_bg.cc.
Removed innobase_reset_background_thd()
Rucha Deodhar
MDEV-39127: UBSAN : downcast of address X which does not point to an object
of type 'multi_update' in sql/sql_update.cc
| Sql_cmd_update::update_single_table

Analysis:
the 'result' object was being incorrectly used which maybe of the type
multi_update.This caused UBSAN error due to an invalid downcast in
Sql_cmd_update::update_single_table().

Fix:
Introduce a dedicated returning_result object for handling RETURNING output
instead of reusing result. This ensures the correct result handler is used
and avoids unsafe casts.
Alexey Botchkov
MDEV-39124 XMLTYPE: allow only well-formed XML.

Necessary checks added to the XMLTYPE.
Gabriele Bocchi
MDEV-39262: galera_new_cluster.sh ignores service name

due to argument due to hardcoded mariadb.service.

Fixes: 649216e70d87c84b6c78e4cfb26c0afc96d5192e
Rucha Deodhar
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.
Tarun Wadhwa
MDEV-29804, MDEV-32447 Fix binlog session variable handling

MDEV-29804: Query_log_event::pack_info() was displaying inverted values
for foreign_key_checks, check_constraint_checks and unique_checks flags
in SHOW BINLOG EVENTS.
MDEV-32447: check_constraint_checks was not included in
OPTIONS_WRITTEN_TO_BINLOG, causing replication to break when
check_constraint_checks=OFF was used in non-ROW binlog formats.

Reviewed-by: Brandon Nesterenko <[email protected]>
Reviewed-by: Georgi Kodinov <[email protected]>
Rucha Deodhar
MDEV-39119: Improve error handling when using OLD_VALUE as alias name

Analysis:
Since OLD_VALUE_SYM was part of reserved keywords, it did not allow
old_value in the alias.
Fix:
Change OLD_VALUE_SYM from reserved keyword to keyword_sp_var_and_label.
Mahmoud Khaled
MDEV-38202: Make init_rpl_role visible at runtime

Problem:
The --init-rpl-role option can be set in the .cnf file or command
line to configure the server replication role at startup (MASTER or
SLAVE), but there was no way to check this value at runtime. This
made it hard to investigate issues because we could not know which
role the server was started with.

Solution:
I added a new read-only system variable init_rpl_role that is set
after startup and kept unchanged.

Example usage:
* SHOW GLOBAL VARIABLES LIKE 'init_rpl_role'
* SELECT @@GLOBAL.init_rpl_role

Reviewed-by: ParadoxV5 <[email protected]>
Reviewed-by: Georgi (Joro) Kodinov <[email protected]>
Marko Mäkelä
MDEV-39162: Use the common log_close() write-ahead logic
Brandon Nesterenko
MDEV-39442: rpl.rpl_extra_col_slave_rebinlog Fails on Buildbot

rpl_extra_col_slave_rebinlog could fail with a SELECT statement
returning empty results on a slave when it should return a row.
The test uses chain replication between the servers, and tried to
synchronized all servers together after a transaction using the
pattern

--connection server_1
trx;
--source include/save_master_gtid.inc

--connection server_3
--source include/sync_with_master_gtid.inc

The problem is that server_2 can be in a state where trx is written in
the binary log but not yet committed (i.e. not visible to other
threads). However, because the data was written into the binlog,
server_2's binlog dump thread can send it to server_3, and server_3 can
execute it and finalize the sync_with_master_gtid.inc; however, server_2
can still not have committed the transaction. This can be reproduced
with the following patch:

```
diff --git a/mysql-test/suite/rpl/t/rpl_extra_col_slave_rebinlog.test b/mysql-test/suite/rpl/t/rpl_extra_col_slave_rebinlog.test
index 7d1e71c4a76..fe130602e20 100644
--- a/mysql-test/suite/rpl/t/rpl_extra_col_slave_rebinlog.test
+++ b/mysql-test/suite/rpl/t/rpl_extra_col_slave_rebinlog.test
@@ -28,6 +28,11 @@ set statement sql_log_bin=0 for alter table t1 add column b int default 5 after
--connection server_3
set statement sql_log_bin=0 for alter table t1 add column b int default 10 after a;

+--connection server_2
+--source include/stop_slave.inc
+set @@global.debug_dbug= "+d,dbug_wait_after_binlogged_before_engine_commit";
+--source include/start_slave.inc
+
--connection server_1
insert into t1 values (1);
--source include/save_master_gtid.inc
diff --git a/sql/log.cc b/sql/log.cc
index 8e2e37a83fc..73a159f3158 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -11087,6 +11087,8 @@ void MYSQL_BIN_LOG::trx_group_commit_with_engines(group_commit_entry *leader,
    DBUG_VOID_RETURN;
  }

+  DBUG_EXECUTE_IF("dbug_wait_after_binlogged", { my_sleep(500000); });
+
  /*
    Wakeup each participant waiting for our group commit, first calling the
    commit_ordered() methods for any transactions doing 2-phase commit.
```

The fix is to run sync_with_master_gtid.inc on server_2 (and more
generally, this should be done on every intermediary server when chain
replication is used).

Signed-off-by: Brandon Nesterenko <[email protected]>
kangrong
MDEV-39390 videx: free libcurl resources in ask_from_videx_http()

LeakSanitizer reports a leak in the VIDEX HTTP path on shutdown.

The problem is that several error/success return paths after
curl_easy_init() bypass libcurl cleanup, so the curl handle and
request headers are not released.

Fix it by routing those exits through a shared cleanup label and
calling:
- curl_slist_free_all(headers)
- curl_easy_cleanup(curl)

Bump VIDEX plugin version to 0.2

Test videx.create-table-and-index updated to demonstrate ASAN
leak failure. A working videx server isn't required for the
test to leak.

Reviewed by: Daniel Black
Alexey Botchkov
MDEV-39124 XMLTYPE: allow only well-formed XML.

Necessary checks added to the XMLTYPE.
Thirunarayanan Balathandayuthapani
MDEV-38412 System tablespace fails to shrink due to legacy tables

Problem:
=======
- InnoDB system tablespace fails to autoshrink when it contains
legacy internal tables. These are non-user tables and internal
table exist from older version. Because the current shrink logic
does recognize these entries as user table, they block the
defragmentation process required to reduce the tablespace size.

Solution:
=========
To enable successful shrinking, InnoDB has been updated to
identify and remove these legacy entries during the startup:

drop_all_orphaned_tables(): A new function that scans the InnoDB
system tables for entries lacking the / naming convention.
It triggers the removal of these table objects from InnoDB system
tables and ensures the purge thread subsequently drops any
associated index trees in SYS_INDEXES.

scan_system_tablespace_metadata(): Scan SYS_TABLES or SYS_INDEXES
and invoke callback for non-system entries in system tablespace.
This function scans either SYS_TABLES or SYS_INDEXES (based on the
table parameter) and invokes the provided callback for each non-system
table or index found in the system tablespace (SPACE=0).

dict_drop_table_metadata(): Function is to remove specific
table IDs from internal system tables.

fsp_system_tablespace_truncate(): If legacy tables are detected,
InnoDB prioritizes their removal. To ensure data integrity and
complete the shrink, a two-restart sequence may be required:
1) purge the legacy table
2) Defragment the system tablespace and shrink the
system tablespace further

Thanks Marko Mäkelä for the contribution of your patch in
drop_orphaned_tables()
Dave Gosselin
MDEV-39014: Factor JOIN_TAB_RANGE allocation into static create()

Adds a static JOIN_TAB_RANGE::create(thd, count) helper that allocates
a JOIN_TAB array and wraps it in a JOIN_TAB_RANGE, replacing the
inline allocation in JOIN::get_best_combination().  Also gives
JOIN_TAB_RANGE::start and ::end default initializers and documents
their half-open range convention.
Thirunarayanan Balathandayuthapani
MDEV-39261 MariaDB crash on startup in presence of indexed virtual columns

Problem:
========
Purge threads computing virtual columns could crash due to:
1. Stale TABLE* pointers when tables are flushed/rebuilt during purge
2. open_purge_table() called close_thread_tables() on failure, making
MDL tickets invalid before purge could release them
3. Purge coordinator opened TABLE* but workers accessed it with wrong
TABLE->in_use
4. No retry mechanism when open_purge_table() failed due to concurrent
FLUSH TABLES, BACKUP STAGE, or ALTER TABLE operations

Solution:
========
1. Removed close_thread_tables() from open_purge_table(). Purge
coordinator thread should close explicitly in close_and_reopen()

2. Added retry logic: when open_purge_table() returns NULL due to
table flush/rebuild, set must_wait() flag and retry in
close_and_reopen()

3. Update close_and_reopen() with purge_table parameter to
close the failed table. Pass it to trx_purge_close_tables()
for proper cleanup

4. Properly set and reset TABLE::in_use during purge operations:
- Set to coordinator_thd in row_purge_parse_undo_rec() when opening
- Reset in trx_purge_close_table() when closing

5. The auto_increment initialization now happens unconditionally for
purge threads , ensuring the auto_increment counter is always
properly initialized when purge opens tables with virtual columns
Andrzej Jarzabek
MDEV-39122 Fix my_realpath to treat empty string as current directory

my_realpath() uses my_load_path() as a fallback. my_load_path()
replaces empty string with a current directory. But my_realpath()
didn't do it itself so the result was inconsistent: empty string was
replaced with a current directory, but if the current directory was
symlinked, symlinks were not resolved (as they were for any other,
non-empty, path, including ".").

Fix my_realpath() to treat empty string consisently with all
other paths - replace with a current dir and resolve symlinks too.