Skip to content

Commit 148d1e1

Browse files
authored
Fixes + Add a config tuning playbook (#12)
This includes a couple of fixes, especially for date timezone handling. Also adds a tuning playbook, which uses information about the database and the cluster/instance size to recommend changes to key settings relevant for performance.
1 parent 5245ce1 commit 148d1e1

File tree

6 files changed

+53
-7
lines changed

6 files changed

+53
-7
lines changed

apps/dbagent/src/components/monitoring/actions.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {
1212
updateSchedule,
1313
updateScheduleRunData
1414
} from '~/lib/db/schedules';
15+
import { utcToLocalDate } from '~/lib/monitoring/scheduler';
1516
import { listPlaybooks } from '~/lib/tools/playbooks';
1617

1718
export async function generateCronExpression(description: string): Promise<string> {
@@ -43,10 +44,10 @@ export async function actionGetSchedules(): Promise<Schedule[]> {
4344
// Ensure last_run is serialized as string
4445
schedules.forEach((schedule) => {
4546
if (schedule.lastRun) {
46-
schedule.lastRun = schedule.lastRun.toString();
47+
schedule.lastRun = utcToLocalDate(schedule.lastRun).toString();
4748
}
4849
if (schedule.nextRun) {
49-
schedule.nextRun = schedule.nextRun.toString();
50+
schedule.nextRun = utcToLocalDate(schedule.nextRun).toString();
5051
}
5152
});
5253
return schedules;

apps/dbagent/src/components/onboarding/actions.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import { getIntegration } from '~/lib/db/integrations';
88
// Server action to get completed tasks
99
export async function getCompletedTasks(): Promise<string[]> {
1010
const completedTasks: string[] = [];
11-
// TODO: Implement getting completed tasks from database
1211
const connection = await getDefaultConnection();
1312
if (!connection) {
1413
return [];

apps/dbagent/src/lib/monitoring/scheduler.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,15 @@ import {
99
import { env } from '../env/server';
1010
import { runSchedule } from './runner';
1111

12+
export function utcToLocalDate(utcString: string): Date {
13+
const date = new Date(utcString);
14+
const offset = date.getTimezoneOffset() * 60000; // Convert offset to milliseconds
15+
return new Date(date.getTime() - offset);
16+
}
17+
1218
export function shouldRunSchedule(schedule: Schedule, now: Date): boolean {
1319
if (schedule.enabled === false || !schedule.nextRun) return false;
14-
const nextRun = new Date(schedule.nextRun);
20+
const nextRun = utcToLocalDate(schedule.nextRun);
1521

1622
if (schedule.status !== 'scheduled') {
1723
if (

apps/dbagent/src/lib/targetdb/db.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ export async function getPerformanceSettings(connString: string): Promise<Perfor
130130
'maintenance_work_mem',
131131
'lock_timeout',
132132
'idle_in_transaction_session_timeout',
133+
'checkpoint_completion_target',
133134
'idle_session_timeout',
134135
'default_transaction_isolation',
135136
'max_wal_size',
@@ -139,7 +140,8 @@ export async function getPerformanceSettings(connString: string): Promise<Perfor
139140
'wal_buffers',
140141
'effective_io_concurrency',
141142
'random_page_cost',
142-
'seq_page_cost'
143+
'seq_page_cost',
144+
'huge_pages'
143145
)
144146
`);
145147
return result.rows;

apps/dbagent/src/lib/tools/dbinfo.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { getClusterByConnection } from '../db/clusters';
22

33
import { DbConnection } from '../db/connections';
44
import { getDbInfo } from '../db/dbinfo';
5+
import { getPerformanceSettings, getVacuumSettings } from '../targetdb/db';
56

67
export async function getTablesAndInstanceInfo(connection: DbConnection): Promise<string> {
78
try {
@@ -24,8 +25,8 @@ ${JSON.stringify(cluster)}
2425
}
2526

2627
export async function getPerformanceAndVacuumSettings(connection: DbConnection): Promise<string> {
27-
const performanceSettings = await getDbInfo(connection.id, 'performance_settings');
28-
const vacuumSettings = await getDbInfo(connection.id, 'vacuum_settings');
28+
const performanceSettings = await getPerformanceSettings(connection.connstring);
29+
const vacuumSettings = await getVacuumSettings(connection.connstring);
2930

3031
return `
3132
Performance settings: ${JSON.stringify(performanceSettings)}

apps/dbagent/src/lib/tools/playbooks.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,12 +66,49 @@ Record any issues found and actions taken.
6666
Note any recurring patterns or areas for improvement.
6767
`;
6868

69+
const TUNING_PLAYBOOK = `
70+
Objective: Recommend performance and vacuum settings for the database.
71+
72+
Step 1:
73+
Use the getTablesAndInstanceInfo tool to gather what you know about the database and the cluster/instance type
74+
75+
Step 2:
76+
Think about what CPU/memory does that AWS instance class have?
77+
78+
Step 3:
79+
Given the information you collected above, think about the ideal settings for the following parameters:
80+
- max_connections
81+
- shared_buffers
82+
- effective_cache_size
83+
- maintenance_work_mem
84+
- checkpoint_completion_target
85+
- wal_buffers
86+
- default_statistics_target
87+
- random_page_cost
88+
- effective_io_concurrency
89+
- work_mem
90+
- huge_pages
91+
- min_wal_size
92+
- max_wal_size
93+
- max_worker_processes
94+
- max_parallel_workers_per_gather
95+
- max_parallel_workers
96+
- max_parallel_maintenance_workers.
97+
98+
Step 4:
99+
Now compare with the value you read via the tool getPerformanceAndVacuumSettings and see if there's anything you'd change.
100+
101+
Report your findings in a structured way, with the settings you'd change, and the reason for the change. Highlight the most important changes first.
102+
`;
103+
69104
export function getPlaybook(name: string): string {
70105
switch (name) {
71106
case 'investigateSlowQueries':
72107
return SLOW_QUERIES_PLAYBOOK;
73108
case 'generalMonitoring':
74109
return GENERAL_MONITORING_PLAYBOOK;
110+
case 'tuneSettings':
111+
return TUNING_PLAYBOOK;
75112
default:
76113
return `Error:Playbook ${name} not found`;
77114
}

0 commit comments

Comments
 (0)