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
Oleksandr Byelkin
Merge branch 'bb-12.3-release' into bb-13.1-release
Sergei Golubchik
MDEV-42025 Unauthenticated handshake converts an unbounded CLIENT_CONNECT_WITH_DB database name

cut the database name to SAFE_NAME_LEN+1 characters before converting
it, a longer name is invalid anyway and stays invalid after the cut.

Assisted-by: Claude:claude-opus-5-5
Oleksandr Byelkin
Merge branch 'bb-11.8-release' into bb-12.3-release
Oleksandr Byelkin
Merge branch 'bb-11.4-release' into bb-11.8-release
Rex Johnston
MDEV-39492 PQ: leave a condition the workers cannot evaluate to the manager

A conjunct of a table's condition that no worker can evaluate kept the
whole query serial. The common one is a correlated subquery: its JOIN
belongs to the manager's thread, so there is no clone of it to hand a
worker, and TPC-H Q21's NOT EXISTS over LINEITEM was enough to refuse a
plan whose driving table the optimizer had already costed as a parallel
scan.

The gate now divides each table's condition instead of refusing it
(pwt_split_table_cond). The conjuncts a worker can evaluate stay with the
table, as the worker's select_cond, and the rest are ANDed into
JOIN::parallel_residual_cond for the manager to apply to every row it
drains, after copy_back_row() has put the shipped columns back into the
manager's own records, where the residual's items already look. A
correlated subquery among them runs on the manager's thread through the
manager's own handlers exactly as it would have run serially. A conjunct
of an inner join may be applied anywhere after its tables have been
read, so the answer is the same; what changes is the number of rows it
is asked of, which is the finished join's rather than this table's.

For the residual to be answerable from a drained row, every field it
reads from a join table has to be a shipped column, which
pwt_row_layout::build() takes from the read_set. The split checks that,
walking into subqueries for their outer references, and refuses the plan
if a conjunct can be evaluated on neither side. The split is taken by
the gate and taken again by init_parallel_workers() from the plan as it
stands when the workers are built (pwt_split_plan_conditions), because it
names the plan's own items.

A plan with a residual ships joined rows rather than pre-aggregating:
the filter has to run before any grouping, so pwt_row_layout::build()
takes a ship_rows argument that keeps 'grouped' off while
'plan_aggregates' stays on, which is the fall-back shape the drain
already handles, with the plan's own terminal grouping what the manager
lets through. The non-aggregating drain applies the residual before
sending a row, and before collecting it when the sort is the manager's.
The optimizer trace records the manager's share under
parallel_scan_manager_evaluates.

On TPC-H SF1 Q21 the serial plan evaluates the NOT EXISTS once per late
LINEITEM row of a finished order, 1.8M times, and the manager once per
row of the finished join, 77k times, since the NATION filter has run by
then. With a FirstMatch semijoin admitted to the workers in the next
commit, Q21 goes from 2.9 s serially to 0.85 s with four workers and
0.68 s with eight, with the same result.

main.parallel_query_residual pins the four shapes: whole-table
aggregation, GROUP BY, a plain select, and a select whose sort the
manager performs, each with a correlated subquery in the WHERE clause,
each run in the workers and each giving the serial answer.

This commit was prepared with Claude Code (Fable 5.1), which diagnosed
the refusal from the optimizer trace, measured that applying the
subqueries after the join was cheaper even serially, designed and wrote
the split, the layout change and the drain-side filter, and wrote the
test.
Marko Mäkelä
MDEV-42035: Recovery hangs due corrupted system or undo tablespace

The function recv_sys_t::recover() that was introduced
in commit 850d61736deba354377634cf344256ee850b93b7 (MDEV-32042)
will cause an infinite loop in case the requested page is corrupted.
The reason is that the code path would hold an extra buffer-fix on
the block, which buf_pool_t::corrupted_evict() would wait to be
released, in vain.

Let us avoid the extra buffer-fix and add stricter assertions
that must hold during the recovery phase, when regular access
to the buffer pool via buf_page_get_gen() and friends is blocked.
bsrikanth-mariadb
MDEV-41293: FederatedX: connection state after a net_read_timeout

Problem:
When reading the reply of the remote server times out, the client
library compiled into the server returns without closing the connection
and without setting a client error. FederatedX took the raw
ER_NET_READ_INTERRUPTED for an error of the remote server and went on
using a connection that still had the reply of the failed statement to
arrive. As a result:
* the next statement on that connection failed in various ways, either
  with ER_QUERY_ON_FOREIGN_DATA_SOURCE ("Server has gone away") or with
  an error packet that mysqltest took for a malformed packet;
* inside a transaction, the following statements continued on a new
  remote session in autocommit mode, so they were committed on the
  remote server one by one even though the local transaction was later
  rolled back. The savepoints of the lost session were also still
  remembered by FederatedX.
The same happened when the connection was lost while reading the reply.

Fix:
* After a timeout FederatedX closes the connection, so that the next
  statement opens a new one. The client still gets the error of the
  timeout, ER_NET_READ_INTERRUPTED.
* Whenever the connection is gone after a failed statement, timeout or
  not, the state of the lost session (autocommit mode, savepoints) is
  forgotten and the local transaction is marked to be rolled back, so a
  new connection starts the transaction again. This includes the case
  where the connection is lost while SET AUTOCOMMIT=0 is sent for the
  first statement of the transaction. The closed connection is also
  freed, which was leaked before.
* Errors of the client library are reported as
  ER_QUERY_ON_FOREIGN_DATA_SOURCE by ha_federatedx::info() as well, the
  same way as by the pushed down multi-table UPDATE/DELETE.
* The error state of ha_federatedx, read by info(), is initialized.
* A non-debug build checks the socket for EOF before it sends a command
  (net_clear()). If the remote server has already closed the connection, the
  write fails without the network layer raising an error, and the client
  would get ER_GET_ERRMSG ("Got error 10000 ...") intermittently. When the
  connection is lost and no error has been raised, raise
  ER_QUERY_ON_FOREIGN_DATA_SOURCE with the error of the client library. The
  COMMIT and ROLLBACK of the transaction still return their error to the
  caller.

Test: federatedx_pushdown_upd_del covers the timeout of a pushed down
multi-table UPDATE and DELETE and of reading a result, the statements
after it, the same inside a transaction, a connection killed in the
middle of a statement, a connection lost while SET AUTOCOMMIT=0 is sent
(also followed by a disconnect and a transaction in another session),
client library errors in info(), and that an error of the remote server
which merely has the code of ER_NET_READ_INTERRUPTED is not taken for a
timeout.
The two statements after the idle connection was killed accept
ER_NET_READ_ERROR (reported by the network layer in a debug build) or
ER_QUERY_ON_FOREIGN_DATA_SOURCE (non-debug build).
Pekka Lampio
MDEV-38999 followup 2: autocommit flag leak, UNION locks, error-reset race

Further review of the previous followup found three more defects.

1. wsrep_trx_locking_read_done was only reset at transaction boundaries
  (trans_begin/trans_commit[_implicit]/trans_rollback[_implicit]), never
  on the statement-commit path (trans_commit_stmt/trans_rollback_stmt).
  A plain autocommit SELECT ... FOR UPDATE sets the flag while it
  executes; its own implicit per-statement transaction then ends (and
  releases the lock) via trans_commit_stmt(), which left the flag stuck
  at true. Every later, unrelated statement on that connection would
  then have wsrep_must_sync_wait() skip its causal wait indefinitely,
  until an explicit BEGIN/COMMIT/ROLLBACK/START TRANSACTION happened to
  reset it - reintroducing the stale-read bug this patch set exists to
  fix. Fixed by resetting the flag in trans_commit_stmt()/
  trans_rollback_stmt() too, guarded by the same
  !thd->in_active_multi_stmt_transaction() condition those functions
  already use to decide a real commit/rollback (and lock release) just
  happened, rather than a savepoint within an explicit transaction.

2. The locking-read detector in wsrep_sync_wait() only inspected
  thd->lex->first_select_lex()->select_lock, but a UNION's trailing
  FOR UPDATE/LOCK IN SHARE MODE is attached by the parser only to the
  unit's *last* SELECT_LEX (see
  SELECT_LEX_UNIT::set_lock_to_the_last_select()), not the first. A
  statement like "SELECT ... UNION SELECT ... FOR UPDATE" could
  therefore take a row lock without wsrep_trx_locking_read_done ever
  being set, reintroducing the self-deadlock risk this flag exists to
  close. Fixed by walking to the unit's last SELECT_LEX, the same way
  the parser itself does when attaching the lock.

3. wsrep_sync_wait() called thd->wsrep_cs().reset_error() after a
  causal-wait timeout without holding client_state's mutex (which is
  thd->LOCK_thd_data - see m_wsrep_mutex(&LOCK_thd_data) in THD's
  constructor), racing a concurrent BF-abort: wsrep::transaction::
  bf_abort() only ever mutates current_error() while holding that same
  mutex. If a genuine BF-abort/deadlock landed right as our own
  pre-check wait timed out, the unlocked reset_error() could silently
  overwrite that real error with success. Fixed by reading and
  conditionally clearing current_error() under LOCK_thd_data, and only
  clearing it when it is still the pre-check failure sync_wait() itself
  can produce (e_timeout_error/e_not_supported_error) - a genuine,
  racing error is left untouched and keeps its correct sticky-until-
  rollback behaviour.

Tests: galera_MDEV-38999_autocommit_fu.test exercises defect 1 - an
autocommit FOR UPDATE followed by an unrelated autocommit SELECT that
must still wait and time out. galera_MDEV-38999_union_fu.test exercises
defect 2 - a UNION ... FOR UPDATE inside an explicit transaction,
followed by a later read that must not re-wait; reverting the fix makes
this test fail with ER_LOCK_WAIT_TIMEOUT, confirming it actually
exercises the gap. Defect 3 has no dedicated test, as it depends on
winning a race with the BF-abort path that existing tests don't
control; it was found and fixed by inspection and matches the
locking contract wsrep-lib's own bf_abort() already follows.

Assisted-by Claude AI
Oleksandr Byelkin
Merge branch 'bb-10.11-release' into bb-11.4-release
Oleksandr Byelkin
MDEV-41258 Crash in Item_func_nextval on prepared re-execution

Sequence prelocking entries were matched across re-executions by
db.str/table_name.str pointer identity, aliasing memory on the TABLE's
own mem_root. Once the owning table was closed and reopened, those
pointers went stale, leaving a dangling duplicate entry that still got
opened and crashed.
Fix: match entries by owning TABLE_LIST and position, deep-copied onto
the statement's own arena.

The relink was gated by has_prelocking_list, which stays true forever
once a trigger is involved, so it silently stopped running after the
first execution for such statements.
Fix: moved it into its own function, called unconditionally per table,
keeping the original gating, scoped to DML statements only.

A stale entry's linked_table pointer could survive its owner's open
being skipped, or a mid-statement open_tables() backoff
(close_tables_for_reopen()), leaving open_table()'s backlink write to
land on freed memory.
Fix: clear it in TABLE_LIST::reinit_before_use() and in
close_tables_for_reopen().

set_parameters() overwrote lex->default_used from each execution's own
bound parameters only, losing a literal DEFAULT written in the
statement text itself.
Fix: also record default_used at prepare time and OR it in.

A mid-execute_loop() reprepare() swaps in a freshly re-parsed lex,
losing "EXECUTE ... USING DEFAULT" already folded into default_used by
set_parameters() for this execution.
Fix: save that bit before reprepare() and OR it back in afterwards.

Assisted-by: Claude:claude-opus-5-5
Oleksandr Byelkin
Merge branch 'bb-10.11-release' into bb-11.4-release
Alexey Yurchenko
MDEV-35940, MDEV-35964 reenable MTR tests

As MDEV-35940, MDEV-35964 have been fixed, reenable tests disabled
because of them
Oleksandr Byelkin
Merge branch '10.11' into 11.4
Oleksandr Byelkin
Merge branch 'bb-11.8-release' into bb-12.3-release
Sergei Petrunia
Merge: MDEV-39226: Push whole multi-table update/delete down into engines
Oleksandr Byelkin
MDEV-41258 Crash in Item_func_nextval on prepared re-execution

Sequence prelocking entries were matched across re-executions by
db.str/table_name.str pointer identity, aliasing memory on the TABLE's
own mem_root. Once the owning table was closed and reopened, those
pointers went stale, leaving a dangling duplicate entry that still got
opened and crashed.
Fix: match entries by owning TABLE_LIST and position, deep-copied onto
the statement's own arena.

The relink was gated by has_prelocking_list, which stays true forever
once a trigger is involved, so it silently stopped running after the
first execution for such statements.
Fix: moved it into its own function, called unconditionally per table,
keeping the original gating, scoped to DML statements only.

A stale entry's linked_table pointer could survive its owner's open
being skipped, or a mid-statement open_tables() backoff
(close_tables_for_reopen()), leaving open_table()'s backlink write to
land on freed memory.
Fix: clear it in TABLE_LIST::reinit_before_use() and in
close_tables_for_reopen().

set_parameters() overwrote lex->default_used from each execution's own
bound parameters only, losing a literal DEFAULT written in the
statement text itself.
Fix: also record default_used at prepare time and OR it in.

A mid-execute_loop() reprepare() swaps in a freshly re-parsed lex,
losing "EXECUTE ... USING DEFAULT" already folded into default_used by
set_parameters() for this execution.
Fix: save that bit before reprepare() and OR it back in afterwards.

Assisted-By: Claude Opus 5.5 <[email protected]>
Oleksandr Byelkin
Merge branch 'bb-10.11-release' into bb-11.4-release
bsrikanth-mariadb
MDEV-42033: Memory leak of derived_handler when a statement fails early

A derived_handler is created in mysql_derived_prepare() and stored in
TABLE_LIST::dt_handler. It was freed only by JOIN::cleanup(). If the
statement failed before a JOIN was created, nothing freed it, e.g.

  WITH cte AS (SELECT * FROM fed_t) UPDATE cte SET a= a * 2;

which fails with ER_NON_UPDATABLE_TABLE.

Make JOIN::free_pushdown_handlers() a free function,
free_derived_pushdown_handlers(), and also call it from
st_select_lex::cleanup() on top_join_list, right after join->destroy().
It sets pushdown_derived and dt_handler to NULL, so calling it a second
time is a no-op.

The failing tests are already present in
federatedx_pushdown_upd_del.test, just that they need to be run with
valgrind or ASAN build.
Oleksandr Byelkin
Merge branch 'bb-10.11-release' into bb-11.4-release
Sergei Golubchik
MDEV-40847 Server crash on EXPLAIN EXTENDED or CREATE VIEW of a deeply nested JSON_TABLE

* check the stack in Json_table_nested_path::print(), it recurses
  once per NESTED PATH level
* don't save a view definition if printing it failed
* don't push the EXPLAIN EXTENDED note if printing it failed

Assisted-by: Claude:claude-opus-5-5
bsrikanth-mariadb
MDEV-41862: Syntax error with DELETE and IN in FederatedX pushdown

A single-table DELETE with an IN subquery on the same table, pushed
down to FederatedX, failed on the remote server with a syntax error:

  DELETE FROM t3 WHERE a IN (SELECT a FROM t3 WHERE a < 3);

The target table of a single-table DELETE is not in top_join_list, so
the list is empty. st_select_lex::print() printed it as
"delete  from  using dual where ...".

Fix: in st_select_lex::print() use top_join_list only when it is not
empty, and otherwise print the tables from leaf_tables. For DELETE that
branch emits the "from " keyword. UPDATE is unchanged.

As a side effect, EXPLAIN EXTENDED of a single-table DELETE no longer
shows the dummy "using dual" and prints "delete from `t` where ...".
A DELETE through a view now prints the view instead of its base table.
Update the affected results (explain_non_select,
myisam_explain_non_select_all, opt_hints, opt_hints_index, opt_trace,
versioning.delete_history).

Add a test to federatedx_pushdown_upd_del that pushes down DELETE (also
with ORDER BY ... LIMIT and as a prepared statement) and UPDATE with an
IN subquery on the same table, and checks both the resulting data and
the statements received by the remote server in its general log.
Sergei Golubchik
MDEV-40530 test: a proxy that modifies ssl_info_client

ssl-mitm.pl --ssl-info-client forwards ssl_info_client as is, drops or
modifies it.

Assisted-by: Claude:claude-opus-5-5
Oleksandr Byelkin
Merge branch 'bb-12.3-release' into bb-13.1-release
Sergei Golubchik
MDEV-41432 CONVERT TABLE ... TO PARTITION does not check privileges on the table it moves in

The table being moved in got grant.privilege copied from the
partitioned table, so check_grant() verified ALTER, DROP on it against
the wrong database. Run check_access() on its own database instead.

Assisted-by: Claude:claude-opus-5-5
Marko Mäkelä
MDEV-42009: Set GLOBAL innodb_log_file_size=ON is not crash safe

log_t::header_rewrite(): Before setting log_sys.archive=true,
ensure that any garbage entries at the end of the file will be
zeroed out so that they cannot be mistaken for newer records.
On Linux and Microsoft Windows we will attempt a shortcut for
writing zeroes, before falling back to log_file_t::write().

Reviewed by: Alessandro Vetere
Oleksandr Byelkin
Merge branch 'bb-11.4-release' into bb-11.8-release
Oleksandr Byelkin
Merge branch 'bb-11.4-release' into bb-11.8-release
Oleksandr Byelkin
Merge branch 'bb-13.1-release' into bb-13.2-release
Sergei Petrunia
Followup: fix versioning.delete_history in MDEV-39226: Push whole multi-table ...
Rex Johnston
MDEV-39492 PQ: run a FirstMatch semijoin in the workers

The gate refused every semijoin duplicate-elimination strategy, on the
grounds that a worker's nested loop implements none of them. For
FirstMatch that was not true. FirstMatch is the nested loop backing out
early: when the last inner table of the semijoin nest matches, the
executor sets join->return_tab to the outer table the nest follows
(JOIN_TAB::do_firstmatch) and sub_select() unwinds to it rather than
looking for further matches that would only duplicate the row. A worker
runs sub_select() over its own JOIN and its own JOIN_TABs, so it does
the same -- provided its copy of do_firstmatch names a tab of its own
array, since return_tab is only ever compared with the tabs of the
array being walked. setup_worker_jointabs() now remaps do_firstmatch,
first_sj_inner_tab and last_sj_inner_tab from the manager's array onto
the worker's, and the gate admits SJ_OPT_FIRST_MATCH, refusing a nest
whose return tab is a const table, which no worker holds. LooseScan and
DuplicateWeedout keep state that no copy carries -- a match flag, a
weed-out table -- and stay refused, as does materialization.

This is the second half of what TPC-H Q21 needed: its EXISTS over
LINEITEM is flattened to a FirstMatch nest after NATION, and with its
NOT EXISTS left to the manager by the previous commit, the plan the
optimizer had costed as a parallel scan of ORDERS now runs in the
workers.

main.parallel_query_firstmatch runs an EXISTS flattened to FirstMatch
under whole-table aggregation, GROUP BY and a manager-side sort, with
two matching inner rows per outer row so that a nested loop without the
early return would double every count, and shows DuplicateWeedout still
refused.

This commit was prepared with Claude Code (Fable 5.1), which read what
sub_select() and evaluate_join_record() consult for FirstMatch, wrote
the remap and the gate change, and wrote the test.
Oleksandr Byelkin
New help
Oleksandr Byelkin
Merge branch 'bb-11.8-release' into bb-12.3-release
Oleksandr Byelkin
Merge branch 'main' into bb-13.2-release
Sergei Golubchik
MDEV-40530 Bind the client authentication response to the server certificate

MDEV-31855 introduced ssl_info that let the client verify
that it uses the correct certificate. But MitM could hijack the
connection after the authentication - the client will detect it
and disconnect but the server won't and will continue talking
to the attacker. Let's introduce ssl_info_client packet that
enables the server to verify that the client uses the correct
certificate.

When require_secure_transport=ON and the connection isn't local:
* the server sets MARIADB_CLIENT_SSL_INFO_CLIENT in the initial handshake
* the client sets it in the reply, if it understands it
* when both sides have it, the client sends ssl_info_client right
  after the OK packet, acl_authenticate() reads it before the session
  is used (init_connect, audit, etc)
* a connection is rejected unless ssl_info_client is valid, either
  for the server certificate fingerprint or for "CA" (the client
  verified the certificate itself)
* an account without a password hash (plugin has no hash_password()
  or empty password) is rejected unless the account REQUIRE a client
  certificate

Assisted-by: Claude:claude-opus-5-5
Oleksandr Byelkin
Merge branch 'bb-11.4-release' into bb-11.8-release
Marko Mäkelä
MDEV-41395 fixup: GCC 16 -Wstringop-overflow

fil_system_t::default_encrypt_next(): Dereference the iterator only once
to avoid a confusing and bogus -Wstringop-overflow by GCC 16.2.0.
Sergei Golubchik
send ssl_info_client to prove the authentication was not relayed

A MitM can relay the authentication, let the client fail on ssl_info
and keep using the authenticated connection.

* MARIADB_CLIENT_SSL_INFO_CLIENT: set it whenever TLS is used
* after the authentication OK packet send ssl_info_client, the server
  does not reply (but might disconnect in case of active MitM).
Oleksandr Byelkin
new CC 3.3