postgresai 0.16.0 → 0.17.0-dev.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +88 -10
- package/dist/bin/postgres-ai.js +10019 -7504
- package/dist/sql/03.permissions.sql +9 -0
- package/dist/sql/sql/03.permissions.sql +9 -0
- package/package.json +9 -4
- package/schemas/F001.schema.json +138 -3
- package/schemas/F003.schema.json +120 -1
- package/sql/03.permissions.sql +9 -0
|
@@ -7,6 +7,15 @@ grant connect on database {{DB_IDENT}} to {{ROLE_IDENT}};
|
|
|
7
7
|
grant pg_monitor to {{ROLE_IDENT}};
|
|
8
8
|
grant select on pg_catalog.pg_index to {{ROLE_IDENT}};
|
|
9
9
|
|
|
10
|
+
-- Required for cluster-wide pg_stat_statements collection.
|
|
11
|
+
-- pg_stat_statements is backed by shared memory and holds entries for every database
|
|
12
|
+
-- in the cluster, but a role without pg_read_all_stats sees other users' rows with
|
|
13
|
+
-- queryid and query text redacted to NULL -- which collapses the per-queryid grouping
|
|
14
|
+
-- in the pg_stat_statements metric. pg_monitor already implies pg_read_all_stats;
|
|
15
|
+
-- granting it explicitly documents the dependency and keeps the metric working if the
|
|
16
|
+
-- pg_monitor grant above is ever narrowed. Idempotent.
|
|
17
|
+
grant pg_read_all_stats to {{ROLE_IDENT}};
|
|
18
|
+
|
|
10
19
|
-- Create postgres_ai schema for our objects
|
|
11
20
|
-- Using IF NOT EXISTS for idempotency - prepare-db can be run multiple times
|
|
12
21
|
create schema if not exists postgres_ai;
|
|
@@ -7,6 +7,15 @@ grant connect on database {{DB_IDENT}} to {{ROLE_IDENT}};
|
|
|
7
7
|
grant pg_monitor to {{ROLE_IDENT}};
|
|
8
8
|
grant select on pg_catalog.pg_index to {{ROLE_IDENT}};
|
|
9
9
|
|
|
10
|
+
-- Required for cluster-wide pg_stat_statements collection.
|
|
11
|
+
-- pg_stat_statements is backed by shared memory and holds entries for every database
|
|
12
|
+
-- in the cluster, but a role without pg_read_all_stats sees other users' rows with
|
|
13
|
+
-- queryid and query text redacted to NULL -- which collapses the per-queryid grouping
|
|
14
|
+
-- in the pg_stat_statements metric. pg_monitor already implies pg_read_all_stats;
|
|
15
|
+
-- granting it explicitly documents the dependency and keeps the metric working if the
|
|
16
|
+
-- pg_monitor grant above is ever narrowed. Idempotent.
|
|
17
|
+
grant pg_read_all_stats to {{ROLE_IDENT}};
|
|
18
|
+
|
|
10
19
|
-- Create postgres_ai schema for our objects
|
|
11
20
|
-- Using IF NOT EXISTS for idempotency - prepare-db can be run multiple times
|
|
12
21
|
create schema if not exists postgres_ai;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "postgresai",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.17.0-dev.0",
|
|
4
4
|
"description": "postgres_ai CLI",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"private": false,
|
|
@@ -49,19 +49,24 @@
|
|
|
49
49
|
"release-notes": "bun run scripts/generate-release-notes.ts"
|
|
50
50
|
},
|
|
51
51
|
"dependencies": {
|
|
52
|
-
"@modelcontextprotocol/sdk": "^1.
|
|
52
|
+
"@modelcontextprotocol/sdk": "^1.26.0",
|
|
53
53
|
"commander": "^14.0.3",
|
|
54
|
-
"js-yaml": "^4.1
|
|
54
|
+
"js-yaml": "^4.3.1",
|
|
55
55
|
"pg": "^8.16.3"
|
|
56
56
|
},
|
|
57
57
|
"devDependencies": {
|
|
58
58
|
"@types/bun": "^1.3.6",
|
|
59
59
|
"@types/js-yaml": "^4.0.9",
|
|
60
60
|
"@types/pg": "^8.15.6",
|
|
61
|
-
"ajv": "
|
|
61
|
+
"ajv": "8.18.0",
|
|
62
62
|
"ajv-formats": "^3.0.1",
|
|
63
63
|
"typescript": "^6.0.2"
|
|
64
64
|
},
|
|
65
|
+
"overrides": {
|
|
66
|
+
"ajv": "8.18.0",
|
|
67
|
+
"fast-uri": "3.1.5",
|
|
68
|
+
"path-to-regexp": "8.4.0"
|
|
69
|
+
},
|
|
65
70
|
"publishConfig": {
|
|
66
71
|
"access": "public"
|
|
67
72
|
}
|
package/schemas/F001.schema.json
CHANGED
|
@@ -58,16 +58,151 @@
|
|
|
58
58
|
"type": "object",
|
|
59
59
|
"additionalProperties": { "$ref": "#/$defs/setting" }
|
|
60
60
|
},
|
|
61
|
+
"effectiveValue": {
|
|
62
|
+
"type": "object",
|
|
63
|
+
"additionalProperties": false,
|
|
64
|
+
"required": ["raw", "effective", "unit", "inherited_from", "inheritance_chain"],
|
|
65
|
+
"properties": {
|
|
66
|
+
"raw": { "type": ["string", "null"] },
|
|
67
|
+
"effective": { "type": ["number", "null"] },
|
|
68
|
+
"unit": { "type": "string" },
|
|
69
|
+
"inherited_from": { "type": ["string", "null"] },
|
|
70
|
+
"inheritance_chain": { "type": "string" }
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
"effectiveValues": {
|
|
74
|
+
"type": "object",
|
|
75
|
+
"additionalProperties": false,
|
|
76
|
+
"required": ["cost_delay_ms", "cost_limit", "work_mem_kb"],
|
|
77
|
+
"properties": {
|
|
78
|
+
"autovacuum": { "type": ["boolean", "null"] },
|
|
79
|
+
"track_counts": { "type": ["boolean", "null"] },
|
|
80
|
+
"cost_delay_ms": { "$ref": "#/$defs/effectiveValue" },
|
|
81
|
+
"cost_limit": { "$ref": "#/$defs/effectiveValue" },
|
|
82
|
+
"work_mem_kb": { "$ref": "#/$defs/effectiveValue" },
|
|
83
|
+
"naptime_s": { "type": ["number", "null"] },
|
|
84
|
+
"scale_factor": { "type": ["number", "null"] },
|
|
85
|
+
"analyze_scale_factor": { "type": ["number", "null"] },
|
|
86
|
+
"vacuum_insert_threshold": { "type": ["number", "null"] },
|
|
87
|
+
"log_min_duration_ms": { "type": ["number", "null"] },
|
|
88
|
+
"max_workers": { "type": ["number", "null"] },
|
|
89
|
+
"page_cost_hit": { "type": "number" },
|
|
90
|
+
"page_cost_miss": { "type": "number" },
|
|
91
|
+
"page_cost_dirty": { "type": "number" }
|
|
92
|
+
}
|
|
93
|
+
},
|
|
94
|
+
"throughputBudget": {
|
|
95
|
+
"type": "object",
|
|
96
|
+
"additionalProperties": false,
|
|
97
|
+
"required": [
|
|
98
|
+
"effective_cost_delay_ms",
|
|
99
|
+
"effective_cost_limit",
|
|
100
|
+
"page_cost_hit",
|
|
101
|
+
"page_cost_miss",
|
|
102
|
+
"page_cost_dirty",
|
|
103
|
+
"tokens_per_sec",
|
|
104
|
+
"read_hit_mbps",
|
|
105
|
+
"read_miss_mbps",
|
|
106
|
+
"dirty_write_mbps",
|
|
107
|
+
"throttling_disabled"
|
|
108
|
+
],
|
|
109
|
+
"properties": {
|
|
110
|
+
"effective_cost_delay_ms": { "type": ["number", "null"] },
|
|
111
|
+
"effective_cost_limit": { "type": ["number", "null"] },
|
|
112
|
+
"page_cost_hit": { "type": "number" },
|
|
113
|
+
"page_cost_miss": { "type": "number" },
|
|
114
|
+
"page_cost_dirty": { "type": "number" },
|
|
115
|
+
"tokens_per_sec": { "type": ["number", "null"] },
|
|
116
|
+
"read_hit_mbps": { "type": ["number", "null"] },
|
|
117
|
+
"read_miss_mbps": { "type": ["number", "null"] },
|
|
118
|
+
"dirty_write_mbps": { "type": ["number", "null"] },
|
|
119
|
+
"throttling_disabled": { "type": "boolean" }
|
|
120
|
+
}
|
|
121
|
+
},
|
|
122
|
+
"largestTable": {
|
|
123
|
+
"type": "object",
|
|
124
|
+
"additionalProperties": false,
|
|
125
|
+
"required": [
|
|
126
|
+
"schema_name",
|
|
127
|
+
"table_name",
|
|
128
|
+
"relkind",
|
|
129
|
+
"relpages",
|
|
130
|
+
"total_relation_size_bytes",
|
|
131
|
+
"total_relation_size_pretty",
|
|
132
|
+
"has_av_override",
|
|
133
|
+
"reloptions",
|
|
134
|
+
"scale_factor_override"
|
|
135
|
+
],
|
|
136
|
+
"properties": {
|
|
137
|
+
"schema_name": { "type": "string" },
|
|
138
|
+
"table_name": { "type": "string" },
|
|
139
|
+
"relkind": { "type": "string" },
|
|
140
|
+
"relpages": { "type": "number" },
|
|
141
|
+
"total_relation_size_bytes": { "type": "number" },
|
|
142
|
+
"total_relation_size_pretty": { "type": "string" },
|
|
143
|
+
"has_av_override": { "type": "boolean" },
|
|
144
|
+
"reloptions": { "type": "string" },
|
|
145
|
+
"scale_factor_override": { "type": ["number", "null"] }
|
|
146
|
+
}
|
|
147
|
+
},
|
|
148
|
+
"reloptionsOverview": {
|
|
149
|
+
"type": "object",
|
|
150
|
+
"additionalProperties": false,
|
|
151
|
+
"required": [
|
|
152
|
+
"relations_total",
|
|
153
|
+
"candidates_considered",
|
|
154
|
+
"tables_with_av_overrides",
|
|
155
|
+
"autovacuum_disabled_tables",
|
|
156
|
+
"cost_delay_zero_tables",
|
|
157
|
+
"cost_delay_zero_toast_only_tables"
|
|
158
|
+
],
|
|
159
|
+
"properties": {
|
|
160
|
+
"relations_total": { "type": "number" },
|
|
161
|
+
"candidates_considered": { "type": "number" },
|
|
162
|
+
"tables_with_av_overrides": { "type": "number" },
|
|
163
|
+
"autovacuum_disabled_tables": { "type": "array", "items": { "type": "string" } },
|
|
164
|
+
"cost_delay_zero_tables": { "type": "array", "items": { "type": "string" } },
|
|
165
|
+
"cost_delay_zero_toast_only_tables": { "type": "array", "items": { "type": "string" } }
|
|
166
|
+
}
|
|
167
|
+
},
|
|
168
|
+
"firedRule": {
|
|
169
|
+
"type": "object",
|
|
170
|
+
"additionalProperties": false,
|
|
171
|
+
"required": ["id", "severity", "conclusion", "recommendation"],
|
|
172
|
+
"properties": {
|
|
173
|
+
"id": { "type": "string" },
|
|
174
|
+
"severity": { "enum": ["CRITICAL", "WARNING", "NOTICE", "INFO"] },
|
|
175
|
+
"conclusion": { "type": "string" },
|
|
176
|
+
"recommendation": { "type": "string" }
|
|
177
|
+
}
|
|
178
|
+
},
|
|
179
|
+
"settingsAnalysis": {
|
|
180
|
+
"type": "object",
|
|
181
|
+
"additionalProperties": false,
|
|
182
|
+
"required": ["severity", "rules_fired", "largest_tables", "reloptions_overview"],
|
|
183
|
+
"properties": {
|
|
184
|
+
"severity": { "enum": ["CRITICAL", "WARNING", "NOTICE", "INFO", null] },
|
|
185
|
+
"rules_fired": { "type": "array", "items": { "$ref": "#/$defs/firedRule" } },
|
|
186
|
+
"largest_tables": { "type": "array", "items": { "$ref": "#/$defs/largestTable" } },
|
|
187
|
+
"reloptions_overview": { "$ref": "#/$defs/reloptionsOverview" },
|
|
188
|
+
"database_size_bytes": { "type": "number" },
|
|
189
|
+
"database_size_pretty": { "type": "string" },
|
|
190
|
+
"thresholds": { "type": "object" }
|
|
191
|
+
}
|
|
192
|
+
},
|
|
61
193
|
"nodeResult": {
|
|
62
194
|
"type": "object",
|
|
63
195
|
"additionalProperties": false,
|
|
64
196
|
"required": ["data"],
|
|
65
197
|
"properties": {
|
|
66
198
|
"data": { "$ref": "#/$defs/data" },
|
|
67
|
-
"postgres_version": { "$ref": "#/$defs/postgresVersion" }
|
|
199
|
+
"postgres_version": { "$ref": "#/$defs/postgresVersion" },
|
|
200
|
+
"effective_values": { "$ref": "#/$defs/effectiveValues" },
|
|
201
|
+
"throughput_budget": { "$ref": "#/$defs/throughputBudget" },
|
|
202
|
+
"conclusions": { "type": "array", "items": { "type": "string" } },
|
|
203
|
+
"recommendations": { "type": "array", "items": { "type": "string" } },
|
|
204
|
+
"settings_analysis": { "$ref": "#/$defs/settingsAnalysis" }
|
|
68
205
|
}
|
|
69
206
|
}
|
|
70
207
|
}
|
|
71
208
|
}
|
|
72
|
-
|
|
73
|
-
|
package/schemas/F003.schema.json
CHANGED
|
@@ -78,7 +78,124 @@
|
|
|
78
78
|
"table_size_bytes": { "type": "number" },
|
|
79
79
|
"table_size_pretty": { "type": "string" },
|
|
80
80
|
"exceeds_dead_tuple_thresholds": { "type": "boolean" },
|
|
81
|
-
"autovacuum_disabled_flagged": { "type": "boolean" }
|
|
81
|
+
"autovacuum_disabled_flagged": { "type": "boolean" },
|
|
82
|
+
"reltuples": { "type": "number" },
|
|
83
|
+
"relpages": { "type": "number" },
|
|
84
|
+
"n_mod_since_analyze": { "type": "number" },
|
|
85
|
+
"n_ins_since_vacuum": { "type": ["number", "null"] },
|
|
86
|
+
"last_autoanalyze": { "type": ["string", "null"] },
|
|
87
|
+
"last_autoanalyze_epoch": { "type": "number" },
|
|
88
|
+
"eff_vacuum_threshold": { "type": "number" },
|
|
89
|
+
"eff_vacuum_scale_factor": { "type": "number" },
|
|
90
|
+
"vacuum_settings_from_reloptions": { "type": "boolean" },
|
|
91
|
+
"eff_analyze_threshold": { "type": "number" },
|
|
92
|
+
"eff_analyze_scale_factor": { "type": "number" },
|
|
93
|
+
"eff_insert_threshold": { "type": ["number", "null"] },
|
|
94
|
+
"eff_insert_scale_factor": { "type": ["number", "null"] },
|
|
95
|
+
"insert_settings_from_reloptions": { "type": "boolean" },
|
|
96
|
+
"vacuum_trigger_point": { "type": "number" },
|
|
97
|
+
"analyze_trigger_point": { "type": "number" },
|
|
98
|
+
"insert_trigger_point": { "type": ["number", "null"] },
|
|
99
|
+
"over_trigger_ratio": { "type": "number" },
|
|
100
|
+
"over_vacuum_trigger": { "type": "boolean" },
|
|
101
|
+
"over_analyze_trigger": { "type": "boolean" },
|
|
102
|
+
"over_insert_trigger": { "type": "boolean" },
|
|
103
|
+
"toast_autovacuum_disabled": { "type": "boolean" },
|
|
104
|
+
"starving": { "type": "boolean" }
|
|
105
|
+
}
|
|
106
|
+
},
|
|
107
|
+
"triggerThresholds": {
|
|
108
|
+
"type": "object",
|
|
109
|
+
"additionalProperties": false,
|
|
110
|
+
"required": ["top_k", "keepup_min_rows", "queue_saturation_multiplier", "starvation_hours"],
|
|
111
|
+
"properties": {
|
|
112
|
+
"top_k": { "type": "number" },
|
|
113
|
+
"keepup_min_rows": { "type": "number" },
|
|
114
|
+
"queue_saturation_multiplier": { "type": "number" },
|
|
115
|
+
"starvation_hours": { "type": "number" }
|
|
116
|
+
}
|
|
117
|
+
},
|
|
118
|
+
"blockedWorker": {
|
|
119
|
+
"type": "object",
|
|
120
|
+
"additionalProperties": false,
|
|
121
|
+
"required": ["worker_pid", "blocker_pid", "blocker_queryid", "wait_seconds"],
|
|
122
|
+
"properties": {
|
|
123
|
+
"worker_pid": { "type": "number" },
|
|
124
|
+
"blocker_pid": { "type": ["number", "null"] },
|
|
125
|
+
"blocker_queryid": { "type": ["string", "null"] },
|
|
126
|
+
"wait_seconds": { "type": "number" }
|
|
127
|
+
}
|
|
128
|
+
},
|
|
129
|
+
"vacuumProgressEntry": {
|
|
130
|
+
"type": "object",
|
|
131
|
+
"additionalProperties": false,
|
|
132
|
+
"required": [
|
|
133
|
+
"schema_name",
|
|
134
|
+
"table_name",
|
|
135
|
+
"vacuum_mode",
|
|
136
|
+
"phase",
|
|
137
|
+
"phase_code",
|
|
138
|
+
"heap_blks_total",
|
|
139
|
+
"heap_blks_scanned",
|
|
140
|
+
"heap_blks_vacuumed",
|
|
141
|
+
"index_vacuum_count",
|
|
142
|
+
"is_anti_wraparound"
|
|
143
|
+
],
|
|
144
|
+
"properties": {
|
|
145
|
+
"schema_name": { "type": "string" },
|
|
146
|
+
"table_name": { "type": "string" },
|
|
147
|
+
"vacuum_mode": { "type": "string" },
|
|
148
|
+
"phase": { "type": "string" },
|
|
149
|
+
"phase_code": { "type": ["number", "null"] },
|
|
150
|
+
"heap_blks_total": { "type": "number" },
|
|
151
|
+
"heap_blks_scanned": { "type": "number" },
|
|
152
|
+
"heap_blks_vacuumed": { "type": "number" },
|
|
153
|
+
"index_vacuum_count": { "type": "number" },
|
|
154
|
+
"is_anti_wraparound": { "type": "boolean" }
|
|
155
|
+
}
|
|
156
|
+
},
|
|
157
|
+
"autovacuumKeepup": {
|
|
158
|
+
"type": "object",
|
|
159
|
+
"additionalProperties": false,
|
|
160
|
+
"required": [
|
|
161
|
+
"relations_total",
|
|
162
|
+
"candidates_considered",
|
|
163
|
+
"queue_length",
|
|
164
|
+
"analyze_queue_length",
|
|
165
|
+
"insert_queue_length",
|
|
166
|
+
"total_dead_tuples_all",
|
|
167
|
+
"active_workers",
|
|
168
|
+
"max_workers",
|
|
169
|
+
"free_slots",
|
|
170
|
+
"anti_wraparound_workers",
|
|
171
|
+
"anti_wraparound_present",
|
|
172
|
+
"saturated",
|
|
173
|
+
"chronic_under_provisioning",
|
|
174
|
+
"starving_tables_count",
|
|
175
|
+
"blocked_workers",
|
|
176
|
+
"vacuum_progress",
|
|
177
|
+
"judgment",
|
|
178
|
+
"status"
|
|
179
|
+
],
|
|
180
|
+
"properties": {
|
|
181
|
+
"relations_total": { "type": "number" },
|
|
182
|
+
"candidates_considered": { "type": "number" },
|
|
183
|
+
"queue_length": { "type": "number" },
|
|
184
|
+
"analyze_queue_length": { "type": "number" },
|
|
185
|
+
"insert_queue_length": { "type": ["number", "null"] },
|
|
186
|
+
"total_dead_tuples_all": { "type": "number" },
|
|
187
|
+
"active_workers": { "type": "number" },
|
|
188
|
+
"max_workers": { "type": ["number", "null"] },
|
|
189
|
+
"free_slots": { "type": ["number", "null"] },
|
|
190
|
+
"anti_wraparound_workers": { "type": "number" },
|
|
191
|
+
"anti_wraparound_present": { "type": "boolean" },
|
|
192
|
+
"saturated": { "type": "boolean" },
|
|
193
|
+
"chronic_under_provisioning": { "type": "boolean" },
|
|
194
|
+
"starving_tables_count": { "type": "number" },
|
|
195
|
+
"blocked_workers": { "type": "array", "items": { "$ref": "#/$defs/blockedWorker" } },
|
|
196
|
+
"vacuum_progress": { "type": "array", "items": { "$ref": "#/$defs/vacuumProgressEntry" } },
|
|
197
|
+
"judgment": { "type": "string" },
|
|
198
|
+
"status": { "type": "string", "enum": ["ok", "warning", "critical"] }
|
|
82
199
|
}
|
|
83
200
|
},
|
|
84
201
|
"thresholds": {
|
|
@@ -115,6 +232,8 @@
|
|
|
115
232
|
"autovacuum_disabled_flagged_count": { "type": "integer" },
|
|
116
233
|
"total_dead_tuples": { "type": "number" },
|
|
117
234
|
"thresholds": { "$ref": "#/$defs/thresholds" },
|
|
235
|
+
"trigger_thresholds": { "$ref": "#/$defs/triggerThresholds" },
|
|
236
|
+
"autovacuum_keepup": { "$ref": "#/$defs/autovacuumKeepup" },
|
|
118
237
|
"conclusions": { "type": "array", "items": { "type": "string" } },
|
|
119
238
|
"recommendations": { "type": "array", "items": { "type": "string" } },
|
|
120
239
|
"database_size_bytes": { "type": "number" },
|
package/sql/03.permissions.sql
CHANGED
|
@@ -7,6 +7,15 @@ grant connect on database {{DB_IDENT}} to {{ROLE_IDENT}};
|
|
|
7
7
|
grant pg_monitor to {{ROLE_IDENT}};
|
|
8
8
|
grant select on pg_catalog.pg_index to {{ROLE_IDENT}};
|
|
9
9
|
|
|
10
|
+
-- Required for cluster-wide pg_stat_statements collection.
|
|
11
|
+
-- pg_stat_statements is backed by shared memory and holds entries for every database
|
|
12
|
+
-- in the cluster, but a role without pg_read_all_stats sees other users' rows with
|
|
13
|
+
-- queryid and query text redacted to NULL -- which collapses the per-queryid grouping
|
|
14
|
+
-- in the pg_stat_statements metric. pg_monitor already implies pg_read_all_stats;
|
|
15
|
+
-- granting it explicitly documents the dependency and keeps the metric working if the
|
|
16
|
+
-- pg_monitor grant above is ever narrowed. Idempotent.
|
|
17
|
+
grant pg_read_all_stats to {{ROLE_IDENT}};
|
|
18
|
+
|
|
10
19
|
-- Create postgres_ai schema for our objects
|
|
11
20
|
-- Using IF NOT EXISTS for idempotency - prepare-db can be run multiple times
|
|
12
21
|
create schema if not exists postgres_ai;
|