menggunakan PostgreSQL 9.1.2
Saya melihat penggunaan CPU yang berlebihan dan sejumlah besar penulisan ke disk dari tugas-tugas postmaster. Ini terjadi bahkan ketika aplikasi saya hampir tidak melakukan apa-apa (10s sisipan per MENIT). Namun ada sejumlah koneksi terbuka yang masuk akal.
Saya sudah mencoba menentukan apa yang menyebabkan aplikasi saya ini. Saya cukup pemula dengan postgresql, dan sejauh ini belum sampai ke mana pun. Saya telah mengaktifkan beberapa opsi logging di file config saya, dan melihat koneksi di tabel pg_stat_activity, tetapi semuanya idle. Namun setiap koneksi mengkonsumsi ~ 50% CPU, dan menulis ~ 15M / s ke disk (tidak membaca).
Saya pada dasarnya menggunakan stock postgresql.conf dengan sedikit sekali tweak. Saya menghargai saran atau petunjuk tentang apa yang bisa saya lakukan untuk melacak ini.
Berikut ini contoh apa yang ditunjukkan oleh 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
Pembaruan : Banyak penulisan file sepertinya merupakan beberapa file sementara (?) Di direktori $ PG_DATA / base /. Pemahaman saya tentang struktur file di sini adalah bahwa setiap tabel pada dasarnya disimpan sebagai file yang namanya OID dari tabel. Namun, ada berton-ton file yang dinamai tnn_nnnnnnn
, dan file-file inilah yang tampaknya selalu ditulis (mungkin ditulis). Untuk apa file-file ini? Ada ~ 4700 file, dan semuanya berukuran 8K:
-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
Pembaruan : Menjalankan strace pada proses postmaster pada dasarnya menunjukkan banyak hal I / O 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
Pembaruan : Jadi masalah ini sepertinya adalah segala sesuatu yang berkaitan dengan tabel sementara. Kami mengubah pengaturan kami sehingga tabel sementara adalah tabel 'biasa', dan semua aktivitas disk hilang, dan kinerja kembali ke tempat yang saya harapkan. Sekarang, perubahan ini hanyalah tes cepat dan kotor: jika kita benar-benar akan berubah menggunakan tabel biasa, kita memiliki masalah dengan konkurensi, dan pembersihan. Apakah meja sementara benar-benar jahat, atau kita menyalahgunakannya?
Perbarui : Beberapa latar belakang lagi. Saya menggunakan middleware replikasi berbasis pernyataan dikembangkan in-house . Ini cukup matang dan telah digunakan pada sejumlah proyek selama beberapa tahun, tetapi menggunakan MySQL. Kami hanya bekerja dengan PostgreSQL selama satu atau dua tahun terakhir. Kami pada dasarnya menggunakan tabel sementara sebagai bagian dari mekanisme replikasi. Setiap kali koneksi baru dibuat, kami membuat tabel sementara untuk setiap tabel dalam database. Dengan koneksi 10-20 (berumur panjang) dan ~ 50 tabel, ini bisa berjumlah banyak tabel sementara. Semua tabel sementara dibuat dengan:
CREATE TEMPORARY TABLE... ON COMMIT DELETE ROWS;
Semantik tabel sementara sangat sesuai dengan skema replikasi kami, dan menyederhanakan banyak kode yang harus kami gunakan untuk MySQL, tetapi sepertinya implementasinya juga tidak adil. Dari sedikit riset yang telah saya lakukan, saya tidak berpikir tabel sementara benar-benar dimaksudkan untuk fungsi yang kami gunakan.
Saya bukan ahli dalam-rumah (bahkan tidak dekat) tentang hal ini, hanya pengguna, jadi penjelasan saya mungkin tidak 100% akurat, tapi saya pikir itu cukup dekat.