From 911c88c23e45242498070aa5154e0e301a19d840 Mon Sep 17 00:00:00 2001 From: rahul Date: Mon, 28 Oct 2024 11:15:55 +0530 Subject: [PATCH 01/16] Modified integration tests for Postgres 17 The values These inventory variables are no longer present in Postgres 17 as per the release docs: https://www.postgresql.org/docs/current/release-17.html --- tests/docker-compose.yml | 2 +- .../testdata/jsonschema-inventory-latest.json | 108 ------------------ 2 files changed, 1 insertion(+), 109 deletions(-) diff --git a/tests/docker-compose.yml b/tests/docker-compose.yml index b80511b..e6b4c94 100644 --- a/tests/docker-compose.yml +++ b/tests/docker-compose.yml @@ -8,7 +8,7 @@ services: POSTGRES_DB: demo postgres-latest-supported: - image: postgres:16 + image: postgres:17.0 restart: always environment: POSTGRES_USER: postgres diff --git a/tests/testdata/jsonschema-inventory-latest.json b/tests/testdata/jsonschema-inventory-latest.json index b052726..b9e6698 100644 --- a/tests/testdata/jsonschema-inventory-latest.json +++ b/tests/testdata/jsonschema-inventory-latest.json @@ -2053,39 +2053,6 @@ "value" ] }, - "db_user_namespace/boot_val": { - "type": "object", - "properties": { - "value": { - "type": "string" - } - }, - "required": [ - "value" - ] - }, - "db_user_namespace/reset_val": { - "type": "object", - "properties": { - "value": { - "type": "string" - } - }, - "required": [ - "value" - ] - }, - "db_user_namespace/setting": { - "type": "object", - "properties": { - "value": { - "type": "string" - } - }, - "required": [ - "value" - ] - }, "deadlock_timeout/boot_val": { "type": "object", "properties": { @@ -7490,39 +7457,6 @@ "value" ] }, - "old_snapshot_threshold/boot_val": { - "type": "object", - "properties": { - "value": { - "type": "string" - } - }, - "required": [ - "value" - ] - }, - "old_snapshot_threshold/reset_val": { - "type": "object", - "properties": { - "value": { - "type": "string" - } - }, - "required": [ - "value" - ] - }, - "old_snapshot_threshold/setting": { - "type": "object", - "properties": { - "value": { - "type": "string" - } - }, - "required": [ - "value" - ] - }, "parallel_leader_participation/boot_val": { "type": "object", "properties": { @@ -10194,39 +10128,6 @@ "value" ] }, - "trace_recovery_messages/boot_val": { - "type": "object", - "properties": { - "value": { - "type": "string" - } - }, - "required": [ - "value" - ] - }, - "trace_recovery_messages/reset_val": { - "type": "object", - "properties": { - "value": { - "type": "string" - } - }, - "required": [ - "value" - ] - }, - "trace_recovery_messages/setting": { - "type": "object", - "properties": { - "value": { - "type": "string" - } - }, - "required": [ - "value" - ] - }, "trace_sort/boot_val": { "type": "object", "properties": { @@ -12128,9 +12029,6 @@ "data_sync_retry/boot_val", "data_sync_retry/reset_val", "data_sync_retry/setting", - "db_user_namespace/boot_val", - "db_user_namespace/reset_val", - "db_user_namespace/setting", "deadlock_timeout/boot_val", "deadlock_timeout/reset_val", "deadlock_timeout/setting", @@ -12623,9 +12521,6 @@ "min_wal_size/boot_val", "min_wal_size/reset_val", "min_wal_size/setting", - "old_snapshot_threshold/boot_val", - "old_snapshot_threshold/reset_val", - "old_snapshot_threshold/setting", "parallel_leader_participation/boot_val", "parallel_leader_participation/reset_val", "parallel_leader_participation/setting", @@ -12869,9 +12764,6 @@ "trace_notify/boot_val", "trace_notify/reset_val", "trace_notify/setting", - "trace_recovery_messages/boot_val", - "trace_recovery_messages/reset_val", - "trace_recovery_messages/setting", "trace_sort/boot_val", "trace_sort/reset_val", "trace_sort/setting", From e948d1b2cab1ef05ed8ee541a3eb9995b1cdfaa1 Mon Sep 17 00:00:00 2001 From: rahul Date: Tue, 29 Oct 2024 13:43:58 +0530 Subject: [PATCH 02/16] Modified instance definitions to add support for Postgres17 --- src/metrics/instance_definitions.go | 41 ++++++++++++++++++++++-- src/metrics/instance_definitions_test.go | 14 ++++++++ 2 files changed, 53 insertions(+), 2 deletions(-) diff --git a/src/metrics/instance_definitions.go b/src/metrics/instance_definitions.go index 92de35e..4416338 100644 --- a/src/metrics/instance_definitions.go +++ b/src/metrics/instance_definitions.go @@ -5,9 +5,10 @@ import ( ) func generateInstanceDefinitions(version *semver.Version) []*QueryDefinition { - queryDefinitions := make([]*QueryDefinition, 1, 3) + queryDefinitions := make([]*QueryDefinition, 1, 5) v91 := semver.MustParse("9.1.0") v92 := semver.MustParse("9.2.0") + v170 := semver.MustParse("17.0.0") queryDefinitions[0] = instanceDefinitionBase @@ -19,6 +20,10 @@ func generateInstanceDefinitions(version *semver.Version) []*QueryDefinition { queryDefinitions = append(queryDefinitions, instanceDefinition92) } + if version.GE(v170) { + queryDefinitions = append(queryDefinitions, instanceDefinitionBase170, instanceDefinition170) + } + return queryDefinitions } @@ -62,6 +67,38 @@ var instanceDefinition92 = &QueryDefinition{ dataModels: []struct { CheckpointWriteTime *int64 `db:"time_writing_checkpoint_files_to_disk" metric_name:"bgwriter.checkpointWriteTimeInMillisecondsPerSecond" source_type:"rate"` - CheckpointSynTime *int64 `db:"time_synchronizing_checkpoint_files_to_disk" metric_name:"bgwriter.checkpointSyncTimeInMillisecondsPerSecond" source_type:"rate"` + CheckpointSyncTime *int64 `db:"time_synchronizing_checkpoint_files_to_disk" metric_name:"bgwriter.checkpointSyncTimeInMillisecondsPerSecond" source_type:"rate"` + }{}, +} + +var instanceDefinitionBase170 = &QueryDefinition{ + query: `SELECT + BG.buffers_clean AS buffers_written_by_background_writer, + BG.maxwritten_clean AS background_writer_stops, + BG.buffers_alloc AS buffers_allocated + FROM pg_stat_bgwriter BG;`, + + dataModels: []struct { + BuffersWrittenByBackgroundWriter *int64 `db:"buffers_written_by_background_writer" metric_name:"bgwriter.buffersWrittenByBackgroundWriterPerSecond" source_type:"rate"` + BackgroundWriterStops *int64 `db:"background_writer_stops" metric_name:"bgwriter.backgroundWriterStopsPerSecond" source_type:"rate"` + BuffersAllocated *int64 `db:"buffers_allocated" metric_name:"bgwriter.buffersAllocatedPerSecond" source_type:"rate"` + }{}, +} + +var instanceDefinition170 = &QueryDefinition{ + query: `SELECT + BG.num_timed AS scheduled_checkpoints_performed, + BG.num_requested AS requested_checkpoints_performed, + BG.buffers_written AS buffers_written_during_checkpoint, + cast(BG.write_time AS bigint) AS time_writing_checkpoint_files_to_disk, + cast(BG.sync_time AS bigint) AS time_synchronizing_checkpoint_files_to_disk + FROM pg_stat_checkpointer BG;`, + + dataModels: []struct { + ScheduledCheckpointsPerformed *int64 `db:"scheduled_checkpoints_performed" metric_name:"checkpointer.checkpointsScheduledPerSecond" source_type:"rate"` + RequestedCheckpointsPerformed *int64 `db:"requested_checkpoints_performed" metric_name:"checkpointer.checkpointsRequestedPerSecond" source_type:"rate"` + BuffersWrittenDuringCheckpoint *int64 `db:"buffers_written_during_checkpoint" metric_name:"checkpointer.buffersWrittenForCheckpointsPerSecond" source_type:"rate"` + CheckpointWriteTime *int64 `db:"time_writing_checkpoint_files_to_disk" metric_name:"checkpointer.checkpointWriteTimeInMillisecondsPerSecond" source_type:"rate"` + CheckpointSyncTime *int64 `db:"time_synchronizing_checkpoint_files_to_disk" metric_name:"checkpointer.checkpointSyncTimeInMillisecondsPerSecond" source_type:"rate"` }{}, } diff --git a/src/metrics/instance_definitions_test.go b/src/metrics/instance_definitions_test.go index bca6e8b..a3f7207 100644 --- a/src/metrics/instance_definitions_test.go +++ b/src/metrics/instance_definitions_test.go @@ -34,3 +34,17 @@ func Test_generateInstanceDefinitions10(t *testing.T) { assert.Equal(t, 3, len(queryDefinitions)) } + +func Test_generateInstanceDefinitions170(t *testing.T) { + v := semver.MustParse("17.0.0") + queryDefinitions := generateInstanceDefinitions(&v) + + assert.Equal(t, 5, len(queryDefinitions)) +} + +func Test_generateInstanceDefinitions175(t *testing.T) { + v := semver.MustParse("17.5.0") + queryDefinitions := generateInstanceDefinitions(&v) + + assert.Equal(t, 5, len(queryDefinitions)) +} From 31de23c828620b1bd3e3da7692ec3172329d3ef1 Mon Sep 17 00:00:00 2001 From: rahul Date: Tue, 29 Oct 2024 14:18:00 +0530 Subject: [PATCH 03/16] Modified Instance Definitions to reflect Postgres 17 changes --- src/metrics/instance_definitions.go | 22 ++++++++++++---------- src/metrics/instance_definitions_test.go | 4 ++-- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/src/metrics/instance_definitions.go b/src/metrics/instance_definitions.go index 4416338..430ad47 100644 --- a/src/metrics/instance_definitions.go +++ b/src/metrics/instance_definitions.go @@ -5,23 +5,25 @@ import ( ) func generateInstanceDefinitions(version *semver.Version) []*QueryDefinition { - queryDefinitions := make([]*QueryDefinition, 1, 5) + queryDefinitions := make([]*QueryDefinition, 1, 3) v91 := semver.MustParse("9.1.0") v92 := semver.MustParse("9.2.0") v170 := semver.MustParse("17.0.0") - queryDefinitions[0] = instanceDefinitionBase + if !version.GE(v170) { + queryDefinitions[0] = instanceDefinitionBase - if version.GE(v91) { - queryDefinitions = append(queryDefinitions, instanceDefinition91) - } + if version.GE(v91) { + queryDefinitions = append(queryDefinitions, instanceDefinition91) + } - if version.GE(v92) { - queryDefinitions = append(queryDefinitions, instanceDefinition92) - } + if version.GE(v92) { + queryDefinitions = append(queryDefinitions, instanceDefinition92) + } - if version.GE(v170) { - queryDefinitions = append(queryDefinitions, instanceDefinitionBase170, instanceDefinition170) + } else { + queryDefinitions[0] = instanceDefinitionBase170 + queryDefinitions = append(queryDefinitions, instanceDefinition170) } return queryDefinitions diff --git a/src/metrics/instance_definitions_test.go b/src/metrics/instance_definitions_test.go index a3f7207..f8c57aa 100644 --- a/src/metrics/instance_definitions_test.go +++ b/src/metrics/instance_definitions_test.go @@ -39,12 +39,12 @@ func Test_generateInstanceDefinitions170(t *testing.T) { v := semver.MustParse("17.0.0") queryDefinitions := generateInstanceDefinitions(&v) - assert.Equal(t, 5, len(queryDefinitions)) + assert.Equal(t, 2, len(queryDefinitions)) } func Test_generateInstanceDefinitions175(t *testing.T) { v := semver.MustParse("17.5.0") queryDefinitions := generateInstanceDefinitions(&v) - assert.Equal(t, 5, len(queryDefinitions)) + assert.Equal(t, 2, len(queryDefinitions)) } From ed9d56451d96c109bcfa1f39420efa00476e5a52 Mon Sep 17 00:00:00 2001 From: rahul Date: Tue, 29 Oct 2024 16:31:10 +0530 Subject: [PATCH 04/16] Modified latest inventory to include new fields --- .../testdata/jsonschema-inventory-latest.json | 482 +++++++++++++++++- 1 file changed, 481 insertions(+), 1 deletion(-) diff --git a/tests/testdata/jsonschema-inventory-latest.json b/tests/testdata/jsonschema-inventory-latest.json index b9e6698..8f9d925 100644 --- a/tests/testdata/jsonschema-inventory-latest.json +++ b/tests/testdata/jsonschema-inventory-latest.json @@ -11843,6 +11843,426 @@ "required": [ "value" ] + }, + "allow_alter_system/boot_val": { + "type": "object", + "properties": { + "value": {"type": "string"} + }, + "required": ["value"] + }, + "allow_alter_system/reset_val": { + "type": "object", + "properties": { + "value": {"type": "string"} + }, + "required": ["value"] + }, + "allow_alter_system/setting": { + "type": "object", + "properties": { + "value": {"type": "string"} + }, + "required": ["value"] + }, + "commit_timestamp_buffers/boot_val": { + "type": "object", + "properties": { + "value": {"type": "string"} + }, + "required": ["value"] + }, + "commit_timestamp_buffers/reset_val": { + "type": "object", + "properties": { + "value": {"type": "string"} + }, + "required": ["value"] + }, + "commit_timestamp_buffers/setting": { + "type": "object", + "properties": { + "value": {"type": "string"} + }, + "required": ["value"] + }, + "enable_group_by_reordering/boot_val": { + "type": "object", + "properties": { + "value": {"type": "string"} + }, + "required": ["value"] + }, + "enable_group_by_reordering/reset_val": { + "type": "object", + "properties": { + "value": {"type": "string"} + }, + "required": ["value"] + }, + "enable_group_by_reordering/setting": { + "type": "object", + "properties": { + "value": {"type": "string"} + }, + "required": ["value"] + }, + "event_triggers/boot_val": { + "type": "object", + "properties": { + "value": {"type": "string"} + }, + "required": ["value"] + }, + "event_triggers/reset_val": { + "type": "object", + "properties": { + "value": {"type": "string"} + }, + "required": ["value"] + }, + "event_triggers/setting": { + "type": "object", + "properties": { + "value": {"type": "string"} + }, + "required": ["value"] + }, + "huge_pages_status/boot_val": { + "type": "object", + "properties": { + "value": {"type": "string"} + }, + "required": ["value"] + }, + "huge_pages_status/reset_val": { + "type": "object", + "properties": { + "value": {"type": "string"} + }, + "required": ["value"] + }, + "huge_pages_status/setting": { + "type": "object", + "properties": { + "value": {"type": "string"} + }, + "required": ["value"] + }, + "io_combine_limit/boot_val": { + "type": "object", + "properties": { + "value": {"type": "string"} + }, + "required": ["value"] + }, + "io_combine_limit/reset_val": { + "type": "object", + "properties": { + "value": {"type": "string"} + }, + "required": ["value"] + }, + "io_combine_limit/setting": { + "type": "object", + "properties": { + "value": {"type": "string"} + }, + "required": ["value"] + }, + "max_notify_queue_pages/boot_val": { + "type": "object", + "properties": { + "value": {"type": "string"} + }, + "required": ["value"] + }, + "max_notify_queue_pages/reset_val": { + "type": "object", + "properties": { + "value": {"type": "string"} + }, + "required": ["value"] + }, + "max_notify_queue_pages/setting": { + "type": "object", + "properties": { + "value": {"type": "string"} + }, + "required": ["value"] + }, + "multixact_member_buffers/boot_val": { + "type": "object", + "properties": { + "value": {"type": "string"} + }, + "required": ["value"] + }, + "multixact_member_buffers/reset_val": { + "type": "object", + "properties": { + "value": {"type": "string"} + }, + "required": ["value"] + }, + "multixact_member_buffers/setting": { + "type": "object", + "properties": { + "value": {"type": "string"} + }, + "required": ["value"] + }, + "multixact_offset_buffers/boot_val": { + "type": "object", + "properties": { + "value": {"type": "string"} + }, + "required": ["value"] + }, + "multixact_offset_buffers/reset_val": { + "type": "object", + "properties": { + "value": {"type": "string"} + }, + "required": ["value"] + }, + "multixact_offset_buffers/setting": { + "type": "object", + "properties": { + "value": {"type": "string"} + }, + "required": ["value"] + }, + "notify_buffers/boot_val": { + "type": "object", + "properties": { + "value": {"type": "string"} + }, + "required": ["value"] + }, + "notify_buffers/reset_val": { + "type": "object", + "properties": { + "value": {"type": "string"} + }, + "required": ["value"] + }, + "notify_buffers/setting": { + "type": "object", + "properties": { + "value": {"type": "string"} + }, + "required": ["value"] + }, + "restrict_nonsystem_relation_kind/boot_val": { + "type": "object", + "properties": { + "value": {"type": "string"} + }, + "required": ["value"] + }, + "restrict_nonsystem_relation_kind/reset_val": { + "type": "object", + "properties": { + "value": {"type": "string"} + }, + "required": ["value"] + }, + "restrict_nonsystem_relation_kind/setting": { + "type": "object", + "properties": { + "value": {"type": "string"} + }, + "required": ["value"] + }, + "serializable_buffers/boot_val": { + "type": "object", + "properties": { + "value": {"type": "string"} + }, + "required": ["value"] + }, + "serializable_buffers/reset_val": { + "type": "object", + "properties": { + "value": {"type": "string"} + }, + "required": ["value"] + }, + "serializable_buffers/setting": { + "type": "object", + "properties": { + "value": {"type": "string"} + }, + "required": ["value"] + }, + "subtransaction_buffers/boot_val": { + "type": "object", + "properties": { + "value": {"type": "string"} + }, + "required": ["value"] + }, + "subtransaction_buffers/reset_val": { + "type": "object", + "properties": { + "value": {"type": "string"} + }, + "required": ["value"] + }, + "subtransaction_buffers/setting": { + "type": "object", + "properties": { + "value": {"type": "string"} + }, + "required": ["value"] + }, + "summarize_wal/boot_val": { + "type": "object", + "properties": { + "value": {"type": "string"} + }, + "required": ["value"] + }, + "summarize_wal/reset_val": { + "type": "object", + "properties": { + "value": {"type": "string"} + }, + "required": ["value"] + }, + "summarize_wal/setting": { + "type": "object", + "properties": { + "value": {"type": "string"} + }, + "required": ["value"] + }, + "sync_replication_slots/boot_val": { + "type": "object", + "properties": { + "value": {"type": "string"} + }, + "required": ["value"] + }, + "sync_replication_slots/reset_val": { + "type": "object", + "properties": { + "value": {"type": "string"} + }, + "required": ["value"] + }, + "sync_replication_slots/setting": { + "type": "object", + "properties": { + "value": {"type": "string"} + }, + "required": ["value"] + }, + "synchronized_standby_slots/boot_val": { + "type": "object", + "properties": { + "value": {"type": "string"} + }, + "required": ["value"] + }, + "synchronized_standby_slots/reset_val": { + "type": "object", + "properties": { + "value": {"type": "string"} + }, + "required": ["value"] + }, + "synchronized_standby_slots/setting": { + "type": "object", + "properties": { + "value": {"type": "string"} + }, + "required": ["value"] + }, + "trace_connection_negotiation/boot_val": { + "type": "object", + "properties": { + "value": {"type": "string"} + }, + "required": ["value"] + }, + "trace_connection_negotiation/reset_val": { + "type": "object", + "properties": { + "value": {"type": "string"} + }, + "required": ["value"] + }, + "trace_connection_negotiation/setting": { + "type": "object", + "properties": { + "value": {"type": "string"} + }, + "required": ["value"] + }, + "transaction_buffers/boot_val": { + "type": "object", + "properties": { + "value": {"type": "string"} + }, + "required": ["value"] + }, + "transaction_buffers/reset_val": { + "type": "object", + "properties": { + "value": {"type": "string"} + }, + "required": ["value"] + }, + "transaction_buffers/setting": { + "type": "object", + "properties": { + "value": {"type": "string"} + }, + "required": ["value"] + }, + "transaction_timeout/boot_val": { + "type": "object", + "properties": { + "value": {"type": "string"} + }, + "required": ["value"] + }, + "transaction_timeout/reset_val": { + "type": "object", + "properties": { + "value": {"type": "string"} + }, + "required": ["value"] + }, + "transaction_timeout/setting": { + "type": "object", + "properties": { + "value": {"type": "string"} + }, + "required": ["value"] + }, + "wal_summary_keep_time/boot_val": { + "type": "object", + "properties": { + "value": {"type": "string"} + }, + "required": ["value"] + }, + "wal_summary_keep_time/reset_val": { + "type": "object", + "properties": { + "value": {"type": "string"} + }, + "required": ["value"] + }, + "wal_summary_keep_time/setting": { + "type": "object", + "properties": { + "value": {"type": "string"} + }, + "required": ["value"] } }, "required": [ @@ -12919,7 +13339,67 @@ "xmloption/setting", "zero_damaged_pages/boot_val", "zero_damaged_pages/reset_val", - "zero_damaged_pages/setting" + "zero_damaged_pages/setting", + "allow_alter_system/boot_val", + "allow_alter_system/reset_val", + "allow_alter_system/setting", + "commit_timestamp_buffers/boot_val", + "commit_timestamp_buffers/reset_val", + "commit_timestamp_buffers/setting", + "enable_group_by_reordering/boot_val", + "enable_group_by_reordering/reset_val", + "enable_group_by_reordering/setting", + "event_triggers/boot_val", + "event_triggers/reset_val", + "event_triggers/setting", + "huge_pages_status/boot_val", + "huge_pages_status/reset_val", + "huge_pages_status/setting", + "io_combine_limit/boot_val", + "io_combine_limit/reset_val", + "io_combine_limit/setting", + "max_notify_queue_pages/boot_val", + "max_notify_queue_pages/reset_val", + "max_notify_queue_pages/setting", + "multixact_member_buffers/boot_val", + "multixact_member_buffers/reset_val", + "multixact_member_buffers/setting", + "multixact_offset_buffers/boot_val", + "multixact_offset_buffers/reset_val", + "multixact_offset_buffers/setting", + "notify_buffers/boot_val", + "notify_buffers/reset_val", + "notify_buffers/setting", + "restrict_nonsystem_relation_kind/boot_val", + "restrict_nonsystem_relation_kind/reset_val", + "restrict_nonsystem_relation_kind/setting", + "serializable_buffers/boot_val", + "serializable_buffers/reset_val", + "serializable_buffers/setting", + "subtransaction_buffers/boot_val", + "subtransaction_buffers/reset_val", + "subtransaction_buffers/setting", + "summarize_wal/boot_val", + "summarize_wal/reset_val", + "summarize_wal/setting", + "sync_replication_slots/boot_val", + "sync_replication_slots/reset_val", + "sync_replication_slots/setting", + "synchronized_standby_slots/boot_val", + "synchronized_standby_slots/reset_val", + "synchronized_standby_slots/setting", + "trace_connection_negotiation/boot_val", + "trace_connection_negotiation/reset_val", + "trace_connection_negotiation/setting", + "transaction_buffers/boot_val", + "transaction_buffers/reset_val", + "transaction_buffers/setting", + "transaction_timeout/boot_val", + "transaction_timeout/reset_val", + "transaction_timeout/setting", + "wal_summary_keep_time/boot_val", + "wal_summary_keep_time/reset_val", + "wal_summary_keep_time/setting" ] }, "events": { From 9827a1493f01bd699b66f4078e9695f6a8d8da64 Mon Sep 17 00:00:00 2001 From: rahul Date: Tue, 29 Oct 2024 16:32:26 +0530 Subject: [PATCH 05/16] Made instance definition queries more extensible for newer versions --- src/metrics/instance_definitions.go | 59 ++++++++++++++++++++--------- 1 file changed, 41 insertions(+), 18 deletions(-) diff --git a/src/metrics/instance_definitions.go b/src/metrics/instance_definitions.go index 430ad47..4ff5946 100644 --- a/src/metrics/instance_definitions.go +++ b/src/metrics/instance_definitions.go @@ -4,29 +4,52 @@ import ( "github.com/blang/semver/v4" ) -func generateInstanceDefinitions(version *semver.Version) []*QueryDefinition { - queryDefinitions := make([]*QueryDefinition, 1, 3) - v91 := semver.MustParse("9.1.0") - v92 := semver.MustParse("9.2.0") - v170 := semver.MustParse("17.0.0") - - if !version.GE(v170) { - queryDefinitions[0] = instanceDefinitionBase +type VersionDefinition struct { + minVersion semver.Version + queryDefinitions []*QueryDefinition +} - if version.GE(v91) { - queryDefinitions = append(queryDefinitions, instanceDefinition91) - } +var versionDefinitions = []VersionDefinition{ + { + minVersion: semver.MustParse("17.0.0"), + queryDefinitions: []*QueryDefinition{ + instanceDefinitionBase170, + instanceDefinition170, + }, + }, + { + minVersion: semver.MustParse("9.2.0"), + queryDefinitions: []*QueryDefinition{ + instanceDefinitionBase, + instanceDefinition91, + instanceDefinition92, + }, + }, + { + minVersion: semver.MustParse("9.1.0"), + queryDefinitions: []*QueryDefinition{ + instanceDefinitionBase, + instanceDefinition91, + }, + }, + { + minVersion: semver.MustParse("0.0.0"), + queryDefinitions: []*QueryDefinition{ + instanceDefinitionBase, + }, + }, +} - if version.GE(v92) { - queryDefinitions = append(queryDefinitions, instanceDefinition92) +func generateInstanceDefinitions(version *semver.Version) []*QueryDefinition { + // Find the first version definition that's applicable + for _, versionDef := range versionDefinitions { + if version.GE(versionDef.minVersion) { + return versionDef.queryDefinitions } - - } else { - queryDefinitions[0] = instanceDefinitionBase170 - queryDefinitions = append(queryDefinitions, instanceDefinition170) } - return queryDefinitions + // This should never happen due to the "0.0.0" fallback version, + return []*QueryDefinition{instanceDefinitionBase} } var instanceDefinitionBase = &QueryDefinition{ From c61b98dd1aae352fc17fb33785c1e60598f15fb1 Mon Sep 17 00:00:00 2001 From: rahul Date: Tue, 29 Oct 2024 16:48:27 +0530 Subject: [PATCH 06/16] Added checkpointer table metrics to the schema --- tests/testdata/jsonschema-latest.json | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/tests/testdata/jsonschema-latest.json b/tests/testdata/jsonschema-latest.json index 17b4cf5..c8be04a 100644 --- a/tests/testdata/jsonschema-latest.json +++ b/tests/testdata/jsonschema-latest.json @@ -85,6 +85,21 @@ "bgwriter.checkpointsScheduledPerSecond": { "type": "number" }, + "checkpointer.buffersWrittenForCheckpointsPerSecond": { + "type": "number" + }, + "checkpointer.checkpointSyncTimeInMillisecondsPerSecond": { + "type": "number" + }, + "checkpointer.checkpointWriteTimeInMillisecondsPerSecond": { + "type": "number" + }, + "checkpointer.checkpointsRequestedPerSecond": { + "type": "number" + }, + "checkpointer.checkpointsScheduledPerSecond": { + "type": "number" + }, "displayName": { "type": "string" }, From d05934010ca9c3a5d5f237ebb894822daf412dc8 Mon Sep 17 00:00:00 2001 From: rahul Date: Wed, 30 Oct 2024 11:25:20 +0530 Subject: [PATCH 07/16] Added query to get dropped metrics for pg_stat_io --- src/metrics/instance_definitions.go | 32 +++++++++++++++++------------ 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/src/metrics/instance_definitions.go b/src/metrics/instance_definitions.go index 4ff5946..c58395d 100644 --- a/src/metrics/instance_definitions.go +++ b/src/metrics/instance_definitions.go @@ -15,6 +15,7 @@ var versionDefinitions = []VersionDefinition{ queryDefinitions: []*QueryDefinition{ instanceDefinitionBase170, instanceDefinition170, + instanceDefinitionInputOutput170, }, }, { @@ -32,12 +33,6 @@ var versionDefinitions = []VersionDefinition{ instanceDefinition91, }, }, - { - minVersion: semver.MustParse("0.0.0"), - queryDefinitions: []*QueryDefinition{ - instanceDefinitionBase, - }, - }, } func generateInstanceDefinitions(version *semver.Version) []*QueryDefinition { @@ -48,7 +43,6 @@ func generateInstanceDefinitions(version *semver.Version) []*QueryDefinition { } } - // This should never happen due to the "0.0.0" fallback version, return []*QueryDefinition{instanceDefinitionBase} } @@ -112,12 +106,12 @@ var instanceDefinitionBase170 = &QueryDefinition{ var instanceDefinition170 = &QueryDefinition{ query: `SELECT - BG.num_timed AS scheduled_checkpoints_performed, - BG.num_requested AS requested_checkpoints_performed, - BG.buffers_written AS buffers_written_during_checkpoint, - cast(BG.write_time AS bigint) AS time_writing_checkpoint_files_to_disk, - cast(BG.sync_time AS bigint) AS time_synchronizing_checkpoint_files_to_disk - FROM pg_stat_checkpointer BG;`, + CP.num_timed AS scheduled_checkpoints_performed, + CP.num_requested AS requested_checkpoints_performed, + CP.buffers_written AS buffers_written_during_checkpoint, + cast(CP.write_time AS bigint) AS time_writing_checkpoint_files_to_disk, + cast(CP.sync_time AS bigint) AS time_synchronizing_checkpoint_files_to_disk + FROM pg_stat_checkpointer CP;`, dataModels: []struct { ScheduledCheckpointsPerformed *int64 `db:"scheduled_checkpoints_performed" metric_name:"checkpointer.checkpointsScheduledPerSecond" source_type:"rate"` @@ -127,3 +121,15 @@ var instanceDefinition170 = &QueryDefinition{ CheckpointSyncTime *int64 `db:"time_synchronizing_checkpoint_files_to_disk" metric_name:"checkpointer.checkpointSyncTimeInMillisecondsPerSecond" source_type:"rate"` }{}, } + +var instanceDefinitionInputOutput170 = &QueryDefinition{ + query: `SELECT + SUM(IO.writes) AS buffers_written_by_backend, + SUM(IO.fsyncs) AS times_backend_executed_own_fsync + FROM pg_stat_io IO;`, + + dataModels: []struct { + BuffersWrittenByBackend *int64 `db:"buffers_written_by_backend" metric_name:"io.buffersWrittenByBackendPerSecond" source_type:"rate"` + BackendExecutedOwnFsync *int64 `db:"times_backend_executed_own_fsync" metric_name:"io.backendFsyncCallsPerSecond" source_type:"rate"` + }{}, +} From a5c8c61a23159ae4e6ab2cbb95ba5bc483f4dbb1 Mon Sep 17 00:00:00 2001 From: rahul Date: Wed, 30 Oct 2024 11:26:17 +0530 Subject: [PATCH 08/16] Tests checking version defs are now table driven --- src/metrics/instance_definitions_test.go | 90 +++++++++++++----------- 1 file changed, 50 insertions(+), 40 deletions(-) diff --git a/src/metrics/instance_definitions_test.go b/src/metrics/instance_definitions_test.go index f8c57aa..6e88f27 100644 --- a/src/metrics/instance_definitions_test.go +++ b/src/metrics/instance_definitions_test.go @@ -7,44 +7,54 @@ import ( "github.com/stretchr/testify/assert" ) -func Test_generateInstanceDefinitions90(t *testing.T) { - v := semver.MustParse("9.0.0") - queryDefinitions := generateInstanceDefinitions(&v) - - assert.Equal(t, 1, len(queryDefinitions)) -} - -func Test_generateInstanceDefinitions91(t *testing.T) { - v := semver.MustParse("9.1.0") - queryDefinitions := generateInstanceDefinitions(&v) - - assert.Equal(t, 2, len(queryDefinitions)) -} - -func Test_generateInstanceDefinitions92(t *testing.T) { - v := semver.MustParse("9.2.0") - queryDefinitions := generateInstanceDefinitions(&v) - - assert.Equal(t, 3, len(queryDefinitions)) -} - -func Test_generateInstanceDefinitions10(t *testing.T) { - v := semver.MustParse("10.2.0") - queryDefinitions := generateInstanceDefinitions(&v) - - assert.Equal(t, 3, len(queryDefinitions)) -} - -func Test_generateInstanceDefinitions170(t *testing.T) { - v := semver.MustParse("17.0.0") - queryDefinitions := generateInstanceDefinitions(&v) - - assert.Equal(t, 2, len(queryDefinitions)) -} - -func Test_generateInstanceDefinitions175(t *testing.T) { - v := semver.MustParse("17.5.0") - queryDefinitions := generateInstanceDefinitions(&v) - - assert.Equal(t, 2, len(queryDefinitions)) +func Test_generateInstanceDefinitions(t *testing.T) { + tests := []struct { + name string + version string + expectedLength int + }{ + { + name: "PostgreSQL 9.0", + version: "9.0.0", + expectedLength: 1, + }, + { + name: "PostgreSQL 9.1", + version: "9.1.0", + expectedLength: 2, + }, + { + name: "PostgreSQL 9.2", + version: "9.2.0", + expectedLength: 3, + }, + { + name: "PostgreSQL 10.2", + version: "10.2.0", + expectedLength: 3, + }, + { + name: "PostgreSQL 16.4", + version: "16.4.2", + expectedLength: 3, + }, + { + name: "PostgreSQL 17.0", + version: "17.0.0", + expectedLength: 3, + }, + { + name: "PostgreSQL 17.5", + version: "17.5.0", + expectedLength: 3, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + version := semver.MustParse(tt.version) + queryDefinitions := generateInstanceDefinitions(&version) + assert.Equal(t, tt.expectedLength, len(queryDefinitions)) + }) + } } From 5a7116462709fa5bebfa47a673d34872dc6f4ea2 Mon Sep 17 00:00:00 2001 From: rahul Date: Wed, 30 Oct 2024 11:30:28 +0530 Subject: [PATCH 09/16] schema json shows metrics from pg_stat_io --- tests/testdata/jsonschema-latest.json | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/testdata/jsonschema-latest.json b/tests/testdata/jsonschema-latest.json index c8be04a..f647d92 100644 --- a/tests/testdata/jsonschema-latest.json +++ b/tests/testdata/jsonschema-latest.json @@ -100,6 +100,12 @@ "checkpointer.checkpointsScheduledPerSecond": { "type": "number" }, + "io.backendFsyncCallsPerSecond": { + "type": "number" + }, + "io.buffersWrittenByBackendPerSecond": { + "type": "number" + }, "displayName": { "type": "string" }, From dbf23910922073bd123166e499b852c96531faa0 Mon Sep 17 00:00:00 2001 From: rahul Date: Wed, 30 Oct 2024 15:55:00 +0530 Subject: [PATCH 10/16] Modified test to check for correct instance definition order and elements --- src/metrics/instance_definitions_test.go | 64 +++++++++++++++--------- 1 file changed, 39 insertions(+), 25 deletions(-) diff --git a/src/metrics/instance_definitions_test.go b/src/metrics/instance_definitions_test.go index 6e88f27..cb69b50 100644 --- a/src/metrics/instance_definitions_test.go +++ b/src/metrics/instance_definitions_test.go @@ -9,44 +9,52 @@ import ( func Test_generateInstanceDefinitions(t *testing.T) { tests := []struct { - name string - version string - expectedLength int + name string + version string + expectedQueries []*QueryDefinition + errorExpected bool }{ { - name: "PostgreSQL 9.0", - version: "9.0.0", - expectedLength: 1, + name: "PostgreSQL 9.0", + version: "9.0.0", + expectedQueries: []*QueryDefinition{instanceDefinitionBase}, + errorExpected: false, }, { - name: "PostgreSQL 9.1", - version: "9.1.0", - expectedLength: 2, + name: "PostgreSQL 9.1", + version: "9.1.0", + expectedQueries: []*QueryDefinition{instanceDefinitionBase, instanceDefinition91}, + errorExpected: false, }, { - name: "PostgreSQL 9.2", - version: "9.2.0", - expectedLength: 3, + name: "PostgreSQL 9.2", + version: "9.2.0", + expectedQueries: []*QueryDefinition{instanceDefinitionBase, instanceDefinition91, instanceDefinition92}, + errorExpected: false, }, { - name: "PostgreSQL 10.2", - version: "10.2.0", - expectedLength: 3, + name: "PostgreSQL 10.2", + version: "10.2.0", + expectedQueries: []*QueryDefinition{instanceDefinitionBase, instanceDefinition91, instanceDefinition92}, + errorExpected: false, }, { - name: "PostgreSQL 16.4", - version: "16.4.2", - expectedLength: 3, + name: "PostgreSQL 16.4", + version: "16.4.2", + expectedQueries: []*QueryDefinition{instanceDefinitionBase, instanceDefinition91, instanceDefinition92}, + errorExpected: false, }, { - name: "PostgreSQL 17.0", - version: "17.0.0", - expectedLength: 3, + name: "PostgreSQL 17.0", + version: "17.0.0", + expectedQueries: []*QueryDefinition{instanceDefinitionBase170, instanceDefinition170, instanceDefinitionInputOutput170}, + errorExpected: false, }, { - name: "PostgreSQL 17.5", - version: "17.5.0", - expectedLength: 3, + name: "PostgreSQL 17.5 out of order", + version: "17.5.0", + expectedQueries: []*QueryDefinition{instanceDefinition170, instanceDefinitionInputOutput170, instanceDefinitionBase170}, + errorExpected: true, }, } @@ -54,7 +62,13 @@ func Test_generateInstanceDefinitions(t *testing.T) { t.Run(tt.name, func(t *testing.T) { version := semver.MustParse(tt.version) queryDefinitions := generateInstanceDefinitions(&version) - assert.Equal(t, tt.expectedLength, len(queryDefinitions)) + assert.Equal(t, len(tt.expectedQueries), len(queryDefinitions)) + + if tt.errorExpected { + assert.False(t, assert.ObjectsAreEqual(tt.expectedQueries, queryDefinitions)) + } else { + assert.ElementsMatch(t, tt.expectedQueries, queryDefinitions) + } }) } } From c1c28a7aae7877d1edd4140e7e38000e9230d31e Mon Sep 17 00:00:00 2001 From: rahul Date: Wed, 6 Nov 2024 14:04:13 +0530 Subject: [PATCH 11/16] Added seperate test for out of order Simplified version specific tests --- src/metrics/instance_definitions_test.go | 32 ++++++++++-------------- 1 file changed, 13 insertions(+), 19 deletions(-) diff --git a/src/metrics/instance_definitions_test.go b/src/metrics/instance_definitions_test.go index cb69b50..654d152 100644 --- a/src/metrics/instance_definitions_test.go +++ b/src/metrics/instance_definitions_test.go @@ -12,49 +12,36 @@ func Test_generateInstanceDefinitions(t *testing.T) { name string version string expectedQueries []*QueryDefinition - errorExpected bool }{ { name: "PostgreSQL 9.0", version: "9.0.0", expectedQueries: []*QueryDefinition{instanceDefinitionBase}, - errorExpected: false, }, { name: "PostgreSQL 9.1", version: "9.1.0", expectedQueries: []*QueryDefinition{instanceDefinitionBase, instanceDefinition91}, - errorExpected: false, }, { name: "PostgreSQL 9.2", version: "9.2.0", expectedQueries: []*QueryDefinition{instanceDefinitionBase, instanceDefinition91, instanceDefinition92}, - errorExpected: false, }, { name: "PostgreSQL 10.2", version: "10.2.0", expectedQueries: []*QueryDefinition{instanceDefinitionBase, instanceDefinition91, instanceDefinition92}, - errorExpected: false, }, { name: "PostgreSQL 16.4", version: "16.4.2", expectedQueries: []*QueryDefinition{instanceDefinitionBase, instanceDefinition91, instanceDefinition92}, - errorExpected: false, }, { name: "PostgreSQL 17.0", version: "17.0.0", expectedQueries: []*QueryDefinition{instanceDefinitionBase170, instanceDefinition170, instanceDefinitionInputOutput170}, - errorExpected: false, - }, - { - name: "PostgreSQL 17.5 out of order", - version: "17.5.0", - expectedQueries: []*QueryDefinition{instanceDefinition170, instanceDefinitionInputOutput170, instanceDefinitionBase170}, - errorExpected: true, }, } @@ -63,12 +50,19 @@ func Test_generateInstanceDefinitions(t *testing.T) { version := semver.MustParse(tt.version) queryDefinitions := generateInstanceDefinitions(&version) assert.Equal(t, len(tt.expectedQueries), len(queryDefinitions)) - - if tt.errorExpected { - assert.False(t, assert.ObjectsAreEqual(tt.expectedQueries, queryDefinitions)) - } else { - assert.ElementsMatch(t, tt.expectedQueries, queryDefinitions) - } + assert.Equal(t, tt.expectedQueries, queryDefinitions) }) } + +} + +func Test_generateInstanceDefinitionsOutOfOrder(t *testing.T) { + t.Run("PostgreSQL 17.5 order check", func(t *testing.T) { + version := semver.MustParse("17.5.0") + queryDefinitions := generateInstanceDefinitions(&version) + expectedQueries := []*QueryDefinition{instanceDefinitionInputOutput170, instanceDefinition170, instanceDefinitionBase170} + + // This fails beacuse order is different + assert.False(t, assert.ObjectsAreEqual(expectedQueries, queryDefinitions), "Query definitions should be in the correct order") + }) } From 25aa94d43d700e6823ad3aae0d5795ed5c907fe2 Mon Sep 17 00:00:00 2001 From: rahul Date: Wed, 6 Nov 2024 15:15:37 +0530 Subject: [PATCH 12/16] Modified changelog to reflect Postgresv17 support --- CHANGELOG.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ee15c61..deb0bc3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,23 @@ Unreleased section should follow [Release Toolkit](https://github.com/newrelic/r ## Unreleased +### 🚀 Enhancements +- Added support for PostgreSQL v17 + +### ⚠️ Breaking Changes +- Metric collection updated to reflect PostgreSQL v17 table structure changes: + - Metrics previously collected from `pg_stat_bgwriter` are now collected from: + - `pg_stat_checkpointer` + - `pg_stat_io` + - Variable names have changed from original `pg_stat_bgwriter` metrics to reflect new table structure: + - `bgwriter.buffersWrittenForCheckpointsPerSecond` → `checkpointer.buffersWrittenForCheckpointsPerSecond` + - `bgwriter.checkpointSyncTimeInMillisecondsPerSecond` → `checkpointer.checkpointSyncTimeInMillisecondsPerSecond` + - `bgwriter.checkpointWriteTimeInMillisecondsPerSecond` → `checkpointer.checkpointWriteTimeInMillisecondsPerSecond` + - `bgwriter.checkpointsRequestedPerSecond` → `checkpointer.checkpointsRequestedPerSecond` + - `bgwriter.checkpointsScheduledPerSecond` → `checkpointer.checkpointsScheduledPerSecond` + - `bgwriter.backendFsyncCallsPerSecond` → `io.backendFsyncCallsPerSecond` + - `bgwriter.buffersWrittenByBackendPerSecond` → `io.buffersWrittenByBackendPerSecond` + ## v2.15.0 - 2024-10-07 ### dependency From 7b3da5c4d3bedcfa6914807eec8969c060f0e54b Mon Sep 17 00:00:00 2001 From: rahul Date: Wed, 6 Nov 2024 15:29:26 +0530 Subject: [PATCH 13/16] Misspelling --- src/metrics/instance_definitions_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/metrics/instance_definitions_test.go b/src/metrics/instance_definitions_test.go index 654d152..1cd39c6 100644 --- a/src/metrics/instance_definitions_test.go +++ b/src/metrics/instance_definitions_test.go @@ -62,7 +62,7 @@ func Test_generateInstanceDefinitionsOutOfOrder(t *testing.T) { queryDefinitions := generateInstanceDefinitions(&version) expectedQueries := []*QueryDefinition{instanceDefinitionInputOutput170, instanceDefinition170, instanceDefinitionBase170} - // This fails beacuse order is different + // This fails because order is different assert.False(t, assert.ObjectsAreEqual(expectedQueries, queryDefinitions), "Query definitions should be in the correct order") }) } From 59da8493eaa7e64c9a88c5de71ac6a533cef25ef Mon Sep 17 00:00:00 2001 From: rahul Date: Wed, 6 Nov 2024 16:48:24 +0530 Subject: [PATCH 14/16] Fixed changelog format --- CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index deb0bc3..918a56a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,10 +9,10 @@ Unreleased section should follow [Release Toolkit](https://github.com/newrelic/r ## Unreleased -### 🚀 Enhancements +### Enhancements - Added support for PostgreSQL v17 -### ⚠️ Breaking Changes +### Breaking Changes - Metric collection updated to reflect PostgreSQL v17 table structure changes: - Metrics previously collected from `pg_stat_bgwriter` are now collected from: - `pg_stat_checkpointer` From 54c533c461c616fd0bd6096086a7bf939155a5e9 Mon Sep 17 00:00:00 2001 From: rahul Date: Wed, 6 Nov 2024 22:03:25 +0530 Subject: [PATCH 15/16] Fixed changelog for correct output and removed breaking changes --- CHANGELOG.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c23bbb1..8ebec62 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,8 +9,12 @@ Unreleased section should follow [Release Toolkit](https://github.com/newrelic/r ## Unreleased -### Enhancements +## v2.16.0 - 2024-11-06 + +### 🚀 Enhancements - Added support for pgbouncer v1.23 with new columns in `STATS` table. +- Added support for PostgreSQL v17 +- Metrics are updated to reflect PostgreSQL v17 metrics origin (metrics collected from `pg_stat_bgwriter` are now collected from `pg_stat_checkpointer` and `pg_stat_io`) when PostgreSQL v17 is used. Specifically: `bgwriter.buffersWrittenForCheckpointsPerSecond` → `checkpointer.buffersWrittenForCheckpointsPerSecond`, `bgwriter.checkpointSyncTimeInMillisecondsPerSecond` → `checkpointer.checkpointSyncTimeInMillisecondsPerSecond`, `bgwriter.checkpointWriteTimeInMillisecondsPerSecond` → `checkpointer.checkpointWriteTimeInMillisecondsPerSecond`, `bgwriter.checkpointsRequestedPerSecond` → `checkpointer.checkpointsRequestedPerSecond`, `bgwriter.checkpointsScheduledPerSecond` → `checkpointer.checkpointsScheduledPerSecond`, `bgwriter.backendFsyncCallsPerSecond` → `io.backendFsyncCallsPerSecond`, `bgwriter.buffersWrittenByBackendPerSecond` → `io.buffersWrittenByBackendPerSecond`. ## v2.15.0 - 2024-10-07 From b7ef21d8fcc5d01fb28fb60e4fcf6ebfbd4ff122 Mon Sep 17 00:00:00 2001 From: rahul Date: Thu, 7 Nov 2024 13:35:43 +0530 Subject: [PATCH 16/16] Fixed unrelease changelog --- CHANGELOG.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8ebec62..12911ea 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,9 +9,7 @@ Unreleased section should follow [Release Toolkit](https://github.com/newrelic/r ## Unreleased -## v2.16.0 - 2024-11-06 - -### 🚀 Enhancements +### enhancements - Added support for pgbouncer v1.23 with new columns in `STATS` table. - Added support for PostgreSQL v17 - Metrics are updated to reflect PostgreSQL v17 metrics origin (metrics collected from `pg_stat_bgwriter` are now collected from `pg_stat_checkpointer` and `pg_stat_io`) when PostgreSQL v17 is used. Specifically: `bgwriter.buffersWrittenForCheckpointsPerSecond` → `checkpointer.buffersWrittenForCheckpointsPerSecond`, `bgwriter.checkpointSyncTimeInMillisecondsPerSecond` → `checkpointer.checkpointSyncTimeInMillisecondsPerSecond`, `bgwriter.checkpointWriteTimeInMillisecondsPerSecond` → `checkpointer.checkpointWriteTimeInMillisecondsPerSecond`, `bgwriter.checkpointsRequestedPerSecond` → `checkpointer.checkpointsRequestedPerSecond`, `bgwriter.checkpointsScheduledPerSecond` → `checkpointer.checkpointsScheduledPerSecond`, `bgwriter.backendFsyncCallsPerSecond` → `io.backendFsyncCallsPerSecond`, `bgwriter.buffersWrittenByBackendPerSecond` → `io.buffersWrittenByBackendPerSecond`.