使用PostgreSQL 9.1.2
我看到过多的CPU使用率和大量的从postmaster任务写入磁盘。 即使我的应用程序几乎没有任何操作(每分钟10秒的插入),也会发生这种情况。 有一个合理的连接数打开然而。
我一直在试图确定什么在我的应用程序造成这一点。 我用postgresql很漂亮,到目前为止还没有到任何地方。 我已经在我的configuration文件中打开了一些日志logging选项,并查看了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
更新 :在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
更新 :所以这个问题似乎是临时表的一切。 我们改变了我们的设置,所以临时表是“常规”表,所有的磁盘活动都消失了,性能又回到了我预期的水平。 现在,这个变化只是一个快速和肮脏的testing:如果我们真的要改变使用常规表,我们有并发和清理的问题。 临时表是真的那么邪恶,还是我们在滥用呢?
更新 :一些更多的背景。 我正在使用一个内部开发的基于语句的复制中间件 。 它已经相当成熟,并且已经在很多年中用于一些项目,但是使用MySQL。 我们在过去的一两年里一直在使用PostgreSQL。 我们基本上使用临时表作为复制机制的一部分。 无论何时build立新的连接,我们都会为数据库中的每个表创build一个临时表。 有10-20(长寿命)的连接和50桌子,这可以相当于很多的临时表。 所有的临时表都是用
CREATE TEMPORARY TABLE... ON COMMIT DELETE ROWS;
临时表的语义非常适合我们的复制scheme,简化了许多我们必须用于MySQL的代码,但是看起来实现并不公平。 从我所做的一些研究中,我不认为临时表是真正用于我们使用它们的function的。
我不是这个问题的内部专家(甚至没有接近),只是一个用户,所以我的解释可能不是100%准确的,但我认为它非常接近。
你的PostgreSQLconfiguration是离开的。 这从你最初的post是可疑的,
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
在你服务器的32GB之外,〜25GB是免费的,不包括〜575MB的缓冲区。
从你的postgresql.conf文件中,
shared_buffers = 32MB # min 128kB #temp_buffers = 8MB # min 800kB #max_prepared_transactions = 0 # zero disables the feature ... #work_mem = 1MB # min 64kB #maintenance_work_mem = 16MB # min 1MB #max_stack_depth = 2MB
我假设这是一个专用的数据库。 如果是,请将其更改为以下参数并重新加载/重新启动,
shared_buffers = 16GB # min 128kB temp_buffers = 128MB # min 800kB #max_prepared_transactions = 0 # zero disables the feature ... work_mem = 8MB # min 64kB maintenance_work_mem = 64MB # min 1MB max_stack_depth = 4MB
请让我知道这是如何改变你的performance,并可以根据需要进一步调整。
如果您的临时表包含短暂的临时数据,并且正如您所提到的,在会话上创build,那么最好使用未logging的表。
如果可以接受的话,可以在会话后截断你的表。
更多信息在这里 – http://michael.otacoo.com/postgresql-2/unlogged-table-performance-in-postgresql-9-1/
我不确定为什么你需要临时表复制。 你不能使用PostgreSQLstream式复制吗?
如果你的服务器没有做好准备,使用临时表和长期连接(可能涉及到连接池)会是一个负担。 您可以尝试使用的一个PostgreSQL参数是temp_buffers ,它控制分配给临时表的RAM。 这些临时缓冲区是按每个连接分配的,默认值(8MB)可能对您的站点来说太低。
也许你还需要改变你的客户端应用程序的一些行为,这取决于你如何使用临时表。 有一个类似的问题, 堆栈溢出很好的答案 。
你能发布你的postgresql.conf文件吗? 你的postgresql似乎明显在优化下。
你能否也发帖:
如果您正在使用未logging的表格作为临时表格?
多less个磁盘和什么RAIDconfiguration?