Skip to content

Commit 90ecb35

Browse files
committed
RHINENG-20474: order advisories to avoid deadlock
fixing: {"@timestamp":"2025-09-11T03:36:30.914Z","err":"unable to process upload\nsaving system into the database: Unable to save or update system in database: unable to update system_platform: fatal error restarting pod\ndatabase error\nERROR: deadlock detected (SQLSTATE 40P01)","level":"panic","message":"Handler failed"}
1 parent 1afc4be commit 90ecb35

3 files changed

Lines changed: 97 additions & 1 deletion

File tree

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
CREATE OR REPLACE FUNCTION on_system_update()
2+
-- this trigger updates advisory_account_data when server changes its stale flag
3+
RETURNS TRIGGER
4+
AS
5+
$system_update$
6+
DECLARE
7+
was_counted BOOLEAN;
8+
should_count BOOLEAN;
9+
change INT;
10+
BEGIN
11+
-- Ignore not yet evaluated systems
12+
IF TG_OP != 'UPDATE' OR NEW.last_evaluation IS NULL THEN
13+
RETURN NEW;
14+
END IF;
15+
16+
was_counted := OLD.stale = FALSE;
17+
should_count := NEW.stale = FALSE;
18+
19+
-- Determine what change we are performing
20+
IF was_counted and NOT should_count THEN
21+
change := -1;
22+
ELSIF NOT was_counted AND should_count THEN
23+
change := 1;
24+
ELSE
25+
-- No change
26+
RETURN NEW;
27+
END IF;
28+
29+
-- insert/update advisories linked to the server
30+
INSERT
31+
INTO advisory_account_data (advisory_id, rh_account_id, systems_installable, systems_applicable)
32+
SELECT sa.advisory_id, NEW.rh_account_id,
33+
case when sa.status_id = 0 then change else 0 end as systems_installable,
34+
change as systems_applicable
35+
FROM system_advisories sa
36+
WHERE sa.system_id = NEW.id AND sa.rh_account_id = NEW.rh_account_id
37+
ON CONFLICT (advisory_id, rh_account_id) DO UPDATE
38+
SET systems_installable = advisory_account_data.systems_installable + EXCLUDED.systems_installable,
39+
systems_applicable = advisory_account_data.systems_applicable + EXCLUDED.systems_applicable;
40+
RETURN NEW;
41+
END;
42+
$system_update$ LANGUAGE plpgsql;
43+
44+
SELECT create_table_partition_triggers('system_platform_on_update',
45+
$$AFTER UPDATE$$,
46+
'system_platform',
47+
$$FOR EACH ROW EXECUTE PROCEDURE on_system_update()$$);
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
CREATE OR REPLACE FUNCTION on_system_update()
2+
-- this trigger updates advisory_account_data when server changes its stale flag
3+
RETURNS TRIGGER
4+
AS
5+
$system_update$
6+
DECLARE
7+
was_counted BOOLEAN;
8+
should_count BOOLEAN;
9+
change INT;
10+
BEGIN
11+
-- Ignore not yet evaluated systems
12+
IF TG_OP != 'UPDATE' OR NEW.last_evaluation IS NULL THEN
13+
RETURN NEW;
14+
END IF;
15+
16+
was_counted := OLD.stale = FALSE;
17+
should_count := NEW.stale = FALSE;
18+
19+
-- Determine what change we are performing
20+
IF was_counted and NOT should_count THEN
21+
change := -1;
22+
ELSIF NOT was_counted AND should_count THEN
23+
change := 1;
24+
ELSE
25+
-- No change
26+
RETURN NEW;
27+
END IF;
28+
29+
-- insert/update advisories linked to the server
30+
INSERT
31+
INTO advisory_account_data (advisory_id, rh_account_id, systems_installable, systems_applicable)
32+
SELECT sa.advisory_id, NEW.rh_account_id,
33+
case when sa.status_id = 0 then change else 0 end as systems_installable,
34+
change as systems_applicable
35+
FROM system_advisories sa
36+
WHERE sa.system_id = NEW.id AND sa.rh_account_id = NEW.rh_account_id
37+
ORDER BY sa.advisory_id
38+
ON CONFLICT (advisory_id, rh_account_id) DO UPDATE
39+
SET systems_installable = advisory_account_data.systems_installable + EXCLUDED.systems_installable,
40+
systems_applicable = advisory_account_data.systems_applicable + EXCLUDED.systems_applicable;
41+
RETURN NEW;
42+
END;
43+
$system_update$ LANGUAGE plpgsql;
44+
45+
SELECT create_table_partition_triggers('system_platform_on_update',
46+
$$AFTER UPDATE$$,
47+
'system_platform',
48+
$$FOR EACH ROW EXECUTE PROCEDURE on_system_update()$$);

database_admin/schema/create_schema.sql

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ CREATE TABLE IF NOT EXISTS schema_migrations
77

88

99
INSERT INTO schema_migrations
10-
VALUES (136, false);
10+
VALUES (137, false);
1111

1212
-- ---------------------------------------------------------------------------
1313
-- Functions
@@ -102,6 +102,7 @@ BEGIN
102102
change as systems_applicable
103103
FROM system_advisories sa
104104
WHERE sa.system_id = NEW.id AND sa.rh_account_id = NEW.rh_account_id
105+
ORDER BY sa.advisory_id
105106
ON CONFLICT (advisory_id, rh_account_id) DO UPDATE
106107
SET systems_installable = advisory_account_data.systems_installable + EXCLUDED.systems_installable,
107108
systems_applicable = advisory_account_data.systems_applicable + EXCLUDED.systems_applicable;

0 commit comments

Comments
 (0)