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
Monty
Update backup code to use new my_dir and my_copy interfaces
Kristian Nielsen
Semi-sync: Clean up incorrect file/pos comparisons

The semi-sync code has a number of places where it compares pairs of
(filename,offset) for which is larger than the other.

The filename comparisons are done using strcmp(), which is wrong. Filenames
will compare wrong when they wrap from eg. bin-999999 to bin-1000000, and
user can also rename log files which can likewise break comparisons.

Further, the comparisons are completely unnecessary, as all the transactions
to be waited for are already stored in a linear list in order _and_ in a
hash table. So the code can simply use the existing hash table look and list
traversal to determine status and sequence of the waited-for transactions.

So this patch removes all the comparisons for larger/smaller, leaving only
comparisons for equality and effectively making the (filename,offset) pairs
just opaque transaction identifiers. And also removes a few other related
pieces of dead/unnecessary code.

Signed-off-by: Kristian Nielsen <[email protected]>
Oleksandr Byelkin
MDEV-39993 Force InnoDB in the sys routine grants upgrade test

vaintroub (PR #5698): without an explicit engine requirement, this
test could run in a config where InnoDB isn't the checked table's
engine, making mariadb-upgrade's "Checking and upgrading" phase
print misleading "Unknown storage engine 'InnoDB'" / "error :
Corrupt" lines for mysql.innodb_index_stats, mysql.innodb_table_stats
and mysql.transaction_registry, and a spurious "Repairing tables"
section. Add --source include/have_innodb.inc so the test only runs
with InnoDB available, and re-record the now-clean result.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
Monty
Implement copying of Aria files with reading of big blocks

The new interface for copy transactional Aria files:

Copying of an aria tables starts and end with these calls:
int aria_open_files_for_backup(THD *thd,
                              const char *path, my_bool trans_type,
                              ARIA_BACKUP_CONTEXT *context);
void aria_close_files_for_backup(ARIA_BACKUP_CONTEXT *context);

Reading through an aria file is done wih these calls:
longlong aria_read_index_file(ARIA_BACKUP_CONTEXT *context,
                              uchar *buffer, size_t buff_length);
longlong aria_read_data_file(ARIA_BACKUP_CONTEXT *context,
                            uchar *buffer, size_t buff_length);
One should call both in a loop until the return is <= 0
0 means end of file, a negative value means error.

storage/maria/test_ma_backup.c tests the code and can be used as an example
of how to use the functions.
Dave Gosselin
MDEV-33616:  Allocate the recovery buffer from the heap

recv_sys.tmp_buf comes from aligned_malloc() rather than from the large
page allocator.

main.large_pages fails on macOS with "Warning: Memory not freed: 16375"
at shutdown.  recv_sys_t::find_checkpoint() asks for 1048585 bytes,
my_large_malloc() rounds that up to 1064960 and charges the rounded
figure to the server memory accounting, and recv_sys_t::tmp_free()
credits back the 1048585 that was requested.  ut_malloc_dontdump() takes
the size by value, so it has nowhere to report what my_large_malloc()
wrote back.

Only macOS rounds.  my_get_large_page_sizes() has no huge page interface
to consult there, so its fallback branch reports the ordinary page size
of 16384 as the only large page size.  Linux offers 2 MiB and larger,
and my_next_large_page_size() returns only sizes at or below the
request, so this buffer is never rounded there.

The alignment is srv_page_size because recv_dblwr_t::validate_page()
uses the start of the buffer as two page frames.

log_sys.buf and log_sys.flush_buf keep the large page allocator and stay
excluded from core dumps.  They round the same way, so a server started
with --large-pages --innodb-log-buffer-size=2101248 still reports 24576
on macOS.  recv_sys.tmp_buf can now appear in a core dump, holding redo
log records that innodb_encrypt_log has decrypted.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
Kristian Nielsen
Semi-sync: Implement support for using GTID in semi-sync ACKs

Implement the necessary logic in class Repl_semi_sync_master_gtid and
related code, so that the semi-sync master can request the slave to put the
GTID in the reply ACK packet, instead of the filename/offset.

In GTID mode, when a slave connects (which it should do using a GTID start
position), the latest GTID in the starting position (if any), as determined
by the list of transactions pending acks, is used as the point at which to
implicit ACK anything pending.

The semi-sync logic is otherwise unchanged, in GTID mode it just uses the
GTID as the transaction identifier instead of the file/pos of the end of the
event group.

This patch only enables the GTID-based semisync for binlog-in-engine, but
the mode works with old binlog implementation as well, and passes all tests
(if enabled by code change).

Signed-off-by: Kristian Nielsen <[email protected]>
Thirunarayanan Balathandayuthapani
MDEV-40324 use-of-uninitialized-value after creation of FULLTEXT table failure

Problem:
=======
For fulltext index, row_create_index_for_mysql() calls
fts_create_index_tables(). If creating FTS auxiliary table fails,
error handling performs trx->rollback() of the dictionary
transaction. Rollback removes the parent table from
dictionary cache and frees it. After that,
convert_error_code_to_mysql() reads table->flags after table->heap.
This leads to read of freed memory.

Solution:
========
create_index(): Read table->flags into a local variable before
calling row_create_index_for_mysql()
Khaled Riyad
MDEV-41150 mariadb client: Ctrl-C does not interrupt tab separated result output

Ctrl-C sets interrupted_query and sends KILL QUERY to the server, but the
result is already fetched into the client by then, so killing the query
cannot stop the output. Only the printing loop can, by checking
interrupted_query.

print_table_data(), print_table_data_html(), print_table_data_xml() and
print_table_data_vertically() check it, print_tab_data() did not, so the
output of -s, -N and -B could not be interrupted.

Add the same check to print_tab_data().

No test case: the suite drives the client through a pty with socat, where
0x03 is not turned into a signal, and there is no other way in the suite to
signal a client while it is printing.
Monty
Fixed that translog_walk_filenames() in Aria properly recognized aria
log filenames.
Val Doroshchuk
MDEV-41154: Report an error when the engine fails in ha_rnd_pos

DELETE skips the row without reporting anything when error is returned by handler::ha_rnd_pos()

Report every error except the two that genuinely mean "the row is not there
any more".
Monty
Update backup code to use new my_dir and my_copy interfaces
Oleksandr Byelkin
MDEV-41205 Report CREATE OR REPLACE routine failures, don't crash/hide them

CREATE OR REPLACE FUNCTION/PROCEDURE/PACKAGE replaces an existing
routine by first deleting its mysql.proc row
(Sp_handler::sp_drop_routine_internal(), or
Sp_handler_package_spec::sp_find_and_drop_routine() for a PACKAGE,
which drops the PACKAGE BODY row then the spec row) and then
writing the new one. If either step failed, no my_error() was ever
called: sp_drop_routine_internal() returned SP_DELETE_ROW_FAILED
silently, its two callers in Sp_handler::sp_create_routine() just
did "goto done;", and a failing ha_write_row() was always reported
as ER_SP_ALREADY_EXISTS regardless of the real cause. The statement
finished with an empty Diagnostics_area, which
Protocol::end_statement() turns into DBUG_ASSERT(0) on a debug
build (crashing the server) and a silent client-visible OK on a
release build, for a routine that may have been left half-dropped.

Fix:
- sp_drop_routine_internal() now captures ha_delete_row()'s error
  code and reports it via print_error() before returning
  SP_DELETE_ROW_FAILED.
- The SP_TYPE_PACKAGE and SP_TYPE_PACKAGE_BODY/FUNCTION/PROCEDURE
  arms in sp_create_routine()'s CREATE OR REPLACE switch now call
  my_error(ER_SP_DROP_FAILED, ...) before "goto done;", mirroring
  the identical safety net the explicit DROP PROCEDURE/FUNCTION
  path already has in sql_parse.cc. Because the first error raised
  wins, this only fires when the delete didn't already report one
  itself (e.g. SP_KEY_NOT_FOUND from a concurrent drop) -- a
  comment explains this so a future reader doesn't "clean up" it
  as dead code.
- ha_write_row()'s error code is now captured too: only a genuine
  HA_ERR_FOUND_DUPP_KEY still gets ER_SP_ALREADY_EXISTS; any other
  code goes through print_error(), with a my_error(ER_SP_STORE_FAILED)
  fallback in case print_error() itself doesn't raise anything
  (a couple of handler error codes are legitimately silent).

Two DBUG_EXECUTE_IF fault-injection points let this be tested without
a real storage-engine failure: "sp_drop_routine_internal_fail" (any
delete), "sp_drop_routine_internal_fail_package_spec_only" (only the
PACKAGE spec delete, letting a test target the harder "body already
gone, spec delete now fails" ordering), and
"sp_create_routine_write_row_fail" for the write path.

New test mysql-test/main/sp-error-debug.test covers FUNCTION,
PROCEDURE, PACKAGE BODY alone, and both PACKAGE delete orderings,
plus the write-row failure path.

Known limitations, deliberately not addressed here:
- Sp_handler_package_spec::sp_find_and_drop_routine() drops the
  PACKAGE BODY row before the spec row; if the spec delete then
  fails, the body is durably gone (already flushed) while the spec
  survives, and neither the drop nor a subsequent DROP PACKAGE
  binlogs that sub-operation. This is a genuine pre-existing gap
  (mysql.proc is Aria, non-transactional, so a true atomic two-row
  drop isn't achievable without a larger change) that this patch
  does not make worse -- it only makes the failure visible via a
  proper error instead of a crash or silent OK. Left for a
  follow-up MDEV.
- sql_parse.cc's explicit DROP PROCEDURE/FUNCTION path calls
  sp_revoke_privileges() whenever sp_result != SP_KEY_NOT_FOUND,
  which now includes a reachable SP_DELETE_ROW_FAILED -- so a
  failed DROP can still strip the routine's grants. Pre-existing,
  unrelated to CREATE OR REPLACE; left for a follow-up MDEV.
- This same code is unchanged in 10.6 and 10.11; the reproducer
  applies there too. Kept on 11.4 per the reporter's request.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
Monty
Fixed that translog_walk_filenames() in Aria properly recognized aria
log filenames.
Oleksandr Byelkin
MDEV-39993 Use CREATE OR REPLACE for sys schema routines

mariadb-upgrade silently dropped EXECUTE grants on sys schema stored
functions and procedures. The sys schema install scripts reinstalled
every routine with DROP FUNCTION/PROCEDURE IF EXISTS followed by
CREATE. DROP cascades to delete the routine's rows in
mysql.procs_priv, so any EXECUTE grant a DBA had issued on e.g.
sys.table_exists or sys.quote_identifier was lost every time
mariadb-upgrade reinstalled the sys schema, even though the routine
itself came back unchanged.

Fix: replace DROP ... IF EXISTS + CREATE with CREATE OR REPLACE in
all 53 sys_schema function/procedure files and in the two templates
(templates/function.sql, templates/procedure.sql) so future routines
follow the same pattern. CREATE OR REPLACE PROCEDURE/FUNCTION goes
through sp_drop_routine_internal(), which only deletes the
mysql.proc row and never reaches sp_revoke_privileges() (that is
only called from the explicit DROP PROCEDURE/FUNCTION statement),
so mysql.procs_priv is left untouched and existing grants survive.
This mirrors the pattern already used by sys schema views
(CREATE OR REPLACE ... VIEW, since MDEV-9077), which never had this
problem.

Four of the converted files (functions/format_path.sql,
functions/ps_is_account_enabled_57.sql,
procedures/ps_setup_reset_to_default.sql,
procedures/ps_trace_thread_57.sql) are not referenced by
scripts/sys_schema/CMakeLists.txt; they were converted anyway for
consistency and have no behavioural effect.

As a side effect, a pre-existing UDF whose name collides with a sys
routine name is no longer destroyed before the reinstall fails:
DROP FUNCTION IF EXISTS resolved the UDF namespace first, silently
dropping the UDF and then failing on ER_SP_ALREADY_EXISTS anyway;
CREATE OR REPLACE fails immediately on ER_UDF_EXISTS with the UDF
intact.

scripts/maria_add_gis_sp.sql.in and the sys_config triggers were
deliberately left untouched: the GIS procedures are only
re-installed at bootstrap time (mariadb-upgrade instead patches
their definer in place via UPDATE), and triggers carry no
procs_priv rows, so neither is on the code path this bug is about.

Added mysql-test/main/mysql_upgrade_sys_routine_grants.test, which
grants EXECUTE on sys.table_exists and sys.quote_identifier,
overwrites both routine bodies with a marker to prove the upgrade
actually reinstalls them (rather than the sys schema install being
skipped), runs mariadb-upgrade, and checks both that the grants
survived and that the real routine bodies came back.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
Kristian Nielsen
Fix GCC uninitialized warning on Fedora 44

Signed-off-by: Kristian Nielsen <[email protected]>
Kristian Nielsen
Implement support for semi-sync with --binlog-storage-engine

Call report_binlog_update() when semi-synchronous replication is enabled and
using --binlog-storage-engine.

Only AFTER_COMMIT is available. The AFTER_SYNC in legacy binlog has the
property that changes in a committing transaction does not get visible to
other transactions until the slave has acknowledged, avoiding phantom reads
if the master fails permanently just after. This requires the two-phase
commit between binlog and storage engine so that the binlog is written
before the transaction is engine-committed. However, the whole point of
--binlog-storage-engine is to avoid the expensive two-phase commit.

(The ability to avoid phantom reads could be later implemented as an
AFTER_PREPARE option, which would send binlog to slave and await ack before
it is written/committed into the engine).

Some existing semi-synchronous replication tests are adapted to also run in
the binlog_in_engine suite.

Signed-off-by: Kristian Nielsen <[email protected]>
Kristian Nielsen
Fix embedded build 2

Signed-off-by: Kristian Nielsen <[email protected]>
Dave Gosselin
MDEV-33616:  Skip the redo log upgrade tests without sparse file support

innodb.log_upgrade and innodb.log_upgrade_101_flags build 8GB redo log
files by seeking past the end of an empty file and writing a single
byte.  That needs a filesystem which leaves the skipped range
unallocated.  HFS on macOS allocates every block of it instead, so the
write fails with ENOSPC and the test reports a perl failure.

include/have_sparse_files.inc probes a directory the caller names,
writing one byte 64MB into an empty file there and comparing the
allocated block count against that offset.
Marko Mäkelä
fixup! ae8056d2279c5a96ce73206a4f70b0d69e5f3817
Kristian Nielsen
After-review fixes

Signed-off-by: Kristian Nielsen <[email protected]>
Kristian Nielsen
Semi-sync: Some few after-review fixes

Signed-off-by: Kristian Nielsen <[email protected]>
Monty
Implement copying of Aria files with reading of big blocks

The new interface for copy transactional Aria files:

Copying of an aria tables starts and end with these calls:
int aria_open_files_for_backup(THD *thd,
                              const char *path, my_bool trans_type,
                              ARIA_BACKUP_CONTEXT *context);
void aria_close_files_for_backup(ARIA_BACKUP_CONTEXT *context);

Reading through an aria file is done wih these calls:
longlong aria_read_index_file(ARIA_BACKUP_CONTEXT *context,
                              uchar *buffer, size_t buff_length);
longlong aria_read_data_file(ARIA_BACKUP_CONTEXT *context,
                            uchar *buffer, size_t buff_length);
One should call both in a loop until the return is <= 0
0 means end of file, a negative value means error.

storage/maria/test_ma_backup.c tests the code and can be used as an example
of how to use the functions.
Monty
fixup!
Kristian Nielsen
mysqltest: Implement --enable_sync_gtid option

The --enable_sync_gtid option switches to use GTID-based
--sync_slave_with_master (eg. using MASTER_GTID_WAIT() instead of
MASTER_POS_WAIT()).

This is useful to run adapt existing test cases for use with
--binlog-storage-engine. But it is also useful in general for replication
using GTID (which is the default).

The option is off by default to not randomly break existing tests.

Signed-off-by: Kristian Nielsen <[email protected]>
Aleksey Midenkov
MDEV-39074 trans_rollback_stmt(THD *): Assertion `! thd->in_sub_stmt' failed.

slave_close_thread_tables() unconditionally called
trans_commit_stmt()/trans_rollback_stmt(), which assert
!thd->in_sub_stmt. A BINLOG statement with malformed base64 payload
executed from an AFTER INSERT trigger hits this: on decode failure,
mysql_client_binlog_statement() sets thd->is_error() and calls
slave_close_thread_tables() from within the trigger's sub-statement.

Guard it with spcont/in_sub_stmt, deferring cleanup to the
enclosing top-level statement. Other callers run only from the
top-level SQL slave applier thread, so this doesn't change their
behavior.

1. BINLOG statement executed from a trigger, SF or SP is disabled
by the patch:

Row events (Rows_log_event) open their target table via a
one-shot check that only fires at the top of a fresh statement.
Inside a trigger, the table is never opened this way. It may be
fixed by reusing query_tables, but:

  - find_locked_table() matched only by table name -- could return
    the TABLE instance the enclosing statement was actively writing
    through, not an idle one. Reusing it would require pre-saving its
    state: record[0]/bitmaps/handler/etc. (will deprecate
    ER_CANT_UPDATE_USED_TABLE_IN_SF_OR_TRG)

  - set_stmt_row_injection()/set_time() calls mutated thd->lex, which
    at that point is main_lex -- shared with the enclosing statement,
    not something safe to touch.

Statement events (Query_log_event) run the embedded query via
mysql_parse(): it bundles lex_start(), reset_for_next_command() and
parse_sql() as one unit meant for a genuinely new top-level statement,
not a one-off nested parse.

Calling parse_sql() directly instead avoids that, but then we own
everything mysql_parse() was doing for us: a private LEX and a
private Query_arena (or allocations land on main_lex/whatever arena
is currently active, shared with the enclosing statement), plus
calling mysql_execute_command() ourselves afterwards.

In any case, DML for query_tables cannot be done due to
ER_CANT_UPDATE_USED_TABLE_IN_SF_OR_TRG reasons explained above.

2. PS for BINLOG statement still works and needs a leak fix for
statement events:

A BINLOG statement decoding to a Query_log_event, executed via
PREPARE/EXECUTE, leaked its nested query's allocations onto the PS's
own persistent arena: thd->stmt_arena pointed at it while mysql_parse()
ran the decoded query. Second EXECUTE asserted on ROOT_FLAG_READ_ONLY,
since PROTECT_STATEMENT_MEMROOT marks that arena read-only after a
successful execution.

The fix redirects thd->stmt_arena to thd itself for the duration of
the nested mysql_parse() call, so stmt_arena->is_conventional() reads
true and activate_stmt_arena_if_needed() (called e.g. from
save_leaf_tables()) never redirects allocations to the PS's arena in
the first place.

Harmless for what it's protecting: leaf_tables_exec is normally cached
on the persistent arena so a repeatedly-executed statement's
SELECT_LEX doesn't rebuild it every time, but our SELECT_LEX is torn
down and reparsed fresh (due to mysql_parse() semantics) on every
EXECUTE, so there's nothing to cache here regardless of which arena is
used.
Kristian Nielsen
MDEV-40729: Add functionality to verify if a transaction is committed or not after failure

Basic proof-of-concept patch, only implements the basics to put trx_id into
the binlog file and search for it with trx_status().

A test case rpl.rpl_client_trx_id demonstrates the functionality.

Some limitations/considerations from this patch:

There is no support for MARIADB_TRX_IN_PROGRESS (do we want/need such
functionality?).

Based on 10.11, however pushing to stable 10.11 will be controversial as it
changes GTID event format.

Since 10.11 has no GTID indexes, linear scan of at least one entire binlog
file will be required. An in-memory cache may be needed to handle client
reconnect-storm after a crash or network outage that caused many ongoing
commits to fail.

When starting gtid is not specified for trx_status(), it is not possible to
distinguish between MARIADB_TRX_ABORTED or MARIADB_TRX_UNKNOWN. In this
case, we return MARIADB_TRX_ABORTED.

Knowing where to start scanning binlogs is important, for performance (to
avoid scanning _entire_ binlog history), and to distinguish
MARIADB_TRX_ABORTED from MARIADB_TRX_UNKNOWN. It is somewhat tricky
though:

- A GTID position is multi-dimensional. The starting GTID _must_ be with
  the same domain_id as the transaction being searched for, otherwise
  searching on a slave may start too late in the slave's binlog and wrongly
  return MARIADB_TRX_ABORTED for a committed transaction.

- The client will need to obtain a starting GTID for the very first
  transaction done on the connection. One possible way could be to
  SELECT @@GLOBAL.gtid_binlog_pos and pick out the one with the domain_id
  which will be used for subsequent transactions.

Signed-off-by: Kristian Nielsen <[email protected]>
Kristian Nielsen
Semi-sync: Refactor in preparation for using GTID in semi-sync acks

This is a refactor patch that contains no/little logic changes but a lot of
mostly mechanic code changes to prepare for allowing to use either old-style
filename/offset or new-style GTID to identify an event group in the
semi-sync ack.

The idea is to replace all explicit filename/offset function arguments with
a generic Repl_semi_sync_trx_info *inf to identify an event group (aka
"transaction"). This object can then be used to look up in the semi-sync
hash table by either file/pos or by GTID.

The classes Active_tranx and Repl_semi_sync_master are sub-classed into
Active_tranx_file_pos/Active_tranx_gtid and
Repl_semi_sync_master_file_pos/Repl_semi_sync_master_gtid. Virtual functions
are implemented in each for comparing identifiers and for calculating hash
keys, using either the file/pos or the GTID as appropriate. This way, the
existing logic can now be used with either (only file/pos is actually used
in this patch; adding GTID is for a subsequent patch).

For the binlog writing side, report_binlog_update(), wait_after_sync(), and
THD::semisync_info are extended to also take the GTID of the event group,
which is already available in the calling code.

For the dump thread / slave connection side, update_sync_header() is
extended to take also the GTID. The dump thread code is extended to keep
track of the GTID of the current event group (slightly extending the logic
already there to keep track of event groups). Also, the dump thread now only
passes the last event of an event group into the semisync layer (the other
events are redundant, as they are never semi-sync ack'ed, saving needless
semisync locking and hash lookups).

Signed-off-by: Kristian Nielsen <[email protected]>
Dave Gosselin
MDEV-33616:  Match the macOS dlopen error in plugins.multiauth

The client reports why it could not load client_ed25519, and macOS names
every path that dlopen() tried.  Two expressions are added, one for the
chunk that holds the start of that message and one for the chunk that
holds the rest of it.

The line runs to 563 bytes, 52 of prefix and the 511 that the client
error buffer holds, while do_exec() reads the output with fgets() into a
512 byte buffer and runs the replacements on each chunk on its own.  A
long enough vardir therefore splits the line, because the path appears
four times in the dlopen text.  The second chunk is the tail of a path
and carries no colon, where the first chunk keeps the colons of the
mysqltest prefix.  That chunk also holds the only line terminator the
error line gets, so the expression captures the newline and the
replacement puts it back.  A replacement is inserted as written, so a \n
spelled there would reach the output as a backslash and an n.

Both expressions stop at a newline.  reg_replace compiles with
REG_DOTALL, so an unrestricted .* runs past the line terminator whenever
the whole message reaches the replacement in one chunk, and the error
line then joins the line after it.
Kristian Nielsen
Fix embedded build 1

Signed-off-by: Kristian Nielsen <[email protected]>
Kristian Nielsen
Fix hang on master when disabling semi-sync

There is a global variable global_ack_signal_fd used to signal the receiver
thread to wake up when disabling semi-sync. This variable was cleared to -1
in the Ack_listener destructor, which ran at the end of the
Ack_receiver::run() function without any locking. If the thread was delayed
at that point, it could end up overwriting the new value set by a new
receiver thread. This would leave the server in a state with an invalid
global_ack_signal_fd and could cause a subsequent disable of semisync to
fail due to the wakeup not arriving at the receiver thread.

This was seen as a sporadic failure of the test case
rpl.rpl_semi_sync_cond_var_per_thd.

Fix by not modifying the global in constructor/destructor; instead set and
clear the global explicitly, allowing to clear the fd with proper locking
while the mutex is still being held.

Also fix a missing pthread_join(), which would leak thread descriptors and
allow to start a new receiver thread before the old one shut down fully.

(Either of these two changes fix the hang bug).

Signed-off-by: Kristian Nielsen <[email protected]>
Rucha Deodhar
MDEV-41181: ASAN heap-buffer-overflow after SELECT JSON_SCHEMA_VALID
Dave Gosselin
MDEV-33616:  Take the read lock many times in perfschema.func_mutex

The wait timer can have a granularity coarser than the time an
uncontended read lock is held, so the recorded duration of one lock can
be zero, which reads back as NULL.  This can cause the test to fail with
a false negative.

Take the lock twenty more times at each measurement point, with the
extra statements silent so the recorded result does not change.  The
mutex part of the test already works this way, since one SELECT
produces ten THR_LOCK::mutex events.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
Monty
Added new mysys functions my_open_dir and improved my_copy

- Improved my_copy() using copy_file_range and memmap

- New mysys functions:
int my_copy_file(File from, File to, myf MyFlags);
int my_copy_file_range(File from, File to, my_off_t start,
                        my_off_t end, myf MyFlags);

- New functions for looping over files in a directory:
MY_NO_CACHE_DIR *my_dir_open();
int my_dir_read_next()
int my_dir_rewind();
int my_dir_close();

Other things
- Fixed #ifdef's in sql_backup.cc to use the new define
  HAVE_COPY_FILE_RANGE
Monty
Integrate the old and new backup code

Fixes a lot of issues in current backup code:
- Galera should now be supported (needs testing)
- Enables ddl logging (so we can use it in the future)
- Flushes binary logs (we still must add code to copy them)
- mdl locks are consistent between maria-backup and backup command
- startup backup code for InnoDB moved to innodb_prepare_for_backup()
  called by prepare_for_backup hton handler.
- Give errors if backup command is done under a transaction, global
  read lock or lock tables.
- Retry for MDL_BACKUP_WAIT_DDL (needed for
  backup.backup_ddl_concurrent_verify)
- Removed wrong log locks in Aria

Things to do (in addition to the things in my earlier review) :
- At backup_stage stage start, force rotate of aria log files. This
  allows us to copy all old logs without any locks
- Copy all transactional tables and old aria logs under BACKUP_START (as
- maria-backup does)
- Copy the active aria log file under block commit (Only one file as aria
  log rotation is disabled while backup is running.
- Improve speed of copying aria tables by copy files in up to 1M
  blocks and run checksum on the blocks and only re-read blocks with
-  wrong checksum.
- Copy non transactional files under BACKUP_PHASE_NO_BEGIN_NON_TRANS.
  Note that Aria does not support the documented
  BACKUP_PHASE_NO_DML_NON_TRANS . The BACKUP_PHASE_NO_BEGIN_NON_TRANS
  state is already blocking changes to non transactional tables
Dave Gosselin
MDEV-41212:  multi_source.status_vars fails on MacOS platform

Replace the two recorded reads of Slave_received_heartbeats with an
assertion that the counter is nonzero.

The counter advances once per heartbeat period for as long as the
connection is running.  The test waited for it to reach 2 and then
read it again in a separate query, so a heartbeat arriving between
those two queries recorded an unexpected value.
Kristian Nielsen
Fix typo in comment

Signed-off-by: Kristian Nielsen <[email protected]>
Pekka Lampio
MDEV-39143 Replicate MySQL binary JSON to a MariaDB slave

Let a MariaDB slave apply ROW-format binlog events from a MySQL
master that contain JSON columns, both as full documents and as
MySQL's partial (diff) JSON updates (PARTIAL_UPDATE_ROWS_EVENT).
Monty
Added new mysys functions my_open_dir, my_win_open and improved my_copy

- Improved my_copy() using copy_file_range and memmap
- Improve performance of my_win_open() by taking free entries from a list
  instead of searching after a free space in an array.

New mysys copy functions:

int my_copy_file(File from, File to, myf MyFlags);
int my_copy_file_range(File from, File to, my_off_t start,
                        my_off_t end, myf MyFlags);

Added compatibility functions for easy converting a windows HANDLE to
a File and back:

File my_convert_handle_to_file(my_native_file handle, int oflag);
void my_detach_file(File fd);
which complements the existing my_native_file_handle(fd)

New functions for looping over files in a directory:

MY_NO_CACHE_DIR *my_dir_open();
int my_dir_read_next()
int my_dir_rewind();
int my_dir_close();

Other things
- Fixed #ifdef's in sql_backup.cc to use the new define
  HAVE_COPY_FILE_RANGE
Oleksandr Byelkin
fix MDEV-31342 view protocol