Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions database_admin/migrations/154_account_advisory.down.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
DROP TABLE IF EXISTS account_advisory;
25 changes: 25 additions & 0 deletions database_admin/migrations/154_account_advisory.up.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
CREATE TABLE IF NOT EXISTS account_advisory
(
advisory_id BIGINT NOT NULL,
rh_account_id INT NOT NULL,
workspace_id UUID NOT NULL,
systems_applicable INT NOT NULL DEFAULT 0,
systems_installable INT NOT NULL DEFAULT 0,
notified TIMESTAMP WITH TIME ZONE NULL,
CONSTRAINT account_advisory_advisory_id
FOREIGN KEY (advisory_id)
REFERENCES advisory_metadata (id),
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Oh, I overlooked this on my first review:
rh_account_id should be FK referencing rh_account (id)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

thanks, missed that. added now.

CONSTRAINT account_advisory_rh_account_id
FOREIGN KEY (rh_account_id)
REFERENCES rh_account (id),
PRIMARY KEY (rh_account_id, workspace_id, advisory_id)
Copy link
Copy Markdown
Collaborator

@MichaelMraka MichaelMraka May 11, 2026

Choose a reason for hiding this comment

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

PK is, by definition, unique. So another unique index on the same columns is not necessary.
I'd also change order of columns in PK to (rh_account_id, advisory_id, workspace_id) because it can be also used to search 'prefixes'. And we will likely have some queries for rh_account_id + advisory_id and not for rh_account_id + workspace_id.
Actually PK is correct. Now with Kessel we always filter by rh_account_id and workspace_id so it make sense to have them first.

) PARTITION BY HASH (rh_account_id);

SELECT create_table_partitions('account_advisory', 32,
$$WITH (fillfactor = '70', autovacuum_vacuum_scale_factor = '0.05')
TABLESPACE pg_default$$);

SELECT grant_table_partitions('SELECT, INSERT, UPDATE, DELETE', 'account_advisory', 'manager');
SELECT grant_table_partitions('SELECT, INSERT, UPDATE, DELETE', 'account_advisory', 'evaluator');
SELECT grant_table_partitions('SELECT, INSERT, UPDATE, DELETE', 'account_advisory', 'listener');
SELECT grant_table_partitions('SELECT, INSERT, UPDATE, DELETE', 'account_advisory', 'vmaas_sync');
29 changes: 28 additions & 1 deletion database_admin/schema/create_schema.sql
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ CREATE TABLE IF NOT EXISTS schema_migrations


INSERT INTO schema_migrations
VALUES (153, false);
VALUES (154, false);

-- ---------------------------------------------------------------------------
-- Functions
Expand Down Expand Up @@ -783,6 +783,33 @@ GRANT SELECT, INSERT, UPDATE, DELETE ON advisory_account_data TO vmaas_sync;
CREATE INDEX ON advisory_account_data (systems_applicable);
CREATE INDEX ON advisory_account_data (systems_installable);

-- account_advisory
CREATE TABLE IF NOT EXISTS account_advisory
(
advisory_id BIGINT NOT NULL,
rh_account_id INT NOT NULL,
workspace_id UUID NOT NULL,
systems_applicable INT NOT NULL DEFAULT 0,
systems_installable INT NOT NULL DEFAULT 0,
notified TIMESTAMP WITH TIME ZONE NULL,
CONSTRAINT account_advisory_advisory_id
FOREIGN KEY (advisory_id)
REFERENCES advisory_metadata (id),
CONSTRAINT account_advisory_rh_account_id
FOREIGN KEY (rh_account_id)
REFERENCES rh_account (id),
PRIMARY KEY (rh_account_id, workspace_id, advisory_id)
) PARTITION BY HASH (rh_account_id);
Comment thread
sourcery-ai[bot] marked this conversation as resolved.

SELECT create_table_partitions('account_advisory', 32,
$$WITH (fillfactor = '70', autovacuum_vacuum_scale_factor = '0.05')
TABLESPACE pg_default$$);

SELECT grant_table_partitions('SELECT, INSERT, UPDATE, DELETE', 'account_advisory', 'manager');
SELECT grant_table_partitions('SELECT, INSERT, UPDATE, DELETE', 'account_advisory', 'evaluator');
SELECT grant_table_partitions('SELECT, INSERT, UPDATE, DELETE', 'account_advisory', 'listener');
SELECT grant_table_partitions('SELECT, INSERT, UPDATE, DELETE', 'account_advisory', 'vmaas_sync');

-- repo
CREATE TABLE IF NOT EXISTS repo
(
Expand Down
1 change: 1 addition & 0 deletions dev/test_data.sql
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ DELETE FROM deleted_system;
DELETE FROM repo;
DELETE FROM timestamp_kv;
DELETE FROM advisory_account_data;
DELETE FROM account_advisory;
DELETE FROM package_account_data;
DELETE FROM package;
DELETE FROM package_name;
Expand Down
1 change: 1 addition & 0 deletions docs/md/database.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ Main database tables description:
- **advisory_metadata** - stores info about advisories (`description`, `summary`, `solution` etc.). It's synced and stored on trigger by `vmaas_sync` component. It allows to display detail information about the advisory.
- **system_advisories** - stores info about advisories evaluated for particular systems (system - advisory M-N mapping table). `system_id` references **system_inventory.id**. Contains info when system advisory was firstly reported and patched (if so). Records are created and updated by `evaluator` component. It allows to display list of advisories related to a system.
- **advisory_account_data** - stores info about all advisories detected within at least one system that belongs to a given account. So it provides overall statistics about system advisories displayed by the application.
- **account_advisory** - workspace-scoped version of `advisory_account_data`. Stores per-advisory aggregate counts (`systems_applicable`, `systems_installable`) and notification state for each workspace within an account. Keyed by `(rh_account_id, workspace_id, advisory_id)`, partitioned by `rh_account_id` (32 partitions).
- **package_name** - names of the packages installed on systems
- **package** - list of all packages versions, precisely all EVRAs (epoch-version-release-arch)
- **system_package2** - list of packages installed on a system
Expand Down
5 changes: 3 additions & 2 deletions tasks/vmaas_sync/metrics_db_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,13 @@ func TestTableSizes(t *testing.T) {
for _, item := range tableSizes {
uniqueTables[item.Key] = true
}
assert.Equal(t, 230, len(tableSizes))
assert.Equal(t, 230, len(uniqueTables))
assert.Equal(t, 263, len(tableSizes))
assert.Equal(t, 263, len(uniqueTables))
assert.True(t, uniqueTables["public.system_inventory"]) // check whether table names were loaded
assert.True(t, uniqueTables["public.system_patch"]) // check whether table names were loaded
assert.True(t, uniqueTables["public.package"])
assert.True(t, uniqueTables["public.repo"])
assert.True(t, uniqueTables["public.account_advisory"])
}

func TestDatabaseSize(t *testing.T) {
Expand Down
Loading