Di recente, ho avuto un server PostgreSQL 8.2.11 aggiornato a 8.4 per sfruttare le funzionalità di autovacuum ed essere in linea con altri 30 server PGSQL. Ciò è stato fatto da un gruppo IT separato che amministra l'hardware, quindi non abbiamo molta scelta su nessun altro aggiornamento (non vedremo 9+ per un po '). Il server esiste in un ambiente molto chiuso (rete isolata, privilegi di root limitati) e funziona su RHEL5.5 (i686). Dopo l'aggiornamento, il database è cresciuto costantemente fino a 5-6 GB al giorno. Normalmente, il database, nel suo insieme, è ~ 20 GB; attualmente è ~ 89 GB. Abbiamo un paio di altri server che eseguono database equivalenti e in realtà sincronizzano i record tra loro tramite un'applicazione di terze parti (uno che non ho accesso al funzionamento interno). Gli altri database sono ~ 20 GB come dovrebbero essere.
Eseguendo il seguente SQL, è abbastanza ovvio che c'è un problema con una tabella particolare e, più specificamente, con la sua tabella TOAST.
SELECT nspname || '.' || relname AS "relation",
pg_size_pretty(pg_relation_size(C.oid)) AS "size"
FROM pg_class C
LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
WHERE nspname NOT IN ('pg_catalog', 'information_schema')
ORDER BY pg_relation_size(C.oid) DESC
LIMIT 20;
Che produce:
relazione | dimensione ------------------------------------ + --------- pg_toast.pg_toast_16874 | 89 GB fews00.warmstates | 1095 MB ... (20 righe)
Questa tabella TOAST è per una tabella chiamata "timeseries" che salva grandi record di dati BLOB. A SUM(LENGTH(blob)/1024./1024.)
di tutti i record nella multiproprietà produce ~ 16 GB per quella colonna. Non ci dovrebbero essere motivi per cui la tabella TOAST di questa tabella dovrebbe essere così grande.
Ho eseguito un VACUUM FULL VERBOSE ANALYZE timeseries
e il vuoto viene eseguito fino al completamento senza errori.
INFORMAZIONI: passare l'aspirapolvere "pg_toast.pg_toast_16874"
INFO: "pg_toast_16874": trovati 22483 rimovibili, 10475318 versioni di file non rimovibili in 10448587 pagine
DETTAGLIO: 0 versioni di file non ancora rimosse.
Le versioni di file non rimovibili vanno da 37 a 2036 byte.
Ci sono stati 20121422 puntatori oggetto inutilizzati.
Lo spazio libero totale (comprese le versioni di riga rimovibili) è di 0 byte. 4944885 pagine sono o diventeranno vuote, incluso 0 alla fine della tabella. 4944885 pagine contenenti 0 byte liberi sono potenziali destinazioni di spostamento.
CPU 75.31s / 29.59u sec trascorsi 877.79 sec.
INFORMAZIONI: l'indice "pg_toast_16874_index" ora contiene 10475318 versioni di riga in 179931 pagine
DETTAGLIO: 23884 versioni di riga di indice rimosse.
101623 pagine indice sono state eliminate, 101623 sono attualmente riutilizzabili.
CPU trascorsa 1,35 s / 2,46u sec 21,07 sec.
Indicizzato al tavolo che ha liberato un po 'di spazio (~ 1 GB). Non riesco a CLUSTER la tabella in quanto non c'è abbastanza spazio su disco per il processo e sto aspettando di ricostruire la tabella interamente poiché vorrei scoprire perché è molto più grande dei database equivalenti che abbiamo.
Ho eseguito una query dal wiki PostgreSQL qui - "Mostra database gonfio" , e questo è quello che ottengo:
database_attuale | schemaname | tablename | tbloat | wastedbytes | iname | ibloat | wastedibytes ----------------- + ------------ + ------------------- ------------- + -------- + ------------- + ------------- -------------------- + -------- + -------------- ptrdb04 | poche centinaia | multiproprietà | 1.0 | 0 | idx_timeseries_synchlevel | 0.0 | 0 ptrdb04 | poche centinaia | multiproprietà | 1.0 | 0 | idx_timeseries_localavail | 0.0 | 0 ptrdb04 | poche centinaia | multiproprietà | 1.0 | 0 | idx_timeseries_expirytime | 0.0 | 0 ptrdb04 | poche centinaia | multiproprietà | 1.0 | 0 | idx_timeseries_expiry_null | 0.0 | 0 ptrdb04 | poche centinaia | multiproprietà | 1.0 | 0 | uniq_localintid | 0.0 | 0 ptrdb04 | poche centinaia | multiproprietà | 1.0 | 0 | pk_timeseries | 0.1 | 0 ptrdb04 | poche centinaia | idx_timeseries_expiry_null | 0.6 | 0 | ? | 0.0 | 0
Sembra che il database non consideri questo spazio come "vuoto", ma non vedo da dove provenga tutto lo spazio su disco!
Ho il sospetto che questo server di database stia decidendo di utilizzare 4-5 volte lo spazio su disco per salvare gli stessi record estratti dagli altri server di dati. La mia domanda è questa: esiste un modo per verificare la dimensione del disco fisico di una riga? Vorrei confrontare le dimensioni di una riga su questo database con un altro database "integro".
Grazie per tutto l'aiuto che potete fornire!
AGGIORNAMENTO 1
Ho finito per ricostruire il tavolo da uno schema scaricato per le sue dimensioni (non potevo lasciarlo solo per un altro giorno). Dopo aver sincronizzato i dati, tramite il processo di sincronizzazione del software, la tabella TOAST era ~ 35 GB; tuttavia, potrei rappresentare solo ~ 9 GB da quella colonna BLOB che dovrebbe essere la più lunga in termini di valori. Non sono sicuro da dove provengano gli altri 26 GB. CLUSTER, VUOTO PIENO e REINDICATO inutilmente. I file postgresql.conf tra i server di dati locali e remoti sono esattamente gli stessi. C'è qualche motivo per cui questo database potrebbe tentare di archiviare ogni record con uno spazio maggiore su disco?
AGGIORNAMENTO 2 - Risolto
Alla fine ho deciso di ricostruire completamente il database da zero, arrivando persino a reinstallare i pacchetti PostgreSQL84 sul sistema. Il percorso del database è stato reinizializzato e i tablespace sono stati cancellati. Il processo di sincronizzazione del software di terze parti ha ripopolato le tabelle e la dimensione finale è risultata essere di ~ 12 GB ! Sfortunatamente, questo, in nessun modo, aiuta a risolvere qual era l'origine esatta del problema. Lo guarderò per un giorno o due e vedrò se ci sono differenze importanti nel modo in cui il database rivitalizzato sta gestendo la tabella TOAST e pubblicherò questi risultati qui.
Dimensione della relazione
ptrdb04=> SELECT nspname || '.' || relname AS "relation",
ptrdb04-> pg_size_pretty(pg_relation_size(C.oid)) AS "size"
ptrdb04-> FROM pg_class C
ptrdb04-> LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
ptrdb04-> WHERE nspname NOT IN ('pg_catalog', 'information_schema')
ptrdb04-> ORDER BY pg_relation_size(C.oid) DESC
ptrdb04-> LIMIT 2;
relazione | dimensione
------------------------- + ---------
pg_toast . pg_toast_17269 | 18 GB
poche centinaia . stati caldi | 1224 MB
( 2 file )
VACUUM VERBOSE ANALYZE timeseries;
INFO: "timeseries": trovate 12699 versioni rimovibili, 681961 non rimovibili in 58130 di 68382 pagine DETTAGLIO: 0 versioni di righe morte non possono ancora essere rimosse. C'erano 105847 puntatori oggetto inutilizzati. 0 pagine sono completamente vuote. CPU 0.83s / 2.08u sec trascorsa 33.36 sec. INFO: aspirapolvere "pg_toast.pg_toast_17269" INFORMAZIONI: indice scansionato "pg_toast_17269_index" per rimuovere le versioni della riga 2055849 DETTAGLIO: CPU 0.37s / 2.92u sec trascorsi 13.29 sec. INFO: "pg_toast_17269": rimosse 2055849 versioni di riga in 518543 pagine DETTAGLIO: CPU 8.60s / 3.21u sec trascorsi 358.42 sec. INFO: l'indice "pg_toast_17269_index" ora contiene 7346902 versioni di riga in 36786 pagine DETTAGLIO: 2055849 versioni di riga dell'indice rimosse. 10410 pagine indice sono state eliminate, 5124 sono attualmente riutilizzabili. CPU 0,00s / 0,00u sec. 0,01 sec. INFORMAZIONI: "pg_toast_17269": trovati 1286128 rimovibili, 2993389 versioni di file non rimovibili in 1257871 su 2328079 pagine DETTAGLIO: 0 versioni di righe morte non possono ancora essere rimosse. C'erano 18847 puntatori oggetto inutilizzati. 0 pagine sono completamente vuote. CPU 26.56s / 13.04u sec trascorsi 714.97 sec. INFO: analisi di "fews00.timeseries" INFO: "timeseries": scansionato 30000 di 68382 pagine, contenente 360192 righe attive e 0 righe morte; 30000 righe nel campione, 821022 righe totali stimate
L'unica differenza evidente dopo la ricostruzione (diversa dall'uso del disco) è
INFORMAZIONI: "pg_toast_17269": trovati 1286128 rimovibili, 2993389 versioni di file non rimovibilicome @CraigRinger menzionato in un commento. Il conteggio delle righe non rimovibili è molto più piccolo di prima.
Nuova domanda: altre tabelle possono influire sulla dimensione di un'altra tabella? (tramite chiavi esterne e simili) La ricostruzione della tabella non ha fatto nulla, ma la ricostruzione dell'intero database ha dimostrato di risolvere il problema.