[MDEV-15250] UPSERT during ALTER-TABLE results in 'Duplicate entry' error for alter Created: 2018-02-08 Updated: 2023-10-13 Resolved: 2022-04-25 |
|
| Status: | Closed |
| Project: | MariaDB Server |
| Component/s: | Data Definition - Alter Table, Locking, Replication, Storage Engine - InnoDB |
| Affects Version/s: | 10.0, 10.1, 10.1.30, 10.2, 10.3, 10.4, 10.5, 10.6, 10.7, 10.8 |
| Fix Version/s: | 10.6.8, 10.7.4, 10.8.3, 10.9.1 |
| Type: | Bug | Priority: | Critical |
| Reporter: | sjon | Assignee: | Thirunarayanan Balathandayuthapani |
| Resolution: | Fixed | Votes: | 1 |
| Labels: | None | ||
| Issue Links: |
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Description |
|
I have a master that very frequently executes INSERT ON DUPLICATE KEY UPDATE. On a slave I executed ALTER TABLE xx row_format=COMPRESSED;, however this resulted in an error (the specific key is a UNIQUE) from the ALTER statement, which did not succeed: ERROR 1062 (23000): Duplicate entry 'xxx-xxx' for key 'xxx' I assume this is because it received an UPSERT while it was altering the table. I think this shouldn't happen as the alter-table should have a lock on the table. |
| Comments |
| Comment by Elena Stepanova [ 2018-03-07 ] |
|
Please provide SHOW CREATE TABLE for the table before and after ALTER, indicate what exactly UPDATE updates, and attach your config files. Thanks. |
| Comment by Marko Mäkelä [ 2021-11-12 ] |
|
I do not need a test case to confirm that this is a problem of my design of WL#5526 and WL#6255 in MySQL 5.6, affecting MariaDB 10.0 and later. The same issue was mentioned in |
| Comment by Marko Mäkelä [ 2021-11-12 ] |
|
The design problem is that currently, any DML operations that are being executed concurrently with an online index creation (MySQL WL#5526) or online table rebuild (MySQL WL#6625) will be logged immediately. For example, BEGIN;INSERT;ROLLBACK; will be logged as INSERT and DELETE. To prevent the ‘fake’ duplicates, we can simply write online_log on transaction commit. In that way, any duplicate key errors during online table rebuild will be filtered out from the online_log, because such duplicate key errors would also occur on the original table, leading to full or partial rollback of the transaction. That is, on transaction commit, we would check if any table in trx_t::mod_tables requires changes to be logged. If yes, we would scan the undo logs that the transaction generated, and write online_log to the affected tables during transaction commit. |
| Comment by Marko Mäkelä [ 2021-11-13 ] |
|
In secondary index creation (especially CREATE UNIQUE INDEX or ALTER TABLE…ADD UNIQUE INDEX) there is an additional phenomenon: A secondary index may be complete but not committed. That is, the online secondary index creation operation would wait for an exclusive metadata lock so that the operation can be committed. A conflicting metadata lock could be held by a transaction that is concurrently modifying the table. Such transactions will have to update the uncommitted index directly. Duplicate key errors must not be reported to the DML transaction if the unique index has not been committed yet. They are reported to the DDL transaction. Also such reporting is now premature and could lead to false duplicates. I think that we can apply changes to uncommitted indexes at transaction commit time. |
| Comment by Marko Mäkelä [ 2022-02-09 ] |
|
thiru, I hope that you can complete my prototype. I believe that fixing this may simplify the |
| Comment by Marko Mäkelä [ 2022-04-04 ] |
|
I posted the first batch of review comments. I did not yet thoroughly check all the new code in trx_t::apply_log(), especially the trx_undo_rec_info. Some source code comments would be very helpful in that area. |
| Comment by Thirunarayanan Balathandayuthapani [ 2022-04-17 ] |
|
| Comment by Marko Mäkelä [ 2022-04-22 ] |
|
Code coverage analysis looks better now. This is OK to push after a final round of testing by mleich. |
| Comment by Matthias Leich [ 2022-04-25 ] |
|
origin/bb-10.6- |