[MDEV-29181] Potential corruption on Foreign key update on a table with vcol index Created: 2022-07-27 Updated: 2024-01-03 |
|
| Status: | In Review |
| Project: | MariaDB Server |
| Component/s: | Storage Engine - InnoDB, Virtual Columns |
| Affects Version/s: | None |
| Fix Version/s: | 10.5, 10.6, 10.11, 11.0 |
| Type: | Bug | Priority: | Critical |
| Reporter: | Nikita Malyavin | Assignee: | Sergei Golubchik |
| Resolution: | Unresolved | Votes: | 1 |
| Labels: | None | ||
| Issue Links: |
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Description |
|
I have added an assertion to ensure that the correct table is chosen in innodb_find_table_for_vc:
This is important, since the table is thread-local data. The above assertion fails with the following test:
I believe we need enough rows to have more that one leaf page in the tree, to avoid a row lock timeout. The best way to fix it is to put mysql_table to a threadlocal data as well. A good place can be row_prebuilt_t (and table is already there): to access child prebuilt, parent prebuilt should contain references to it, we can fill it on open under certain conditions, or on demand |
| Comments |
| Comment by Nikita Malyavin [ 2022-08-09 ] | ||||||||||||||||||||||||
|
I have implemented the solution on the innodb side, based on row_prebuilt_t. I feel unsatisfied of this, given how much effort it required to make a solution that passes current tests. Many corner cases were there, especially the interesting fact I wasn't aware about, that prebuilt and handler remain open is tc instance is still cached. This may affect the maintainance cost later, especially given that 10.11 is LTS, and it is likely that new FOREIGN KEYs implementation will be finished in 2023. So I'm thinking of a simpler solution easier to maintain partially made on sql side. | ||||||||||||||||||||||||
| Comment by Nikita Malyavin [ 2022-08-22 ] | ||||||||||||||||||||||||
|
A new solution is implemented in a simpler way, by extending TABLE_LIST class. | ||||||||||||||||||||||||
| Comment by Nikita Malyavin [ 2022-08-22 ] | ||||||||||||||||||||||||
|
serg marko The solution requres the review from both innodb and runtime sides. Note that it can be merged to 10.3 and 10.4 only after MDEV-26951 is done. 10.10 version is here Since innodb_find_table_for_vc is no longer called for foreign keys (only akcground thead can need it in some cases), only non-deterministic test is possible, I have added it as a separate commit. | ||||||||||||||||||||||||
| Comment by Marko Mäkelä [ 2022-08-23 ] | ||||||||||||||||||||||||
|
I think that a new debug instrumentation dependent test needs to be created:
The InnoDB changes look OK to me, except that the upd_node_t::prebuilt needs to be documented better. The comments must say that essentially, row_create_update_node_for_mysql() is passing a parameter to row_upd_check_references_constraints(). Can that parameter be a pointer to const? Some code changes mix TABs and spaces. Some comments say MySQL instead of MariaDB. This will have to be extensively stress-tested before being pushed to a main branch. | ||||||||||||||||||||||||
| Comment by Nikita Malyavin [ 2022-08-23 ] | ||||||||||||||||||||||||
It can be done for an upd_node_t field, but doesn't lie so nasty for an argument passed in functions row_ins_check_foreign_constraint and row_ins_foreign_check_on_constraint, because I modify prebuilt->index to match clust_index in processing online changes in 10.11. This can be done differently, though, but doubt it's worth it. I also can do it consts for 10.3-10.10, and leave them mutable in 10.11.
No, just forgot to remove the reset line.
In ha_innodb.h? It was just a move from private zone to public. But yes, can be updated, too. The branch is updated, you can see the changes (except for the test, I've deleted the just like in-place there) in this commit | ||||||||||||||||||||||||
| Comment by Nikita Malyavin [ 2022-11-02 ] | ||||||||||||||||||||||||
|
RQG testing reported a crash (by mleich)
| ||||||||||||||||||||||||
| Comment by Matthias Leich [ 2022-11-04 ] | ||||||||||||||||||||||||
|
| ||||||||||||||||||||||||
| Comment by Nikita Malyavin [ 2022-11-11 ] | ||||||||||||||||||||||||
|
TBR-1621 demonstrated a flaw against not locked parent table of the ADDed FK. The fix is to prelock this table. This was already done by Svoj in The vulnerability for DROP was also existed, but a way to fix it without additional prelocking was found. https://github.com/MariaDB/server/commit/57f69f307f47152aa6db54e7dac9c4549f5ac68c | ||||||||||||||||||||||||
| Comment by Matthias Leich [ 2023-01-17 ] | ||||||||||||||||||||||||
|
origin/bb-10.6-MDEV-29181 332ca90e4e796c82733f9fcdd3bba7b9b7541d64 2023-01-12T17:48:32+03:00 | ||||||||||||||||||||||||
| Comment by Marko Mäkelä [ 2023-01-26 ] | ||||||||||||||||||||||||
|
I can’t find anything wrong with the algorithm here. The branch for testing included also MDEV-30103, which I think goes need some more work, and MDEV-30021, which looks OK to me. I only have a coding style comment: It would be good to declare maria_table_to_prebuilt() in ha_prototypes.h, define it in ha_innodb.cc and avoid including ha_innodb.h in low-level source files. OK to push after addressing this. | ||||||||||||||||||||||||
| Comment by Marko Mäkelä [ 2023-07-28 ] | ||||||||||||||||||||||||
|
I am not sure if this would fix the following failure related to FOREIGN KEY checks, or if it would be something else, such as MDEV-30103:
That is, the ALTER TABLE test.t8_p is trying to evict the data dictionary object that the INSERT INTO test.t8_c is accessing, to see if an insert into a child table is allowed by the existence of the parent table. When I implemented | ||||||||||||||||||||||||
| Comment by Marko Mäkelä [ 2023-09-20 ] | ||||||||||||||||||||||||
|
As part of applying this fix, please re-enable the test gcol.innodb_virtual_fk and ensure that it is stable. |