Se non conosci PostgreSQL, la sfida più comune che devi affrontare riguarda come ottimizzare il tuo ambiente di database.
Quando PostgreSQL è installato, produce automaticamente un file postgresql.conf di base. Questo file di configurazione viene normalmente conservato all'interno della directory dei dati a seconda del sistema operativo in uso. Ad esempio, in Ubuntu PostgreSQL posiziona le configurazioni (pg_hba.conf, postgresql.conf, pg_ident.conf) all'interno della directory /etc/postgresql. Prima di poter ottimizzare il tuo database PostgreSQL, devi prima individuare i file postgresql.conf.
Ma quali sono le impostazioni giuste da usare? e quali sono i valori impostati inizialmente? L'uso di strumenti esterni come PGTune (e strumenti alternativi come ClusterControl) ti aiuterà a risolvere questo problema specifico.
Cos'è PGtune?
PGTune è una procedura guidata di configurazione originariamente creata da Greg Smith da 2ndQuadrant. È basato su uno script Python che, sfortunatamente, non è più supportato. (Non supporta le versioni più recenti di PostgreSQL.) È quindi passato a pgtune.leopard.in.ua (che è basato sul PGTune originale) e ora è una procedura guidata di configurazione che puoi utilizzare per le impostazioni di configurazione del database PG.
PGTune viene utilizzato per calcolare i parametri di configurazione per PostgreSQL in base alle prestazioni massime per una determinata configurazione hardware. Tuttavia, non è un proiettile d'argento, poiché molte impostazioni dipendono non solo dalla configurazione hardware, ma anche dalle dimensioni del database, dal numero di client e dalla complessità delle query.
Come usare PGtune
La vecchia versione di PGTune era basata sullo script python che puoi invocare tramite il comando della shell (usando Ubuntu):
[email protected]:~/pgtune-master# $PWD/pgtune -L -T Mixed -i /etc/postgresql/9.1/main/postgresql.conf | sed -e '/#.*/d' | sed '/^$/N;/^\n/D'
stats_temp_directory = '/var/run/postgresql/9.1-main.pg_stat_tmp'
datestyle = 'iso, mdy'
default_text_search_config = 'pg_catalog.english'
default_statistics_target = 100
maintenance_work_mem = 120MB
checkpoint_completion_target = 0.9
effective_cache_size = 1408MB
work_mem = 9MB
wal_buffers = 16MB
checkpoint_segments = 32
shared_buffers = 480MB
Ma quello nuovo è molto più semplice e conveniente poiché puoi accedere semplicemente tramite browser. Basta andare su https://pgtune.leopard.in.ua/. Un buon esempio è il seguente:
Tutto quello che devi fare è specificare i seguenti campi:
- Versione DB - la versione del tuo PostgreSQL. Supporta le versioni di PostgreSQL da 9.2, 9.3, 9.4, 9.5, 9.6, 10, 11 e 12.
- Tipo di sistema operativo - il tipo di sistema operativo (Linux, OS X, Windows)
- Tipo DB - il tipo di database che è principalmente il tipo di elaborazione transazionale che il tuo database gestirà (Applicazione Web, OLTP, Data Warehousing, Applicazione desktop, Tipo misto di applicazioni)
- Memoria totale (RAM) - La memoria totale che gestirà l'istanza PG. È necessario specificarlo in GiB.
- Numero di CPU - Numero di CPU che PostgreSQL può utilizzare CPU =thread per core * core per socket * socket
- Numero di connessioni - Numero massimo di connessioni client PostgreSQL
- Archiviazione dati - Tipo di dispositivo di archiviazione dati che puoi scegliere tra SSD, HDD o storage basato su SAN.
Quindi premi il pulsante Genera. In alternativa, puoi anche eseguire l'istruzione ALTER SYSTEM che genera postgresql.auto.conf, ma non ci vorrà prima di riavviare PostgreSQL.
Come imposta i valori
L'algoritmo per questo strumento può essere trovato fondamentalmente qui in configuration.js. Condivide lo stesso algoritmo del vecchio PGTune a partire da qui pgtune#L477. Ad esempio, le versioni di PostgreSQL <9.5 supportano checkpoint_segments, ma PG>=9.5 utilizza min_wal_size e max_wal_size.
L'impostazione di checkpoint_segments o min_wal_size/max_wal_size dipende dal tipo di versione di PostgreSQL e dal tipo di database di transazione dell'applicazione database. Guarda come nello snippet qui sotto:
if (dbVersion < 9.5) {
return [
{
key: 'checkpoint_segments',
value: ({
[DB_TYPE_WEB]: 32,
[DB_TYPE_OLTP]: 64,
[DB_TYPE_DW]: 128,
[DB_TYPE_DESKTOP]: 3,
[DB_TYPE_MIXED]: 32
}[dbType])
}
]
} else {
return [
{
key: 'min_wal_size',
value: ({
[DB_TYPE_WEB]: (1024 * SIZE_UNIT_MAP['MB'] / SIZE_UNIT_MAP['KB']),
[DB_TYPE_OLTP]: (2048 * SIZE_UNIT_MAP['MB'] / SIZE_UNIT_MAP['KB']),
[DB_TYPE_DW]: (4096 * SIZE_UNIT_MAP['MB'] / SIZE_UNIT_MAP['KB']),
[DB_TYPE_DESKTOP]: (100 * SIZE_UNIT_MAP['MB'] / SIZE_UNIT_MAP['KB']),
[DB_TYPE_MIXED]: (1024 * SIZE_UNIT_MAP['MB'] / SIZE_UNIT_MAP['KB'])
}[dbType])
},
{
key: 'max_wal_size',
value: ({
[DB_TYPE_WEB]: (4096 * SIZE_UNIT_MAP['MB'] / SIZE_UNIT_MAP['KB']),
[DB_TYPE_OLTP]: (8192 * SIZE_UNIT_MAP['MB'] / SIZE_UNIT_MAP['KB']),
[DB_TYPE_DW]: (16384 * SIZE_UNIT_MAP['MB'] / SIZE_UNIT_MAP['KB']),
[DB_TYPE_DESKTOP]: (2048 * SIZE_UNIT_MAP['MB'] / SIZE_UNIT_MAP['KB']),
[DB_TYPE_MIXED]: (4096 * SIZE_UNIT_MAP['MB'] / SIZE_UNIT_MAP['KB'])
}[dbType])
}
]
}
Giusto per spiegare brevemente, rileva se dbVersion <9.5, quindi determina i valori suggeriti per le variabili checkpoint_segments o min_wal_size/max_wal_size in base al tipo di valore dbType impostato durante il modulo dell'interfaccia utente web.
Fondamentalmente, puoi saperne di più sull'algoritmo su come decide di suggerire i valori guardando questo script configuration.js.
Ottimizzazione della configurazione di PostgreSQL con ClusterControl
Se utilizzi ClusterControl per creare, creare o importare un cluster, esegue automaticamente un'ottimizzazione iniziale in base alle specifiche hardware specificate. Ad esempio, la creazione di un cluster con le seguenti specifiche del lavoro di seguito,
{
"command": "create_cluster",
"group_id": 1,
"group_name": "admins",
"job_data": {
"api_id": 1,
"cluster_name": "pg_11",
"cluster_type": "postgresql_single",
"company_id": "1",
"datadir": "/var/lib/postgresql/11/",
"db_password": "dbapgadmin",
"db_user": "dbapgadmin",
"disable_firewall": true,
"disable_selinux": true,
"generate_token": true,
"install_software": true,
"nodes": [
{
"hostname": "192.168.30.40",
"hostname_data": "192.168.30.40",
"hostname_internal": "",
"port": "5432"
},
{
"hostname": "192.168.30.50",
"hostname_data": "192.168.30.50",
"hostname_internal": "",
"port": "5432",
"synchronous": false
}
],
"port": "5432",
"ssh_keyfile": "/home/vagrant/.ssh/id_rsa",
"ssh_port": "22",
"ssh_user": "vagrant",
"sudo_password": "",
"user_id": 1,
"vendor": "default",
"version": "11"
},
"user_id": 1,
"user_name": "[email protected]"
}
Mi fornisce la seguente ottimizzazione come mostrato di seguito:
[[email protected] ~]# s9s job --log --job-id 84919 | sed -n '/stat_statements/,/Writing/p'
192.168.30.40:5432: Enabling stat_statements plugin.
192.168.30.40:5432: Setting wal options.
192.168.30.40:5432: Performance tuning.
192.168.30.40: Detected memory: 1999MB.
192.168.30.40:5432: Selected workload type: mixed
Using the following fine-tuning options:
checkpoint_completion_target: 0.9
effective_cache_size: 1535985kB
maintenance_work_mem: 127998kB
max_connections: 100
shared_buffers: 511995kB
wal_keep_segments: 32
work_mem: 10239kB
Writing file '192.168.30.40:/etc/postgresql/11/main/postgresql.conf'.
192.168.30.50:5432: Enabling stat_statements plugin.
192.168.30.50:5432: Setting wal options.
192.168.30.50:5432: Performance tuning.
192.168.30.50: Detected memory: 1999MB.
192.168.30.50:5432: Selected workload type: mixed
Using the following fine-tuning options:
checkpoint_completion_target: 0.9
effective_cache_size: 1535985kB
maintenance_work_mem: 127998kB
max_connections: 100
shared_buffers: 511995kB
wal_keep_segments: 32
work_mem: 10239kB
Writing file '192.168.30.50:/etc/postgresql/11/main/postgresql.conf'.
Inoltre, ottimizza anche i parametri del tuo sistema o del kernel come,
192.168.30.50:5432: Tuning OS parameters.
192.168.30.50:5432: Setting vm.swappiness = 1.
Conclusione
I parametri di ottimizzazione di ClusterControl si basano anche sull'algoritmo condiviso in pgtune#L477. Non è elegante, ma puoi cambiarlo con i valori che desideri. Con questi valori di impostazione, ti consente di avere un avvio grezzo che è sufficientemente pronto per gestire un carico di produzione basato sui valori iniziali forniti.