Skip to content
Merged
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
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,13 @@

### Added

- **TurboStats databases count their tables.** `DatabaseResources` sends
`table_count`, the tables in the database's own schemas with partitions
included, and `partition_count`, how many of them are partitions. A
table partitioned by day adds a partition a day until retention drops
one, so a partition count that keeps climbing is retention that
stopped. The widest database bundle grows 54 bytes, to 84,091.

- **TurboStats tables carry their schema and their writes.** A
`DatabaseTable` sends `schema_hash` every report, a hash of its columns'
names, types and nullability, and `schema_changes` in the report where
Expand Down
2 changes: 2 additions & 0 deletions internal/turbostats/dimensional_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -620,6 +620,8 @@ func widestDatabase(tables, replicas, errors, queries, changes int) *wire.Databa
SizeBytes: &big,
OldestTransactionSeconds: &big,
Memory: &wire.DatabaseMemory{SharedBuffersBytes: big},
TableCount: &n,
PartitionCount: &n,
},
Replication: &wire.DatabaseReplication{Role: "primary", LagSeconds: &secs, LastReplayedAt: &at, Upstream: host + ":65535"},
Load: &wire.DatabaseLoad{
Expand Down
7 changes: 7 additions & 0 deletions turbostats/wire/database.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,13 @@ type DatabaseResources struct {
// one idle in transaction holds vacuum back.
OldestTransactionSeconds *int64 `json:"oldest_transaction_seconds,omitempty"`
Memory *DatabaseMemory `json:"memory,omitempty"`
// TableCount is the tables in the database's own schemas, partitions
// included; the system catalogs are not counted. PartitionCount is how
// many of them are partitions. A table partitioned by day adds one a
// day until retention drops one, so a PartitionCount that keeps
// climbing is retention that stopped.
TableCount *int `json:"table_count,omitempty"`
PartitionCount *int `json:"partition_count,omitempty"`
}

// DatabaseConnections is connections in use against the configured maximum.
Expand Down
20 changes: 20 additions & 0 deletions turbostats/wire/database_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -163,3 +163,23 @@ func TestDatabaseTable_SchemaAndWritesRoundTrip(t *testing.T) {
assert.That(t, !strings.Contains(string(out), "rows_inserted"))
assert.Equal(t, 60, MaxDatabaseSchemaChanges)
}

// A database counts its tables and how many of them are partitions. A
// table partitioned by day adds a partition a day until retention drops
// one, so a partition count that keeps climbing is retention that stopped.
func TestDatabaseResources_TableAndPartitionCountsRoundTrip(t *testing.T) {
coverage.Covers(t, "observability.turbostats")
raw := `{"size_bytes":247463936,"table_count":172,"partition_count":148}`
var r DatabaseResources
assert.NoError(t, json.Unmarshal([]byte(raw), &r))
assert.Equal(t, 172, *r.TableCount)
assert.Equal(t, 148, *r.PartitionCount)
out, err := json.Marshal(r)
assert.NoError(t, err)
assert.Equal(t, raw, string(out))

// A kind that cannot count its tables leaves both out.
out, err = json.Marshal(DatabaseResources{})
assert.NoError(t, err)
assert.Equal(t, `{}`, string(out))
}
7 changes: 7 additions & 0 deletions turbostats/wire/schema/bundle.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -618,6 +618,13 @@
"required": [
"shared_buffers_bytes"
]
},
"table_count": {
"type": "integer",
"description": "TableCount is the tables in the database's own schemas, partitions\nincluded; the system catalogs are not counted. PartitionCount is how\nmany of them are partitions. A table partitioned by day adds one a\nday until retention drops one, so a PartitionCount that keeps\nclimbing is retention that stopped."
},
"partition_count": {
"type": "integer"
}
},
"type": "object"
Expand Down
Loading