PostgreSQL 9.1.2 사용
포스트 마스터 작업에서 과도한 CPU 사용량과 디스크에 대량의 쓰기가 발생하는 것을보고 있습니다. 이것은 내 응용 프로그램이 거의 아무것도하지 않는 동안에도 발생합니다 (분당 10 회 삽입). 그러나 적절한 수의 연결이 열려 있습니다.
내 응용 프로그램 에서이 원인을 확인하려고했습니다. 나는 postgresql을 처음 접했고 지금까지 얻지 못했습니다. 구성 파일에서 로깅 옵션을 설정하고 pg_stat_activity 테이블의 연결을 확인했지만 모두 유휴 상태입니다. 그러나 각 연결은 ~ 50 %의 CPU를 소비하고 ~ 15M / s를 디스크에 쓰고 있습니다 (읽기 없음).
기본적으로 재고 postgresql.conf를 약간 조정하여 사용하고 있습니다. 이 문제를 추적하기 위해 수행 할 수있는 작업에 대한 조언이나 조언을 부탁드립니다.
다음은 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
업데이트 : 많은 파일 쓰기가 $ PG_DATA / base / 디렉토리의 임시 파일 (?)에 대한 것 같습니다. 여기서 파일 구조에 대한 이해 는 각 테이블이 기본적으로 이름이 테이블의 OID 인 파일로 저장된다는 것입니다. 그러나라는 이름의 파일 tnn_nnnnnnn
이 많이 있으며 이러한 파일은 지속적으로 기록 된 것 같습니다. 이 파일들은 무엇입니까? ~ 4700 개의 파일이 있으며 모두 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
업데이트 : 포스트 마스터 프로세스에서 strace를 실행하면 기본적으로 많은 파일 I / O 항목이 표시됩니다.
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
업데이트 : 따라서이 문제는 임시 테이블과 관련된 모든 것으로 보입니다. 임시 테이블이 '일반적인'테이블이되도록 설정을 변경했으며 모든 디스크 작업이 사라졌으며 성능이 예상했던 위치로 돌아 왔습니다. 이제이 변경은 빠르고 더러운 테스트였습니다. 실제로 일반 테이블을 사용하도록 변경하려는 경우 동시성 및 정리 문제가 있습니다. 임시 테이블이 정말 사악합니까, 아니면 학대합니까?
업데이트 : 좀 더 배경. 사내에서 개발 한 명령문 기반 복제 미들웨어를 사용하고 있습니다. 그것은 성숙하고 수년에 걸쳐 많은 프로젝트에서 사용되고 있지만 MySQL을 사용하고 있습니다. 우리는 지난 1 ~ 2 년간 PostgreSQL 과만 협력했습니다. 기본적으로 복제 메커니즘의 일부로 임시 테이블을 사용했습니다. 새 연결이 설정 될 때마다 데이터베이스의 각 테이블에 대한 임시 테이블이 작성됩니다. 10-20 (긴 수명) 연결과 ~ 50 개의 테이블을 사용하면 많은 임시 테이블에이를 수 있습니다. 모든 임시 테이블은 다음을 사용하여 작성되었습니다.
CREATE TEMPORARY TABLE... ON COMMIT DELETE ROWS;
임시 테이블의 의미는 복제 체계와 매우 잘 맞으며 MySQL에 사용해야하는 많은 코드를 단순화했지만 구현도 공정하지 않은 것처럼 보입니다. 내가 한 약간의 연구에서 나는 임시 테이블이 실제로 우리가 사용했던 기능을 의미한다고 생각하지 않습니다.
나는이 주제에 대한 사내 전문가 (가까운조차도)가 아니며 단지 사용자이므로 내 설명은 100 % 정확하지는 않지만 꽤 가깝다고 생각합니다.