Conversation
Usage: mtr --mysqld=--debug=d,ref_array,query:i:o,/tmp/mdl.log
…h versioned column In MDEV-25644 vers_check_update() sets vers_write to false in case it returns false. It is ok for UPDATE but is not correct for ODKU is bulk insert requires vers_write on next tuple. The fix return vers_write value back when vers_check_update() and related vers_insert_history_row() are done in ODKU.
row_sel_store_mysql_field() does: 3113 mysql_rec[templ->mysql_null_byte_offset] 3114 &= static_cast<byte>(~templ->mysql_null_bit_mask); but mysql_rec[] which is prefetch buffer was allocated without initialization. Prefetch buffers are allocated by row_sel_prefetch_cache_init(): 3881 ptr = static_cast<byte*>(ut_malloc_nokey(sz)); and then it initializes the buffers with the magic numbers. The fix initializes the buffers with null bytes as well for nullable fields.
This comment was marked as outdated.
This comment was marked as outdated.
There was a problem hiding this comment.
Pull request overview
This PR delivers a set of 10.11 bugfixes across InnoDB row prefetch caching, SELECT ref-pointer-array diagnostics, sequence-function parsing restrictions in clauses that disallow subqueries/stored functions, and versioned-table ODKU behavior—along with regression tests for the reported MDEV issues.
Changes:
- Initialize parts of the InnoDB fetch-cache row buffer to avoid uninitialized NULL-bitmap content.
- Add DBUG instrumentation to track ref_ptrs/all_fields element consumption during
JOIN::prepare(). - Disallow sequence functions (
nextval/lastval/setval) whenLEX::clause_that_disallows_subselectis set; adjust tests and expected errors accordingly. - Fix versioning ODKU behavior by ensuring
table->vers_writeis set for the next bulk iteration; add regression tests. - Add an InnoDB suite regression test for the partition swap_blobs sanitizer/valgrind issue.
Reviewed changes
Copilot reviewed 13 out of 13 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| storage/innobase/row/row0sel.cc | Initializes fetch-cache row buffers (incl. NULL-bitmap handling) during prefetch-cache allocation. |
| sql/sql_select.cc | Adds debug tracing for ref-array element usage through major phases of JOIN::prepare(). |
| sql/sql_lex.h | Clarifies comment docs for clause_that_disallows_subselect. |
| sql/sql_lex.cc | Adds ref-array reservation debug prints; blocks sequence functions in clauses that disallow subqueries/stored functions. |
| sql/sql_insert.cc | Adjusts versioned ODKU flow to ensure vers_write remains set for subsequent bulk iterations; keeps history-row insertion semantics. |
| mysql-test/suite/versioning/t/update.test | Adds regression test for MDEV-38854. |
| mysql-test/suite/versioning/r/update.result | Updates expected output for MDEV-38854 test. |
| mysql-test/suite/versioning/t/partition.test | Adds regression tests for MDEV-36362 expecting ER_SUBQUERIES_NOT_SUPPORTED. |
| mysql-test/suite/versioning/r/partition.result | Updates expected errors/messages for new partition regression tests. |
| mysql-test/suite/sql_sequence/other.test | Updates CHECK-clause expectations to ER_SUBQUERIES_NOT_SUPPORTED for sequence functions. |
| mysql-test/suite/sql_sequence/other.result | Updates expected CHECK-clause error messages/codes accordingly. |
| mysql-test/suite/innodb/t/bug.test | Adds regression test for MDEV-27569 (partition swap_blobs sanitizer/valgrind). |
| mysql-test/suite/innodb/r/bug.result | Expected output for the new InnoDB regression test. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 13 out of 13 changed files in this pull request and generated 1 comment.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
7b9df61 to
11953b9
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 13 out of 13 changed files in this pull request and generated 2 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| for (ulint j = 0; j < prebuilt->n_template; j++) { | ||
| const mysql_row_templ_t*templ = &prebuilt->mysql_template[j]; | ||
| if (templ->mysql_null_bit_mask) { | ||
| ptr[templ->mysql_null_byte_offset] = 0; | ||
| } | ||
| } |
There was a problem hiding this comment.
The fetch-cache rows are later copied with memcpy(buf, cached_rec, prebuilt->null_bitmap_len), so all bytes of the MySQL NULL-bitmap in each cached row must be initialized. This loop only clears bytes for nullable columns present in mysql_template; if the template does not cover all nullable columns, some NULL-bitmap bytes can remain uninitialized and still get copied, triggering MSAN/valgrind warnings. Consider zero-initializing the full NULL-bitmap region (e.g., the first prebuilt->null_bitmap_len bytes) for each cache slot instead of only template offsets.
| for (ulint j = 0; j < prebuilt->n_template; j++) { | |
| const mysql_row_templ_t*templ = &prebuilt->mysql_template[j]; | |
| if (templ->mysql_null_bit_mask) { | |
| ptr[templ->mysql_null_byte_offset] = 0; | |
| } | |
| } | |
| /* Initialize the full MySQL NULL-bitmap because fetch-cache | |
| rows may later be copied based on prebuilt->null_bitmap_len. */ | |
| memset(ptr, 0, prebuilt->null_bitmap_len); |
| MEM_UNDEFINED(prebuilt->fetch_cache[0], prebuilt->mysql_row_len); | ||
| row_sel_prefetch_cache_init(prebuilt); |
There was a problem hiding this comment.
When prebuilt->fetch_cache[0] == NULL, prebuilt->fetch_cache[0] is still a null pointer until row_sel_prefetch_cache_init() sets it. Calling MEM_UNDEFINED(prebuilt->fetch_cache[0], prebuilt->mysql_row_len) here therefore passes a NULL address to MSAN/valgrind instrumentation and can crash or misbehave. Move the MEM_UNDEFINED() call to after row_sel_prefetch_cache_init(prebuilt) (or apply it to the pointer returned/assigned by the init).
Function calls in INTERVAL expression of DDL have little sense. SETVAL() fails because sequences require opened tables and vers_set_interval() is called at earlier stage. The fix throws ER_SUBQUERIES_NOT_SUPPORTED for sequence functions SETVAL(), NEXTVAL(), LASTVAL() when the context does not allow subselect (determined by clause_that_disallows_subselect).
a08f1bb to
aac70a6
Compare
The problem with the current initialization is that TABLE_LIST ctors as well as init_one_table*() functions call reset() that byte-zeroes the object after encapsulated objects were initialized by their constructors. That specifically creates the wrong value for mdl_request.type which must be MDL_NOT_INITIALIZED (-1) by default and bzero() reverts it to MDL_INTENTION_EXCLUSIVE (0). And these constant values is not easy (if not possible) to change. The fix introduces utility base class Byte_zero which moves bzero() call before the encapsulated ctors (as parent classes' ctors are called first). So now encapsulated ctors are not called redundantly and no double initialization is needed. All the C++-constructed objects call init_one_table*() as before, only without reset(). The C-alloced objects call init_one_tab*_r() versions that call reset(). These will be replaced back to no-reset() versions after their allocation is refactored to C++ version.
As C++ style initialization of TABLE_LIST now works correctly after Byte_zero refactoring. We may remove MDL_NOT_INITIALIZED double initialiation.
aac70a6 to
856b5f4
Compare
|
Hi @midenok ! If you don’t mind, may I kindly suggest that you avoid using a bb- branch and a Pull Request at the same time for the pull requests you open? This ends up duplicating builds in Buildbot. I’m working on a solution to cancel the unnecessary ones, but it would really help me a lot if your source branch for this Pull Request (or others) didn’t include bb- in its name. Also, one more thing please: pushes that happen more frequently than once per minute, but still quite often, generate a very large number of builds. Again, I’m working on a solution here as well to cancel the older ones. Thank you very much for your understanding! |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 30 out of 30 changed files in this pull request and generated 1 comment.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| } | ||
|
|
||
| TABLE_LIST(TABLE *table_arg, thr_lock_type lock_type) | ||
| TABLE_LIST(TABLE *table_arg, thr_lock_type lock_type) : Byte_zero(*this) |
There was a problem hiding this comment.
TABLE_LIST(TABLE *table_arg, ...) initializes the Byte_zero base with *this, but Byte_zero expects a size_t. This should not compile, and even if it did, the intent appears to be zeroing sizeof(*this) like the other constructors.
| TABLE_LIST(TABLE *table_arg, thr_lock_type lock_type) : Byte_zero(*this) | |
| TABLE_LIST(TABLE *table_arg, thr_lock_type lock_type) : Byte_zero(sizeof(*this)) |
I thought it was fixed long ago, but it was not actually... @RazvanLiviuVarzaru, do you know the solution? |
No description provided.