Skip to content

Commit 142f483

Browse files
committed
RHINENG-20474: simplify trigger on system_platform
the trigger creates lock on advisory_account_table faster trigger means less time spent in lock
1 parent 67166fe commit 142f483

3 files changed

Lines changed: 130 additions & 36 deletions

File tree

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
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+
-- find advisories linked to the server
30+
WITH to_update_advisories AS (
31+
SELECT aad.advisory_id,
32+
aad.rh_account_id,
33+
case when sa.status_id = 0 then change else 0 end as systems_installable_change,
34+
change as systems_applicable_change
35+
FROM advisory_account_data aad
36+
JOIN system_advisories sa ON aad.advisory_id = sa.advisory_id
37+
-- Filter advisory_account_data only for advisories affectign this system & belonging to system account
38+
WHERE aad.rh_account_id = NEW.rh_account_id
39+
AND sa.system_id = NEW.id AND sa.rh_account_id = NEW.rh_account_id
40+
ORDER BY aad.advisory_id),
41+
-- update existing rows
42+
update AS (
43+
UPDATE advisory_account_data aad
44+
SET systems_installable = aad.systems_installable + ta.systems_installable_change,
45+
systems_applicable = aad.systems_applicable + ta.systems_applicable_change
46+
FROM to_update_advisories ta
47+
WHERE aad.advisory_id = ta.advisory_id
48+
AND aad.rh_account_id = NEW.rh_account_id
49+
)
50+
-- If we have system affected && no exisiting advisory_account_data entry, we insert new rows
51+
INSERT
52+
INTO advisory_account_data (advisory_id, rh_account_id, systems_installable, systems_applicable)
53+
SELECT sa.advisory_id, NEW.rh_account_id,
54+
case when sa.status_id = 0 then 1 else 0 end as systems_installable,
55+
1 as systems_applicable
56+
FROM system_advisories sa
57+
WHERE sa.system_id = NEW.id AND sa.rh_account_id = NEW.rh_account_id
58+
AND change > 0
59+
-- create only rows which are not already in to_update_advisories
60+
AND (NEW.rh_account_id, sa.advisory_id) NOT IN (
61+
SELECT ta.rh_account_id, ta.advisory_id
62+
FROM to_update_advisories ta
63+
)
64+
ON CONFLICT (advisory_id, rh_account_id) DO UPDATE
65+
SET systems_installable = advisory_account_data.systems_installable + EXCLUDED.systems_installable,
66+
systems_applicable = advisory_account_data.systems_applicable + EXCLUDED.systems_applicable;
67+
RETURN NEW;
68+
END;
69+
$system_update$ LANGUAGE plpgsql;
70+
71+
SELECT create_table_partition_triggers('system_platform_on_update',
72+
$$AFTER UPDATE$$,
73+
'system_platform',
74+
$$FOR EACH ROW EXECUTE PROCEDURE on_system_update()$$);
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()$$);

database_admin/schema/create_schema.sql

Lines changed: 9 additions & 36 deletions
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 (133, false);
10+
VALUES (134, false);
1111

1212
-- ---------------------------------------------------------------------------
1313
-- Functions
@@ -107,44 +107,17 @@ BEGIN
107107
RETURN NEW;
108108
END IF;
109109

110-
-- find advisories linked to the server
111-
WITH to_update_advisories AS (
112-
SELECT aad.advisory_id,
113-
aad.rh_account_id,
114-
case when sa.status_id = 0 then change else 0 end as systems_installable_change,
115-
change as systems_applicable_change
116-
FROM advisory_account_data aad
117-
JOIN system_advisories sa ON aad.advisory_id = sa.advisory_id
118-
-- Filter advisory_account_data only for advisories affectign this system & belonging to system account
119-
WHERE aad.rh_account_id = NEW.rh_account_id
120-
AND sa.system_id = NEW.id AND sa.rh_account_id = NEW.rh_account_id
121-
ORDER BY aad.advisory_id),
122-
-- update existing rows
123-
update AS (
124-
UPDATE advisory_account_data aad
125-
SET systems_installable = aad.systems_installable + ta.systems_installable_change,
126-
systems_applicable = aad.systems_applicable + ta.systems_applicable_change
127-
FROM to_update_advisories ta
128-
WHERE aad.advisory_id = ta.advisory_id
129-
AND aad.rh_account_id = NEW.rh_account_id
130-
)
131-
-- If we have system affected && no exisiting advisory_account_data entry, we insert new rows
110+
-- insert/update advisories linked to the server
132111
INSERT
133112
INTO advisory_account_data (advisory_id, rh_account_id, systems_installable, systems_applicable)
134113
SELECT sa.advisory_id, NEW.rh_account_id,
135-
case when sa.status_id = 0 then 1 else 0 end as systems_installable,
136-
1 as systems_applicable
137-
FROM system_advisories sa
138-
WHERE sa.system_id = NEW.id AND sa.rh_account_id = NEW.rh_account_id
139-
AND change > 0
140-
-- create only rows which are not already in to_update_advisories
141-
AND (NEW.rh_account_id, sa.advisory_id) NOT IN (
142-
SELECT ta.rh_account_id, ta.advisory_id
143-
FROM to_update_advisories ta
144-
)
145-
ON CONFLICT (advisory_id, rh_account_id) DO UPDATE
146-
SET systems_installable = advisory_account_data.systems_installable + EXCLUDED.systems_installable,
147-
systems_applicable = advisory_account_data.systems_applicable + EXCLUDED.systems_applicable;
114+
case when sa.status_id = 0 then change else 0 end as systems_installable,
115+
change as systems_applicable
116+
FROM system_advisories sa
117+
WHERE sa.system_id = NEW.id AND sa.rh_account_id = NEW.rh_account_id
118+
ON CONFLICT (advisory_id, rh_account_id) DO UPDATE
119+
SET systems_installable = advisory_account_data.systems_installable + EXCLUDED.systems_installable,
120+
systems_applicable = advisory_account_data.systems_applicable + EXCLUDED.systems_applicable;
148121
RETURN NEW;
149122
END;
150123
$system_update$ LANGUAGE plpgsql;

0 commit comments

Comments
 (0)