[MDEV-29954] Unique hash key on column prefix is computed incorrectly Created: 2022-11-06 Updated: 2024-01-24 Resolved: 2024-01-23 |
|
| Status: | Closed |
| Project: | MariaDB Server |
| Component/s: | Admin statements, Storage Engine - InnoDB |
| Affects Version/s: | 10.4, 10.5, 10.6, 10.7, 10.8, 10.9, 10.10, 10.11, 11.0 |
| Fix Version/s: | 10.5.24, 10.6.17, 10.11.7, 11.0.5, 11.1.4, 11.2.3 |
| Type: | Bug | Priority: | Critical |
| Reporter: | Elena Stepanova | Assignee: | Sergei Golubchik |
| Resolution: | Fixed | Votes: | 1 |
| Labels: | corruption, regression | ||
| Issue Links: |
|
||||||||||||||||||||||||
| Description |
|
The error started showing up on 10.6 after
|
| Comments |
| Comment by Elena Stepanova [ 2022-11-06 ] | ||||||||||||||||||||||||||||||||||||||||||
|
Adding a sleep before CHECK causes appearance of additional warnings in the CHECK and different errors in the error log;
| ||||||||||||||||||||||||||||||||||||||||||
| Comment by Elena Stepanova [ 2022-11-06 ] | ||||||||||||||||||||||||||||||||||||||||||
|
The MyISAM variation of the error naturally existed before the InnoDB CHECK extension. It should probably be another bug report, if we still file bugs related to unique blobs; the point of this report was that CHECK which succeeded or pretended to succeed before is now throwing corruption errors.
| ||||||||||||||||||||||||||||||||||||||||||
| Comment by Marko Mäkelä [ 2022-11-07 ] | ||||||||||||||||||||||||||||||||||||||||||
|
If I define UNIQUE(a,b), the check will pass. As soon as I define a prefix index on the column b, the check will fail. Internally, the unique index is defined as INDEX(DB_ROW_HASH_1), with the value 0x55a75aa8493a53ce for the only row. It is notable that a non-EXTENDED check reports no failure.
The wait for the purge of committed transaction history is there to give the When the value of the column is being computed from the clustered index record in row_check_index_match(), the function innobase_get_computed_value() will invoke row_sel_field_store_in_mysql_format_func() with the full length of column b, instead of using the column prefix length b(8). I think that this is correct: InnoDB is supposed to supply the full values of the base columns. What seems incorrect is the way how the value of DB_ROW_HASH_1 is computed. I see that the vf.vcol_info.expr in TABLE::update_virtual_field() is defined as Item_func_hash on two expressions, the second one being Item_func_left). This subexpression would be created in parse_vcol_defs() when opening the table definition:
We must ensure that the full column b from the clustered index will be attached to the Item_field when the expression is being evaluated. During the invocation of innobase_get_computed_value(), Item_field::val_str() will be invoked twice: First for on the full column a, with str->Ptr="foo", then on the column prefix b, with the incorrect value str->Ptr=nullptr. For the full column, the str->Ptr was initialized already during the execution of the INSERT statement. Curiously, even during the INSERT, the column prefix index is not being taken account in the calculation, but apparently the evaluation error will be ignored, unlike in innobase_get_computed_value():
| ||||||||||||||||||||||||||||||||||||||||||
| Comment by Marko Mäkelä [ 2022-11-07 ] | ||||||||||||||||||||||||||||||||||||||||||
|
I see that there is no SQL syntax for the Item_func_hash. An attempt to use a different type of hash function failed:
| ||||||||||||||||||||||||||||||||||||||||||
| Comment by Elena Stepanova [ 2022-11-07 ] | ||||||||||||||||||||||||||||||||||||||||||
|
As further discussion revealed and the extension of the test confirmed, the new "flagging" prevents further DML on the table:
while it worked seemingly all right before:
So I would still say that from the user perspective, it's a regression, and a fairly big one. | ||||||||||||||||||||||||||||||||||||||||||
| Comment by Roel Van de Paar [ 2023-02-14 ] | ||||||||||||||||||||||||||||||||||||||||||
|
Ran into this also
And for InnoDB:
| ||||||||||||||||||||||||||||||||||||||||||
| Comment by Marko Mäkelä [ 2023-08-24 ] | ||||||||||||||||||||||||||||||||||||||||||
|
If I understood it correctly, |