forked from wangziqi/gongxue-base
chore: gate production postgres tuning and taro handoff
This commit is contained in:
175
scripts/lib/postgres-tuning-profile.js
Normal file
175
scripts/lib/postgres-tuning-profile.js
Normal file
@@ -0,0 +1,175 @@
|
||||
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);
|
||||
}
|
||||
Reference in New Issue
Block a user