Skip to content

postgres: alias insertion deadlock#1891

Open
hdonnay wants to merge 3 commits into
quay:mainfrom
hdonnay:bug/sql-concurrent-alias
Open

postgres: alias insertion deadlock#1891
hdonnay wants to merge 3 commits into
quay:mainfrom
hdonnay:bug/sql-concurrent-alias

Conversation

@hdonnay

@hdonnay hdonnay commented May 21, 2026

Copy link
Copy Markdown
Member

This fixes a transaction conflict where concurrent updaters could attempt to insert the same alias namespaces and cause the entire update to abort.

@hdonnay
hdonnay requested a review from crozzy May 21, 2026 00:25
@hdonnay
hdonnay force-pushed the bug/sql-concurrent-alias branch 2 times, most recently from b8d0c0b to da65def Compare May 27, 2026 19:49
@hdonnay
hdonnay force-pushed the bug/sql-concurrent-alias branch from da65def to a43e074 Compare May 28, 2026 18:46
@hdonnay
hdonnay force-pushed the bug/sql-concurrent-alias branch 2 times, most recently from 136e223 to 5928a1b Compare May 29, 2026 15:38
@crozzy

crozzy commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

This appears to stop the deadlocks but causes the time to insert to increase considerably. Since we are inserting the aliases and namespaces outside of the transaction (so IIUC deadlocking is not an issue), would it be possible to collect all the aliases to be inserted using the dedupe maps that already exist and fire two bulk statements for the alias and the namespace?

@hdonnay

hdonnay commented Jun 25, 2026

Copy link
Copy Markdown
Member Author

I'll take a look and try structuring it that way.

@hdonnay
hdonnay force-pushed the bug/sql-concurrent-alias branch 2 times, most recently from 96286f2 to 25bd69e Compare July 15, 2026 19:33
@hdonnay

hdonnay commented Jul 15, 2026

Copy link
Copy Markdown
Member Author

I've integrated the changes in #1934 and crozzy#89 here. I've kept the authorship correct as best I could.

@hdonnay
hdonnay marked this pull request as ready for review July 15, 2026 19:40
@hdonnay
hdonnay requested review from a team as code owners July 15, 2026 19:40
@hdonnay
hdonnay force-pushed the bug/sql-concurrent-alias branch 2 times, most recently from 020f257 to 428280d Compare July 15, 2026 20:09
@hdonnay
hdonnay requested a review from jvdm July 16, 2026 18:01

@jvdm jvdm left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we pull TestConcurrentUpdateVulnerabilities from #1934 which seems to test the deadlock?

Also, looks like this does not have the self alias fields on the test vulns in TestGetLatestVulnerabilities that #1934 added. Without the self fields, bulkLinkSelf is never exercised: no self set, vsHashKinds stays empty and the bulkLinkSelf statement never runs.

@hdonnay

hdonnay commented Jul 17, 2026

Copy link
Copy Markdown
Member Author

I removed that test because it didn't work; I could never get it to trip. The other changes to the tests were unintentional, I'll pull those back.

hdonnay and others added 3 commits July 16, 2026 19:43
This fixes a transaction conflict where concurrent updaters could
attempt to insert the same alias namespaces and cause the entire update
to abort.

Signed-off-by: Hank Donnay <hdonnay@redhat.com>
Change-Id: I4f7f613f17e47c7cbcff82fbbb7674a06a6a6964
Replace the per-vulnerability insertVulnerabilityAliases and
insertSelfAlias batch queries -- each of which did a hash-lookup
subquery against the vuln table -- with two single bulk INSERT
statements that use unnest() + JOIN to link all vulnerabilities
to their aliases and self-references in one pass.

The flattened (hash_kind, hash, alias_space, alias_name) arrays
accumulated during the vuln iteration are comparable in size to
the arrays already built by the insertAliases pre-pass, so memory
usage does not grow significantly relative to what was already held.

For VEX with a 2-year lookback (~1.1M vulns), this reduces the
alias-linking phase from timing out at 30 minutes to ~43 seconds.

Signed-off-by: crozzy <joseph.crosland@gmail.com>
Change-Id: Icc408d5593c3eca5832ca32a72fe65f86a6a6964
This fixes a bug where `insertAliases` consumes the single-pass
`vulnIter` (backed by `jsonblob.RecordIter`) before the main
vulnerability insertion loop runs, resulting in zero vuln rows being
inserted.

The fix removes the separate `insertAliases` pre-pass and instead
collects alias namespaces and aliases during the main `vulnIter` loop,
then bulk-inserts them via a separate connection (outside the
transaction) after the loop -- preserving the deadlock-avoidance
property.

Also adds a test using a `sync.Once`-guarded single-pass iterator that
reproduces the bug.

Signed-off-by: Hank Donnay <hdonnay@redhat.com>
Change-Id: I764435cfde1f62b7492dc056824e8b606a6a6964
@hdonnay
hdonnay force-pushed the bug/sql-concurrent-alias branch from 428280d to 40ee906 Compare July 17, 2026 00:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

3 participants