usando PostgreSQL 9.1.2
Vedo un uso eccessivo della CPU e grandi quantità di scritture su disco da attività postmaster. Questo succede anche mentre la mia applicazione non fa quasi nulla (10s di inserti al MINUTO). Vi è tuttavia un numero ragionevole di connessioni aperte.
Ho cercato di determinare cosa sta causando nella mia applicazione. Sono abbastanza newb con postgresql e finora non sono arrivato da nessuna parte. Ho attivato alcune opzioni di registrazione nel mio file di configurazione e ho esaminato le connessioni nella tabella pg_stat_activity, ma sono tutte inattive. Tuttavia ogni connessione consuma ~ 50% di CPU e scrive ~ 15M / s sul disco (non legge nulla).
Sto fondamentalmente usando lo stock postgresql.conf con pochissime modifiche. Apprezzerei qualsiasi consiglio o suggerimento su cosa posso fare per rintracciarlo.
Ecco un esempio di ciò che top / iotop mi sta mostrando:
Cpu(s): 18.9%us, 14.4%sy, 0.0%ni, 53.4%id, 11.8%wa, 0.0%hi, 1.5%si, 0.0%st
Mem: 32865916k total, 7263720k used, 25602196k free, 575608k buffers
Swap: 16777208k total, 0k used, 16777208k free, 4464212k cached
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
17057 postgres 20 0 236m 33m 13m R 45.0 0.1 73:48.78 postmaster
17188 postgres 20 0 219m 15m 11m R 42.3 0.0 61:45.57 postmaster
17963 postgres 20 0 219m 16m 11m R 42.3 0.1 27:15.01 postmaster
17084 postgres 20 0 219m 15m 11m S 41.7 0.0 63:13.64 postmaster
17964 postgres 20 0 219m 17m 12m R 41.7 0.1 27:23.28 postmaster
18688 postgres 20 0 219m 15m 11m R 41.3 0.0 63:46.81 postmaster
17088 postgres 20 0 226m 24m 12m R 41.0 0.1 64:39.63 postmaster
24767 postgres 20 0 219m 17m 12m R 41.0 0.1 24:39.24 postmaster
18660 postgres 20 0 219m 14m 9.9m S 40.7 0.0 60:51.52 postmaster
18664 postgres 20 0 218m 15m 11m S 40.7 0.0 61:39.61 postmaster
17962 postgres 20 0 222m 19m 11m S 40.3 0.1 11:48.79 postmaster
18671 postgres 20 0 219m 14m 9m S 39.4 0.0 60:53.21 postmaster
26168 postgres 20 0 219m 15m 10m S 38.4 0.0 59:04.55 postmaster
Total DISK READ: 0.00 B/s | Total DISK WRITE: 195.97 M/s
TID PRIO USER DISK READ DISK WRITE SWAPIN IO> COMMAND
17962 be/4 postgres 0.00 B/s 14.83 M/s 0.00 % 0.25 % postgres: aggw aggw [local] idle
17084 be/4 postgres 0.00 B/s 15.53 M/s 0.00 % 0.24 % postgres: aggw aggw [local] idle
17963 be/4 postgres 0.00 B/s 15.00 M/s 0.00 % 0.24 % postgres: aggw aggw [local] idle
17188 be/4 postgres 0.00 B/s 14.80 M/s 0.00 % 0.24 % postgres: aggw aggw [local] idle
17964 be/4 postgres 0.00 B/s 15.50 M/s 0.00 % 0.24 % postgres: aggw aggw [local] idle
18664 be/4 postgres 0.00 B/s 15.13 M/s 0.00 % 0.23 % postgres: aggw aggw [local] idle
17088 be/4 postgres 0.00 B/s 14.71 M/s 0.00 % 0.13 % postgres: aggw aggw [local] idle
18688 be/4 postgres 0.00 B/s 14.72 M/s 0.00 % 0.00 % postgres: aggw aggw [local] idle
24767 be/4 postgres 0.00 B/s 14.93 M/s 0.00 % 0.00 % postgres: aggw aggw [local] idle
18671 be/4 postgres 0.00 B/s 16.14 M/s 0.00 % 0.00 % postgres: aggw aggw [local] idle
17057 be/4 postgres 0.00 B/s 13.58 M/s 0.00 % 0.00 % postgres: aggw aggw [local] idle
26168 be/4 postgres 0.00 B/s 15.50 M/s 0.00 % 0.00 % postgres: aggw aggw [local] idle
18660 be/4 postgres 0.00 B/s 15.85 M/s 0.00 % 0.00 % postgres: aggw aggw [local] idle
Aggiornamento : gran parte della scrittura dei file sembra essere in alcuni file temporanei (?) Nella directory $ PG_DATA / base /. La mia comprensione della struttura dei file qui è che ogni tabella è sostanzialmente memorizzata come un file il cui nome è l'OID della tabella. Tuttavia, ci sono tonnellate di file denominati tnn_nnnnnnn, e sono questi file che sembrano essere scritti (forse sovrascritti) costantemente. A cosa servono questi file? Sono presenti circa 4700 file e tutti hanno una dimensione di 8 KB:
-rw-------. 1 postgres postgres 8192 Jul 3 23:08 t12_1430975
-rw-------. 1 postgres postgres 8192 Jul 3 23:08 t16_1432736
-rw-------. 1 postgres postgres 8192 Jul 3 23:08 t28_1439066
-rw-------. 1 postgres postgres 8192 Jul 3 23:08 t24_1436243
-rw-------. 1 postgres postgres 8192 Jul 3 23:08 t24_1436210
-rw-------. 1 postgres postgres 8192 Jul 3 23:08 t19_1393372
-rw-------. 1 postgres postgres 8192 Jul 3 23:08 t28_1439051
-rw-------. 1 postgres postgres 8192 Jul 3 23:08 t8_1430334
Aggiornamento : l'esecuzione di strace sui processi postmaster mostra sostanzialmente molte cose di I / O dei file:
open("base/16388/t24_1435947_fsm", O_RDWR) = -1 ENOENT (No such file or directory)
open("base/16388/t24_1435947_vm", O_RDWR) = -1 ENOENT (No such file or directory)
open("base/16388/t24_1435947", O_RDWR) = 9
lseek(9, 0, SEEK_END) = 8192
ftruncate(9, 0) = 0
lseek(9, 0, SEEK_END) = 0
open("base/16388/t24_1435941", O_RDWR) = 18
lseek(18, 0, SEEK_END) = 0
write(9, "\0\0\0\0\0\0\0\0\1\0\0\0000\0\360\37\360\37\4 \0\0\0\0b1\5\0\2\0\0\0"..., 8192) = 8192
lseek(18, 0, SEEK_END) = 0
close(9) = 0
open("base/16388/t24_1435947", O_RDWR) = 9
lseek(9, 0, SEEK_END) = 8192
close(18) = 0
close(9) = 0
open("base/16388/t24_1435944_fsm", O_RDWR) = -1 ENOENT (No such file or directory)
open("base/16388/t24_1435944_vm", O_RDWR) = -1 ENOENT (No such file or directory)
open("base/16388/t24_1435944", O_RDWR) = 9
lseek(9, 0, SEEK_END) = 0
close(9) = 0
Aggiornamento : quindi questo problema sembra essere tutto a che fare con le tabelle temporanee. Abbiamo modificato la nostra configurazione in modo che le tabelle temporanee siano tabelle 'regolari' e tutte le attività del disco siano andate via e le prestazioni sono tornate dove mi aspettavo. Ora, questo cambiamento è stato solo un test rapido e sporco: se avremo davvero intenzione di cambiare per usare le tabelle regolari, avremo problemi con la concorrenza e la pulizia. I tavoli temporanei sono davvero così malvagi o li stiamo abusando?
Aggiornamento : qualche altro sfondo. Sto facendo uso di un middleware di replica basato su istruzioni sviluppato internamente . È abbastanza maturo ed è stato utilizzato su numerosi progetti per diversi anni, ma usando MySQL. Abbiamo lavorato con PostgreSQL solo negli ultimi due anni. Stavamo essenzialmente utilizzando le tabelle temporanee come parte del meccanismo di replica. Ogni volta che viene stabilita una nuova connessione, creiamo una tabella temporanea per ogni tabella nel database. Con 10-20 connessioni (di lunga durata) e ~ 50 tabelle, ciò può equivalere a molte tabelle temporanee. Tutte le tabelle temporanee sono state create con:
CREATE TEMPORARY TABLE... ON COMMIT DELETE ROWS;
La semantica delle tabelle temporanee si adatta molto bene al nostro schema di replica e ha semplificato gran parte del codice che dovevamo usare per MySQL, ma sembra che l'implementazione non sia corretta. Dal po 'di ricerca che ho fatto, non credo che le tabelle temporanee fossero davvero pensate per la funzione per cui le stavamo usando.
Non sono un esperto interno (nemmeno vicino) su questo argomento, ne sono solo un utente, quindi la mia spiegazione potrebbe non essere accurata al 100%, ma penso che sia abbastanza vicina.