Console View
|
Categories: connectors experimental galera main |
|
| connectors | experimental | galera | main | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
|
|
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Georgi (Joro) Kodinov
joro@mariadb.org |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
MDEV-39572: Fix small typos in COMMUNITY_CONTRIBUTIONS.md Fixed some minor header typos in the document. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Alexander Barkov
bar@mariadb.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
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
daniel@mariadb.org |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| MDEV-40949 Missing space after how-to-produce-a-full-stack-trace-for-mariadb link | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Vladislav Vaintroub
vvaintroub@gmail.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
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
db@dbart.us |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Merge branch 'bb-10.11-bumpversion' of github.com:MariaDB/server into bb-10.11-bumpversion | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Marko Mäkelä
marko.makela@mariadb.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
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
vvaintroub@gmail.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
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
hemant.dangi@mariadb.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
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
daniel@mariadb.org |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
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
git@jaeheonshim.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
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
khaled57.dev@gmail.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
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
jan.lindstrom@mariadb.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
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
cpswastik31@gmail.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
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
jan.lindstrom@mariadb.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
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ä
marko.makela@mariadb.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
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
jan.lindstrom@mariadb.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
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
seppo.jaakola@mariadb.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
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
knielsen@knielsen-hq.org |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
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
thiru@mariadb.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
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
brandon.nesterenko@mariadb.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
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
vvaintroub@gmail.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
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
anehra@amazon.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
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
knielsen@knielsen-hq.org |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
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
knielsen@knielsen-hq.org |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
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
monty@mariadb.org |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
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
db@dbart.us |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| bump the VERSION | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
ParadoxV5
paradox.ver5@gmail.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
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
seppo.jaakola@mariadb.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
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
db@dbart.us |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| bump the VERSION | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Kristian Nielsen
knielsen@knielsen-hq.org |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
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
jacob@iakob.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
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
bar@mariadb.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
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
hemant.dangi@mariadb.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
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
otto@kekalainen.net |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
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ä
marko.makela@mariadb.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
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
daniel@mariadb.org |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
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
jan.lindstrom@mariadb.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
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
vvaintroub@gmail.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Rocksdb - suppress MSVC warning in external code ribbon_impl.h(879,1): warning C4723: potential divide by 0 on VS2025 |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Vladislav Vaintroub
vvaintroub@gmail.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
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
iminelink@gmail.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
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. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||