forked from wangziqi/gongxue-base
176 lines
6.4 KiB
JavaScript
176 lines
6.4 KiB
JavaScript
export const postgresTuningProfiles = {
|
|
'shared-host': {
|
|
name: 'shared-host',
|
|
label: '4c16g shared-host',
|
|
description: '4 vCPU / 16GB RAM, PostgreSQL shares the host with API, worker, Nginx and monitoring agents.',
|
|
settings: {
|
|
max_connections: {
|
|
recommended: '80',
|
|
min: 40,
|
|
max: 120,
|
|
type: 'number',
|
|
rationale: '4 vCPU should use application/pooler limits instead of many direct active connections.',
|
|
},
|
|
shared_buffers: {
|
|
recommended: '3GB',
|
|
min: '2GB',
|
|
max: '4GB',
|
|
type: 'bytes',
|
|
restart: true,
|
|
rationale: 'Keep PostgreSQL buffers large enough while leaving RAM for OS cache and sibling services.',
|
|
},
|
|
effective_cache_size: {
|
|
recommended: '10GB',
|
|
min: '8GB',
|
|
max: '12GB',
|
|
type: 'bytes',
|
|
rationale: 'Planner estimate only; reflects shared buffers plus OS cache on a 16GB shared host.',
|
|
},
|
|
work_mem: {
|
|
recommended: '16MB',
|
|
min: '8MB',
|
|
max: '32MB',
|
|
type: 'bytes',
|
|
rationale: 'This is per sort/hash operation, not a global cap.',
|
|
},
|
|
maintenance_work_mem: {
|
|
recommended: '512MB',
|
|
min: '256MB',
|
|
max: '1GB',
|
|
type: 'bytes',
|
|
rationale: 'Helps index builds, vacuum and imports without overcommitting memory.',
|
|
},
|
|
autovacuum_work_mem: {
|
|
recommended: '256MB',
|
|
min: '128MB',
|
|
max: '512MB',
|
|
type: 'bytes',
|
|
rationale: 'Avoid letting multiple autovacuum workers inherit an overly high maintenance_work_mem.',
|
|
},
|
|
wal_buffers: {
|
|
recommended: '16MB',
|
|
min: '8MB',
|
|
max: '64MB',
|
|
type: 'bytes',
|
|
restart: true,
|
|
rationale: 'Enough WAL buffering for steady learning writes and import bursts.',
|
|
},
|
|
min_wal_size: {
|
|
recommended: '1GB',
|
|
min: '1GB',
|
|
max: '4GB',
|
|
type: 'bytes',
|
|
rationale: 'Reserve WAL for short write spikes and batch jobs.',
|
|
},
|
|
max_wal_size: {
|
|
recommended: '6GB',
|
|
min: '4GB',
|
|
max: '12GB',
|
|
type: 'bytes',
|
|
rationale: 'Reduce checkpoint pressure while keeping crash recovery bounded.',
|
|
},
|
|
checkpoint_timeout: {
|
|
recommended: '10min',
|
|
min: '5min',
|
|
max: '15min',
|
|
type: 'duration',
|
|
rationale: 'Avoid overly frequent checkpoints on write bursts.',
|
|
},
|
|
checkpoint_completion_target: {
|
|
recommended: '0.9',
|
|
min: 0.8,
|
|
max: 0.95,
|
|
type: 'number',
|
|
rationale: 'Spread checkpoint I/O without pushing completion too close to the next checkpoint.',
|
|
},
|
|
effective_io_concurrency: {
|
|
recommended: '100',
|
|
min: 50,
|
|
max: 300,
|
|
type: 'number',
|
|
rationale: 'SSD cloud disk starting point; validate against the actual disk class.',
|
|
},
|
|
random_page_cost: {
|
|
recommended: '1.1',
|
|
min: 1,
|
|
max: 1.5,
|
|
type: 'number',
|
|
rationale: 'Reflect SSD random I/O and encourage reasonable index scans.',
|
|
},
|
|
jit: {
|
|
recommended: 'off',
|
|
exact: 'off',
|
|
type: 'text',
|
|
rationale: 'Question-bank API queries are mostly short OLTP requests where JIT planning cost is usually not worth it.',
|
|
},
|
|
log_min_duration_statement: {
|
|
recommended: '500ms',
|
|
min: '100ms',
|
|
max: '1000ms',
|
|
type: 'duration',
|
|
rationale: 'Capture slow SQL during launch without logging every normal request.',
|
|
},
|
|
idle_in_transaction_session_timeout: {
|
|
recommended: '60s',
|
|
min: '30s',
|
|
max: '120s',
|
|
type: 'duration',
|
|
rationale: 'Kill idle transactions before they block migrations and writes.',
|
|
},
|
|
statement_timeout: {
|
|
recommended: '30s',
|
|
min: '5s',
|
|
max: '60s',
|
|
type: 'duration',
|
|
rationale: 'API requests should fail boundedly; import jobs can override per session.',
|
|
},
|
|
lock_timeout: {
|
|
recommended: '5s',
|
|
min: '1s',
|
|
max: '10s',
|
|
type: 'duration',
|
|
rationale: 'Ordinary API requests should not wait a long time behind locks.',
|
|
},
|
|
},
|
|
},
|
|
'dedicated-db': {
|
|
name: 'dedicated-db',
|
|
label: '4c16g dedicated PostgreSQL',
|
|
description: '4 vCPU / 16GB RAM where PostgreSQL is the only heavy service on the host.',
|
|
settings: {
|
|
max_connections: { recommended: '120', min: 60, max: 150, type: 'number' },
|
|
shared_buffers: { recommended: '4GB', min: '3GB', max: '5GB', type: 'bytes', restart: true },
|
|
effective_cache_size: { recommended: '12GB', min: '10GB', max: '14GB', type: 'bytes' },
|
|
work_mem: { recommended: '16MB', min: '8MB', max: '32MB', type: 'bytes' },
|
|
maintenance_work_mem: { recommended: '768MB', min: '512MB', max: '1536MB', type: 'bytes' },
|
|
autovacuum_work_mem: { recommended: '256MB', min: '128MB', max: '512MB', type: 'bytes' },
|
|
wal_buffers: { recommended: '16MB', min: '8MB', max: '64MB', type: 'bytes', restart: true },
|
|
min_wal_size: { recommended: '2GB', min: '1GB', max: '4GB', type: 'bytes' },
|
|
max_wal_size: { recommended: '8GB', min: '4GB', max: '16GB', type: 'bytes' },
|
|
checkpoint_timeout: { recommended: '15min', min: '5min', max: '20min', type: 'duration' },
|
|
checkpoint_completion_target: { recommended: '0.9', min: 0.8, max: 0.95, type: 'number' },
|
|
effective_io_concurrency: { recommended: '100', min: 50, max: 300, type: 'number' },
|
|
random_page_cost: { recommended: '1.1', min: 1, max: 1.5, type: 'number' },
|
|
jit: { recommended: 'off', exact: 'off', type: 'text' },
|
|
log_min_duration_statement: { recommended: '500ms', min: '100ms', max: '1000ms', type: 'duration' },
|
|
idle_in_transaction_session_timeout: { recommended: '60s', min: '30s', max: '120s', type: 'duration' },
|
|
statement_timeout: { recommended: '30s', min: '5s', max: '60s', type: 'duration' },
|
|
lock_timeout: { recommended: '5s', min: '1s', max: '10s', type: 'duration' },
|
|
},
|
|
},
|
|
};
|
|
|
|
export const defaultPostgresTuningProfile = 'shared-host';
|
|
|
|
export function getPostgresTuningProfile(name = defaultPostgresTuningProfile) {
|
|
const profile = postgresTuningProfiles[name];
|
|
if (!profile) {
|
|
throw new Error(`Unknown PostgreSQL tuning profile: ${name}`);
|
|
}
|
|
return profile;
|
|
}
|
|
|
|
export function getPostgresTuningSettingNames(profileName = defaultPostgresTuningProfile) {
|
|
return Object.keys(getPostgresTuningProfile(profileName).settings);
|
|
}
|