使用PostgreSQL 9.1.2
我看到过多的CPU使用率以及来自邮局主管任务的大量磁盘写操作。即使我的应用程序几乎什么也不做(每分钟10次插入),也会发生这种情况。但是,有相当数量的连接打开。
我一直在尝试确定导致应用程序崩溃的原因。我对Postgresql相当陌生,到目前为止还没有到位。我在配置文件中打开了一些日志记录选项,并查看了pg_stat_activity表中的连接,但是它们都处于空闲状态。但是,每个连接消耗约50%的CPU,并且正在以每秒15M / s的速度向磁盘写入数据(不读取内容)。
我基本上是通过很少的调整来使用stock 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
更新:在postmaster进程上运行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多年,已经在许多项目中使用。过去一两年,我们仅使用PostgreSQL。实际上,我们将临时表用作复制机制的一部分。每当建立新连接时,我们都会为数据库中的每个表创建一个临时表。使用10-20个(长寿命)连接和约50个表,这可能会导致大量临时表。所有临时表都使用以下命令创建:
CREATE TEMPORARY TABLE... ON COMMIT DELETE ROWS;
临时表的语义非常适合我们的复制方案,并且简化了许多我们必须用于MySQL的代码,但是看起来实现也不公平。从我所做的研究来看,我认为临时表并不是真正用于我们使用它们的功能。
我不是该主题的内部专家(甚至不是亲密的专家),只是该主题的使用者,所以我的解释可能不是100%准确,但我认为这很接近。