Skip to content

Commit 43ed0ba

Browse files
committed
Separate metrics table DDL from materialized view recreation
The DDL is purely metadata so cheap to execute, but still holds ACCESS EXCLUSIVE locks which block concurrent modifications. By splitting we prevent the MV recreation blocking the DDL unnecessarily. Signed-off-by: nscuro <nscuro@protonmail.com>
1 parent a224335 commit 43ed0ba

2 files changed

Lines changed: 182 additions & 183 deletions

File tree

migration/src/main/resources/org/dependencytrack/migration/V202606300916__add_kev_metrics.sql

Lines changed: 0 additions & 183 deletions
Original file line numberDiff line numberDiff line change
@@ -3,186 +3,3 @@ ALTER TABLE "DEPENDENCYMETRICS" ADD COLUMN IF NOT EXISTS "KEV" integer NOT NULL
33

44
-- squawk-ignore prefer-bigint-over-int
55
ALTER TABLE "PROJECTMETRICS" ADD COLUMN IF NOT EXISTS "KEV" integer NOT NULL DEFAULT 0;
6-
7-
DROP MATERIALIZED VIEW IF EXISTS "PORTFOLIOMETRICS_GLOBAL";
8-
9-
CREATE MATERIALIZED VIEW "PORTFOLIOMETRICS_GLOBAL" AS
10-
WITH retention AS (
11-
SELECT COALESCE(
12-
(
13-
SELECT "CONFIGPROPERTY"."PROPERTYVALUE"::INT AS "PROPERTYVALUE"
14-
FROM "CONFIGPROPERTY"
15-
WHERE "CONFIGPROPERTY"."GROUPNAME" = 'maintenance'
16-
AND "CONFIGPROPERTY"."PROPERTYNAME" = 'metrics.retention.days'
17-
),
18-
90
19-
) AS days
20-
),
21-
date_range AS (
22-
SELECT date_trunc('day', (CURRENT_DATE - ('1 day'::INTERVAL * (day.day)::DOUBLE PRECISION))) AS metrics_date
23-
FROM generate_series(0, GREATEST(((SELECT retention.days FROM retention) - 1), 0)) AS day(day)
24-
),
25-
latest_daily_project_metrics AS (
26-
SELECT date_range.metrics_date
27-
, latest_metrics."COMPONENTS"
28-
, latest_metrics."CRITICAL"
29-
, latest_metrics."FINDINGS_AUDITED"
30-
, latest_metrics."FINDINGS_TOTAL"
31-
, latest_metrics."FINDINGS_UNAUDITED"
32-
, latest_metrics."FIRST_OCCURRENCE"
33-
, latest_metrics."HIGH"
34-
, latest_metrics."KEV"
35-
, latest_metrics."RISKSCORE"
36-
, latest_metrics."LAST_OCCURRENCE"
37-
, latest_metrics."LOW"
38-
, latest_metrics."MEDIUM"
39-
, latest_metrics."POLICYVIOLATIONS_AUDITED"
40-
, latest_metrics."POLICYVIOLATIONS_FAIL"
41-
, latest_metrics."POLICYVIOLATIONS_INFO"
42-
, latest_metrics."POLICYVIOLATIONS_LICENSE_AUDITED"
43-
, latest_metrics."POLICYVIOLATIONS_LICENSE_TOTAL"
44-
, latest_metrics."POLICYVIOLATIONS_LICENSE_UNAUDITED"
45-
, latest_metrics."POLICYVIOLATIONS_OPERATIONAL_AUDITED"
46-
, latest_metrics."POLICYVIOLATIONS_OPERATIONAL_TOTAL"
47-
, latest_metrics."POLICYVIOLATIONS_OPERATIONAL_UNAUDITED"
48-
, latest_metrics."POLICYVIOLATIONS_SECURITY_AUDITED"
49-
, latest_metrics."POLICYVIOLATIONS_SECURITY_TOTAL"
50-
, latest_metrics."POLICYVIOLATIONS_SECURITY_UNAUDITED"
51-
, latest_metrics."POLICYVIOLATIONS_TOTAL"
52-
, latest_metrics."POLICYVIOLATIONS_UNAUDITED"
53-
, latest_metrics."POLICYVIOLATIONS_WARN"
54-
, latest_metrics."PROJECT_ID"
55-
, latest_metrics."SUPPRESSED"
56-
, latest_metrics."UNASSIGNED_SEVERITY"
57-
, latest_metrics."VULNERABILITIES"
58-
, latest_metrics."VULNERABLECOMPONENTS"
59-
FROM date_range
60-
LEFT JOIN LATERAL (
61-
SELECT DISTINCT ON (pm."PROJECT_ID")
62-
pm."COMPONENTS"
63-
, pm."CRITICAL"
64-
, pm."FINDINGS_AUDITED"
65-
, pm."FINDINGS_TOTAL"
66-
, pm."FINDINGS_UNAUDITED"
67-
, pm."FIRST_OCCURRENCE"
68-
, pm."HIGH"
69-
, pm."KEV"
70-
, pm."RISKSCORE"
71-
, pm."LAST_OCCURRENCE"
72-
, pm."LOW"
73-
, pm."MEDIUM"
74-
, pm."POLICYVIOLATIONS_AUDITED"
75-
, pm."POLICYVIOLATIONS_FAIL"
76-
, pm."POLICYVIOLATIONS_INFO"
77-
, pm."POLICYVIOLATIONS_LICENSE_AUDITED"
78-
, pm."POLICYVIOLATIONS_LICENSE_TOTAL"
79-
, pm."POLICYVIOLATIONS_LICENSE_UNAUDITED"
80-
, pm."POLICYVIOLATIONS_OPERATIONAL_AUDITED"
81-
, pm."POLICYVIOLATIONS_OPERATIONAL_TOTAL"
82-
, pm."POLICYVIOLATIONS_OPERATIONAL_UNAUDITED"
83-
, pm."POLICYVIOLATIONS_SECURITY_AUDITED"
84-
, pm."POLICYVIOLATIONS_SECURITY_TOTAL"
85-
, pm."POLICYVIOLATIONS_SECURITY_UNAUDITED"
86-
, pm."POLICYVIOLATIONS_TOTAL"
87-
, pm."POLICYVIOLATIONS_UNAUDITED"
88-
, pm."POLICYVIOLATIONS_WARN"
89-
, pm."PROJECT_ID"
90-
, pm."SUPPRESSED"
91-
, pm."UNASSIGNED_SEVERITY"
92-
, pm."VULNERABILITIES"
93-
, pm."VULNERABLECOMPONENTS"
94-
FROM "PROJECT" p
95-
JOIN "PROJECTMETRICS" pm
96-
ON pm."PROJECT_ID" = p."ID"
97-
AND p."INACTIVE_SINCE" IS NULL
98-
AND p."COLLECTION_LOGIC" IS NULL
99-
WHERE pm."LAST_OCCURRENCE" < (date_range.metrics_date + '1 day'::INTERVAL)
100-
AND pm."LAST_OCCURRENCE" >= (date_range.metrics_date - '1 day'::INTERVAL)
101-
ORDER BY pm."PROJECT_ID"
102-
, pm."LAST_OCCURRENCE" DESC
103-
) latest_metrics ON (true)
104-
),
105-
daily_metrics AS (
106-
SELECT count(DISTINCT latest_daily_project_metrics."PROJECT_ID") AS projects
107-
, sum(latest_daily_project_metrics."COMPONENTS") AS components
108-
, sum(latest_daily_project_metrics."CRITICAL") AS critical
109-
, latest_daily_project_metrics.metrics_date
110-
, sum(latest_daily_project_metrics."FINDINGS_AUDITED") AS findings_audited
111-
, sum(latest_daily_project_metrics."FINDINGS_TOTAL") AS findings_total
112-
, sum(latest_daily_project_metrics."FINDINGS_UNAUDITED") AS findings_unaudited
113-
, sum(latest_daily_project_metrics."HIGH") AS high
114-
, sum(latest_daily_project_metrics."KEV") AS kev
115-
, sum(latest_daily_project_metrics."RISKSCORE") AS inherited_risk_score
116-
, sum(latest_daily_project_metrics."LOW") AS low
117-
, sum(latest_daily_project_metrics."MEDIUM") AS medium
118-
, sum(latest_daily_project_metrics."POLICYVIOLATIONS_AUDITED") AS policy_violations_audited
119-
, sum(latest_daily_project_metrics."POLICYVIOLATIONS_FAIL") AS policy_violations_fail
120-
, sum(latest_daily_project_metrics."POLICYVIOLATIONS_INFO") AS policy_violations_info
121-
, sum(latest_daily_project_metrics."POLICYVIOLATIONS_LICENSE_AUDITED") AS policy_violations_license_audited
122-
, sum(latest_daily_project_metrics."POLICYVIOLATIONS_LICENSE_TOTAL") AS policy_violations_license_total
123-
, sum(latest_daily_project_metrics."POLICYVIOLATIONS_LICENSE_UNAUDITED") AS policy_violations_license_unaudited
124-
, sum(latest_daily_project_metrics."POLICYVIOLATIONS_OPERATIONAL_AUDITED") AS policy_violations_operational_audited
125-
, sum(latest_daily_project_metrics."POLICYVIOLATIONS_OPERATIONAL_TOTAL") AS policy_violations_operational_total
126-
, sum(latest_daily_project_metrics."POLICYVIOLATIONS_OPERATIONAL_UNAUDITED") AS policy_violations_operational_unaudited
127-
, sum(latest_daily_project_metrics."POLICYVIOLATIONS_SECURITY_AUDITED") AS policy_violations_security_audited
128-
, sum(latest_daily_project_metrics."POLICYVIOLATIONS_SECURITY_TOTAL") AS policy_violations_security_total
129-
, sum(latest_daily_project_metrics."POLICYVIOLATIONS_SECURITY_UNAUDITED") AS policy_violations_security_unaudited
130-
, sum(latest_daily_project_metrics."POLICYVIOLATIONS_TOTAL") AS policy_violations_total
131-
, sum(latest_daily_project_metrics."POLICYVIOLATIONS_UNAUDITED") AS policy_violations_unaudited
132-
, sum(latest_daily_project_metrics."POLICYVIOLATIONS_WARN") AS policy_violations_warn
133-
, sum(latest_daily_project_metrics."SUPPRESSED") AS suppressed
134-
, sum(latest_daily_project_metrics."UNASSIGNED_SEVERITY") AS unassigned
135-
, sum(latest_daily_project_metrics."VULNERABILITIES") AS vulnerabilities
136-
, sum(latest_daily_project_metrics."VULNERABLECOMPONENTS") AS vulnerable_components
137-
, sum(
138-
CASE
139-
WHEN latest_daily_project_metrics."VULNERABLECOMPONENTS" > 0
140-
THEN 1
141-
ELSE 0
142-
END
143-
) AS vulnerable_projects
144-
FROM latest_daily_project_metrics
145-
GROUP BY latest_daily_project_metrics.metrics_date
146-
)
147-
SELECT COALESCE(dm.components, (0)::bigint) AS "COMPONENTS"
148-
, COALESCE(dm.critical, (0)::bigint) AS "CRITICAL"
149-
, COALESCE(dm.findings_audited, (0)::bigint) AS "FINDINGS_AUDITED"
150-
, COALESCE(dm.findings_total, (0)::bigint) AS "FINDINGS_TOTAL"
151-
, COALESCE(dm.findings_unaudited, (0)::bigint) AS "FINDINGS_UNAUDITED"
152-
, date_range.metrics_date AS "FIRST_OCCURRENCE"
153-
, COALESCE(dm.high, (0)::bigint) AS "HIGH"
154-
, COALESCE(dm.kev, (0)::bigint) AS "KEV"
155-
, COALESCE(dm.inherited_risk_score, (0)::double precision) AS "INHERITED_RISK_SCORE"
156-
, date_range.metrics_date AS "LAST_OCCURRENCE"
157-
, COALESCE(dm.low, (0)::bigint) AS "LOW"
158-
, COALESCE(dm.medium, (0)::bigint) AS "MEDIUM"
159-
, COALESCE(dm.policy_violations_audited, (0)::bigint) AS "POLICY_VIOLATIONS_AUDITED"
160-
, COALESCE(dm.policy_violations_fail, (0)::bigint) AS "POLICY_VIOLATIONS_FAIL"
161-
, COALESCE(dm.policy_violations_info, (0)::bigint) AS "POLICY_VIOLATIONS_INFO"
162-
, COALESCE(dm.policy_violations_license_audited, (0)::bigint) AS "POLICY_VIOLATIONS_LICENSE_AUDITED"
163-
, COALESCE(dm.policy_violations_license_total, (0)::bigint) AS "POLICY_VIOLATIONS_LICENSE_TOTAL"
164-
, COALESCE(dm.policy_violations_license_unaudited, (0)::bigint) AS "POLICY_VIOLATIONS_LICENSE_UNAUDITED"
165-
, COALESCE(dm.policy_violations_operational_audited, (0)::bigint) AS "POLICY_VIOLATIONS_OPERATIONAL_AUDITED"
166-
, COALESCE(dm.policy_violations_operational_total, (0)::bigint) AS "POLICY_VIOLATIONS_OPERATIONAL_TOTAL"
167-
, COALESCE(dm.policy_violations_operational_unaudited, (0)::bigint) AS "POLICY_VIOLATIONS_OPERATIONAL_UNAUDITED"
168-
, COALESCE(dm.policy_violations_security_audited, (0)::bigint) AS "POLICY_VIOLATIONS_SECURITY_AUDITED"
169-
, COALESCE(dm.policy_violations_security_total, (0)::bigint) AS "POLICY_VIOLATIONS_SECURITY_TOTAL"
170-
, COALESCE(dm.policy_violations_security_unaudited, (0)::bigint) AS "POLICY_VIOLATIONS_SECURITY_UNAUDITED"
171-
, COALESCE(dm.policy_violations_total, (0)::bigint) AS "POLICY_VIOLATIONS_TOTAL"
172-
, COALESCE(dm.policy_violations_unaudited, (0)::bigint) AS "POLICY_VIOLATIONS_UNAUDITED"
173-
, COALESCE(dm.policy_violations_warn, (0)::bigint) AS "POLICY_VIOLATIONS_WARN"
174-
, COALESCE(dm.projects, (0)::bigint) AS "PROJECTS"
175-
, COALESCE(dm.suppressed, (0)::bigint) AS "SUPPRESSED"
176-
, COALESCE(dm.unassigned, (0)::bigint) AS "UNASSIGNED"
177-
, COALESCE(dm.vulnerabilities, (0)::bigint) AS "VULNERABILITIES"
178-
, COALESCE(dm.vulnerable_components, (0)::bigint) AS "VULNERABLE_COMPONENTS"
179-
, COALESCE(dm.vulnerable_projects, (0)::bigint) AS "VULNERABLE_PROJECTS"
180-
FROM date_range
181-
LEFT JOIN daily_metrics dm
182-
ON date_range.metrics_date = dm.metrics_date
183-
WITH NO DATA;
184-
185-
-- squawk-ignore require-concurrent-index-creation
186-
CREATE UNIQUE INDEX IF NOT EXISTS "PORTFOLIOMETRICS_GLOBAL_LAST_OCCURRENCE_IDX" ON "PORTFOLIOMETRICS_GLOBAL" USING btree ("LAST_OCCURRENCE");
187-
188-
REFRESH MATERIALIZED VIEW "PORTFOLIOMETRICS_GLOBAL";

0 commit comments

Comments
 (0)