-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[#24701] YSQL: Always fetch wholerow attribute in non-fast path UPDATEs
Summary: PG in commit 86dc90056dfdbd9d1b891718d2e5614e3e432f35 reworked the UPDATE node's execution to get only the updated and junk columns from its child node. It (the UPDATE node) then fetches the existing "old" tuple and merges it with the output of the child node to construct the new tuple. This led to performance degradation in Yugabyte because: - Before this change, the UPDATE node sent only write operations that could be buffered (with some restrictions) and batch executed. - With this change, the UPDATE node sent a read followed by a write operation per row, triggering 2 RPCs per row. YB commit cf176f4 / D31673 addressed the above problem by sending the old tuple as "wholerow" junk attribute to the UPDATE node. With this, the read operation inside the UPDATE node to fetch the old tuple was no longer required. While this approach was correct, it made the following mistakes: - Justification: Citing a `failed to fetch tuple being updated`, it claimed that performing read inside the UPDATE node has a correctness issue that materializes only in Yugabyte (see D31673's summary for details). That claim was incorrect. This issue could have been resolved by using the correct `in_txn_limit`. (Skipping the details here as that approach is not being taken anyway). - Over-optimization: YB does not need the old tuple in some cases. So, it tried to fetch the wholerow attribute only when necessary. While doing so, it missed (at least) one case: when a subset of foreign key columns are updated. Fetching the old row is necessary to check for foreign key violations in this case correctly. Consider: ``` CREATE TABLE pk(a INT, b INT, PRIMARY KEY (a, b)); CREATE TABLE fk(a INT, b INT, FOREIGN KEY(a, b) REFERENCES pk); INSERT INTO pk VALUES (1, 1); INSERT INTO fk VALUES (1, 1); UPDATE fk set a = a + 1; -- should fail due to foreign key violation ``` Without the old tuple, during the UPDATE operation, the only tuple present in the relation becomes (a = 2, b = null). Consequently, the foreign key violation is not thrown. There can potentially be more cases where not fetching the wholerow can lead to incorrect results. Moreover, in most cases, the old tuple is needed anyway. This revision removes this optimization and fetches the wholerow attribute in all non-fast path UPDATEs. Jira: DB-13777 Test Plan: ./yb_build.sh --java-test org.yb.pgsql.TestPgRegressForeignKey Reviewers: amartsinchyk, kramanathan Reviewed By: amartsinchyk Subscribers: yql Differential Revision: https://phorge.dev.yugabyte.com/D40671
- Loading branch information
Showing
17 changed files
with
136 additions
and
204 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.