za pomocą PostgreSQL 9.1.2
Widzę nadmierne zużycie procesora i duże ilości zapisów na dysk z zadań postmastera. Dzieje się tak nawet wtedy, gdy moja aplikacja prawie nic nie robi (10s wkładek na MINUTĘ). Istnieje jednak rozsądna liczba otwartych połączeń.
Próbowałem ustalić, co powoduje to w mojej aplikacji. Jestem całkiem nowy z postgresql i jak dotąd nie dotarłem. Włączyłem niektóre opcje rejestrowania w pliku konfiguracyjnym i sprawdziłem połączenia w tabeli pg_stat_activity, ale wszystkie są bezczynne. Jednak każde połączenie zużywa ~ 50% procesora i zapisuje ~ 15M / s na dysk (nic nie czyta).
Zasadniczo używam giełdowego postgresql.conf z bardzo małymi poprawkami. Byłbym wdzięczny za wszelkie porady i wskazówki, co mogę zrobić, aby to wyśledzić.
Oto próbka tego, co pokazuje mi top / iotop:
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
Aktualizacja : Wydaje się, że większość zapisywanych plików dotyczy plików tymczasowych (?) W katalogu $ PG_DATA / base /. Rozumiem tutaj strukturę pliku, że każda tabela jest zasadniczo przechowywana jako plik, którego nazwa to OID tabeli. Istnieje jednak mnóstwo nazwanych plików tnn_nnnnnnn
i właśnie te pliki wydają się być zapisywane (być może nadpisywane) w sposób ciągły. Do czego służą te pliki? Plików jest ~ 4700, a wszystkie mają rozmiar 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
Aktualizacja : Uruchomienie śledzenia procesów postmastera zasadniczo pokazuje wiele rzeczy we / wy pliku:
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
Aktualizacja : Wydaje się, że ten problem dotyczy wszystkich tabel tymczasowych. Zmieniliśmy naszą konfigurację, aby tabele tymczasowe były tabelami „normalnymi”, a cała aktywność dysku zniknęła, a wydajność powróciła do oczekiwanego poziomu. Ta zmiana była tylko szybkim i nieprzyzwoitym testem: jeśli naprawdę zamierzamy zmienić zwykłe tabele, mamy problemy z współbieżnością i czyszczeniem. Czy tymczasowe stoły naprawdę są złem, czy nadużywamy ich?
Aktualizacja : trochę więcej tła. Korzystam z opracowanego przez siebie oprogramowania pośredniego do replikacji . Jest dość dojrzały i był używany w wielu projektach przez wiele lat, ale używa MySQL. Pracujemy z PostgreSQL dopiero od ostatniego roku lub dwóch. Zasadniczo korzystaliśmy z tabel tymczasowych jako części mechanizmu replikacji. Po każdym ustanowieniu nowego połączenia tworzymy tymczasową tabelę dla każdej tabeli w bazie danych. Przy 10-20 (długotrwałych) połączeniach i ~ 50 tabelach może to stanowić wiele tymczasowych tabel. Wszystkie tabele tymczasowe zostały utworzone za pomocą:
CREATE TEMPORARY TABLE... ON COMMIT DELETE ROWS;
Semantyka tabel tymczasowych bardzo dobrze wpasowuje się w nasz schemat replikacji i uprościła wiele kodu, którego musieliśmy użyć w MySQL, ale wygląda na to, że implementacja nie była również w porządku. Z części badań, które przeprowadziłem, nie sądzę, aby tabele tymczasowe były naprawdę przeznaczone dla funkcji, w której je wykorzystaliśmy.
Nie jestem wewnętrznym ekspertem (nawet bliskim) na ten temat, tylko jego użytkownikiem, więc moje wyjaśnienie może nie być w 100% dokładne, ale myślę, że jest dość blisko.
źródło
Odpowiedzi:
Twoja konfiguracja PostgreSQL jest daleka. To było podejrzane od twojego pierwszego postu,
Z 32 GB na serwerze ~ 25 GB jest darmowe, z wyłączeniem ~ 575 MB bufora.
Z pliku postgresql.conf
Zakładam, że jest to dedykowana baza danych. Jeśli tak, zmień go na następujące parametry i załaduj ponownie / uruchom ponownie,
Daj mi znać, jak to zmienia twoje osiągi i mogę je dalej dostosowywać w razie potrzeby.
Jeśli chodzi o niezalogowane tabele, jeśli tabele tymczasowe zawierają dane tymczasowe, które są efemeryczne i, jak wspomniano, są tworzone podczas sesji, lepiej jest używać niezalogowanych tabel.
Możesz skrócić sesję tabelową po sesji, jeśli jest to dopuszczalne.
Więcej informacji tutaj - http://michael.otacoo.com/postgresql-2/unlogged-table-performance-in-postgresql-9-1/
Nie jestem pewien, dlaczego potrzebujesz tabel tymczasowych do replikacji. Nie możesz używać replikacji strumieniowej PostgreSQL?
źródło
Korzystanie z tabel tymczasowych i utrzymywanie długotrwałych połączeń (prawdopodobnie dotyczy to puli połączeń) może być dużym obciążeniem, jeśli serwer nie jest do tego przygotowany. Jednym z parametrów PostgreSQL, z którym można grać, jest
temp_buffers
kontrolowanie pamięci RAM przydzielonej do tabel tymczasowych. Te tymczasowe bufory są przydzielane dla każdego połączenia, a wartość domyślna (8 MB) jest prawdopodobnie zbyt niska dla Twojej witryny.Być może musisz również zmienić nieco zachowanie aplikacji klienckiej, w zależności od sposobu korzystania z tabel tymczasowych. Istnieje podobne pytanie z ładną odpowiedzią na temat przepełnienia stosu .
źródło
temp_buffers
. Czy możesz nam również powiedzieć, jaki jest rozmiar bazy danych, którą próbujesz powielić? Ile tabel, średni rozmiar na tabelę i całkowity rozmiar DB?Czy możesz opublikować plik postgresql.conf? Twój postgresql wydaje się znacznie niedostatecznie zoptymalizowany.
Czy możesz także opublikować:
Jeśli używasz niezalogowanych tabel do tabel tymczasowych?
Ile dysków i w jakiej konfiguracji RAID?
źródło