mit PostgreSQL 9.1.2
Ich sehe eine übermäßige CPU-Auslastung und große Mengen an Schreibvorgängen von Postmaster-Aufgaben auf die Festplatte. Dies geschieht auch dann, wenn meine Anwendung fast nichts tut (10 Sekunden Einfügungen pro Minute). Es ist jedoch eine angemessene Anzahl von Verbindungen offen.
Ich habe versucht festzustellen, was in meiner Anwendung dies verursacht. Ich bin ziemlich neu in Postgresql und habe bisher noch nichts erreicht. Ich habe einige Protokollierungsoptionen in meiner Konfigurationsdatei aktiviert und die Verbindungen in der Tabelle pg_stat_activity überprüft, aber sie sind alle inaktiv. Jede Verbindung verbraucht jedoch ~ 50% CPU und schreibt ~ 15 M / s auf die Festplatte (liest nichts).
Ich benutze im Grunde die stock postgresql.conf mit sehr kleinen Verbesserungen. Ich würde mich über Ratschläge oder Hinweise freuen, was ich tun kann, um dies aufzuspüren.
Hier ist ein Beispiel dessen, was top / iotop mir zeigt:
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
Update : Ein Großteil des Dateischreibens scheint in temporäre (?) Dateien im Verzeichnis $ PG_DATA / base / zu erfolgen. Mein Verständnis der Dateistruktur hier ist, dass jede Tabelle im Grunde genommen als Datei gespeichert wird, deren Name die OID der Tabelle ist. Es gibt jedoch Unmengen von benannten Dateien tnn_nnnnnnn
, und es sind diese Dateien, die scheinbar ständig beschrieben (möglicherweise überschrieben) werden. Wofür sind diese Dateien? Es gibt ~ 4700 Dateien und alle sind 8 KB groß:
-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
Update : Das Ausführen von strace auf den Postmaster-Prozessen zeigt im Grunde eine Menge Datei-E / A-Inhalte:
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
Update : Dieses Problem scheint also alles mit temporären Tabellen zu tun zu haben. Wir haben unser Setup so geändert, dass die temporären Tabellen "normale" Tabellen sind und alle Festplattenaktivitäten weg sind und die Leistung wieder dort ist, wo ich sie erwartet habe. Diese Änderung war nur ein schneller und schmutziger Test: Wenn wir wirklich Änderungen an regulären Tabellen vornehmen wollen, haben wir Probleme mit der Parallelität und der Bereinigung. Sind temporäre Tische wirklich so böse oder missbrauchen wir sie?
Update : Noch etwas Hintergrund. Ich verwende eine eigens entwickelte, auf Anweisungen basierende Replikations-Middleware . Es ist ziemlich ausgereift und wurde über mehrere Jahre in einer Reihe von Projekten verwendet, verwendet jedoch MySQL. Wir haben erst in den letzten ein oder zwei Jahren mit PostgreSQL gearbeitet. Wir haben im Wesentlichen die temporären Tabellen als Teil des Replikationsmechanismus verwendet. Immer wenn eine neue Verbindung hergestellt wird, erstellen wir für jede Tabelle in der Datenbank eine temporäre Tabelle. Bei 10-20 (langlebigen) Verbindungen und ~ 50 Tabellen kann dies viele temporäre Tabellen bedeuten. Alle temporären Tabellen wurden erstellt mit:
CREATE TEMPORARY TABLE... ON COMMIT DELETE ROWS;
Die Semantik temporärer Tabellen passt sehr gut zu unserem Replikationsschema und vereinfacht einen Großteil des Codes, den wir für MySQL verwenden mussten, aber es sieht so aus, als ob die Implementierung nicht fair war. Nach meiner Recherche glaube ich nicht, dass temporäre Tabellen wirklich für die Funktion gedacht waren, für die wir sie verwendet haben.
Ich bin kein interner Experte (nicht einmal in der Nähe) zu diesem Thema, nur ein Benutzer davon, daher ist meine Erklärung möglicherweise nicht 100% genau, aber ich denke, es ist ziemlich nah.
quelle
Antworten:
Ihre PostgreSQL-Konfiguration ist weit entfernt. Dies war verdächtig von Ihrem ersten Beitrag,
Von 32 GB auf Ihrem Server sind ~ 25 GB kostenlos, ausgenommen ~ 575 MB Puffer.
Aus Ihrer postgresql.conf-Datei,
Ich gehe davon aus, dass dies eine dedizierte Datenbank ist. Wenn ja, ändern Sie es in die folgenden Parameter und laden Sie es neu / starten Sie es neu.
Lassen Sie mich wissen, wie sich dadurch Ihre Leistung ändert, und können Sie sie bei Bedarf weiter optimieren.
In Bezug auf nicht protokollierte Tabellen: Wenn Ihre temporären Tabellen kurzlebige temporäre Daten enthalten und, wie Sie erwähnt haben, in einer Sitzung erstellt werden, ist es besser, nicht protokollierte Tabellen zu verwenden.
Sie können Ihre Tabellen nach der Sitzung abschneiden, wenn dies akzeptabel ist.
Weitere Informationen hier - http://michael.otacoo.com/postgresql-2/unlogged-table-performance-in-postgresql-9-1/
Ich bin mir nicht sicher, warum Sie temporäre Tabellen für die Replikation benötigen. Können Sie die PostgreSQL-Streaming-Replikation nicht verwenden?
quelle
Die Verwendung temporärer Tabellen und langjährige Verbindungen (wahrscheinlich handelt es sich um Verbindungspooling) kann eine Belastung sein, wenn Ihr Server nicht darauf vorbereitet ist. Ein PostgreSQL-Parameter, mit dem Sie spielen können,
temp_buffers
steuert den RAM, der temporären Tabellen zugewiesen ist. Diese temporären Puffer werden pro Verbindung zugewiesen und der Standardwert (8 MB) ist wahrscheinlich zu niedrig für Ihre Site.Möglicherweise müssen Sie auch das Verhalten Ihrer Clientanwendung etwas ändern, je nachdem, wie Sie Ihre temporären Tabellen verwenden. Es gibt eine ähnliche Frage mit einer schönen Antwort auf Stack Overflow .
quelle
temp_buffers
. Können Sie uns auch mitteilen, wie groß die Datenbank ist, die Sie replizieren möchten? Wie viele Tabellen, mittlere Größe pro Tabelle und Gesamtgröße der Datenbank?Könnten Sie Ihre postgresql.conf-Datei veröffentlichen? Ihr Postgresql scheint deutlich unteroptimiert zu sein.
Könntest du auch posten:
Wenn Sie nicht protokollierte Tabellen für Ihre temporären Tabellen verwenden?
Wie viele Festplatten und in welcher RAID-Konfiguration?
quelle