mirror of
https://github.com/MariaDB/server.git
synced 2025-08-12 05:21:37 +02:00
![]() Server-level UNIQUE constraints (namely, WITHOUT OVERLAPS and USING HASH) only worked with InnoDB in REPEATABLE READ isolation mode, when the constraint was checked first and then the row was inserted or updated. Gap locks prevented race conditions when a concurrent connection could've also checked the constraint and inserted/updated a row at the same time. In READ COMMITTED there are no gap locks. To avoid race conditions, we now check the constraint *after* the row operation. This is enabled by the HA_CHECK_UNIQUE_AFTER_WRITE table flag that InnoDB sets in the READ COMMITTED transactions. Checking the constraint after the row operation is more complex. First, the constraint will see the current (inserted/updated) row, and needs to skip it. Second, IGNORE operations become tricky, as we need to revert the insert/update and continue statement execution. write_row() (INSERT IGNORE) is reverted with delete_row(). Conveniently it deletes the current row, that is, the last inserted row. update_row(a,b) (UPDATE IGNORE) is reverted with a reversed update, update_row(b,a). Conveniently, it updates the current row too. Except in InnoDB when the PK is updated - in this case InnoDB internally performs delete+insert, but does not move the cursor, so the "current" row is the deleted one and the reverse update doesn't work. This combination now throws an "unsupported" error and will be fixed in MDEV-37233 |
||
---|---|---|
.. | ||
ha_innodb.cc | ||
ha_innodb.h | ||
handler0alter.cc | ||
i_s.cc | ||
i_s.h |