Skip to content

Remove orphaned Vulnerabilities::Feedback records

What does this MR do and why?

This MR schedules a background migration to remove rows from vulnerability_feedback table that have no corresponding rows in vulnerability_occurrences table.

Related to #372251 (closed)

Database review

Total records count

Total count: 380 282

Total records affected

Rows without matching uuid

Count: 106724

SELECT COUNT(v_f.finding_uuid)
FROM vulnerability_feedback v_f
LEFT JOIN vulnerability_occurrences v_o
ON v_f.finding_uuid = v_o.uuid::uuid
WHERE v_o.uuid IS NULL
AND v_f.finding_uuid IS NOT NULL;

Rows without matching project_fingerprint

Count: 7638

SELECT COUNT(*)
FROM vulnerability_feedback v_f
LEFT JOIN vulnerability_occurrences v_o
ON v_f.project_fingerprint::bytea = v_o.project_fingerprint
WHERE v_f.finding_uuid IS NULL
AND v_o.id IS NULL;

Batch selection

EXPLAIN SELECT "vulnerability_feedback"."id"
FROM "vulnerability_feedback"
WHERE (
		NOT EXISTS (
			SELECT 1
			FROM vulnerability_occurrences
			WHERE vulnerability_occurrences.uuid = vulnerability_feedback.finding_uuid::VARCHAR
			)
		)
	AND (
		NOT EXISTS (
			SELECT 1
			FROM vulnerability_occurrences
			WHERE vulnerability_occurrences.project_fingerprint = vulnerability_feedback.project_fingerprint::bytea
			)
		)
	AND "vulnerability_feedback"."id" BETWEEN 1
		AND 100
	AND "vulnerability_feedback"."id" >= 1
ORDER BY "vulnerability_feedback"."id" ASC;

Plan: https://postgres.ai/console/gitlab/gitlab-production-tunnel-pg12/sessions/11881/commands/42250

Batch drop

DELETE
FROM "vulnerability_feedback"
WHERE (
		NOT EXISTS (
			SELECT 1
			FROM vulnerability_occurrences
			WHERE vulnerability_occurrences.uuid = vulnerability_feedback.finding_uuid::VARCHAR
			)
		)
	AND (
		NOT EXISTS (
			SELECT 1
			FROM vulnerability_occurrences
			WHERE vulnerability_occurrences.project_fingerprint = vulnerability_feedback.project_fingerprint::bytea
			)
		)
	AND "vulnerability_feedback"."id" BETWEEN 1
		AND 100
	AND "vulnerability_feedback"."id" >= 1

Query plan: https://console.postgres.ai/gitlab/gitlab-production-tunnel-pg12/sessions/11881/commands/42247

Additional notes

You can verify that Feedback will be kept if there's no match on the vulnerability_occurrences table but there's a match on the security_findings by adding

      sast_scan_type = 1 # it's different because it's a Security::Scan object
      ci_build = create_ci_build(project, user)
      security_scan = create_security_scan(ci_build, sast_scan_type)
      create_security_finding(
        security_scan,
        scanner,
        uuid: nonexistent_uuid
      )

after line 49 in spec/lib/gitlab/background_migration/drop_invalid_vulnerabilities_feedback_records_spec.rb. The spec should fail because the count will decrease by 1 instead of 2

MR acceptance checklist

This checklist encourages us to confirm any changes have been analyzed to reduce risks in quality, performance, reliability, security, and maintainability.

Edited by Michał Zając

Merge request reports

Loading