Postgres,不时挂起

我们使用Postgres作为我们的Django项目的数据库后端。 一切工作正常,除了不时Postgres的理由挂起。 平均峰值加载到80点,并有许多posgtres进程。 至于我看到有问题的是我们的网上用户表。 在每个请求都有更新,我们正在更新“上次看到”列。 在每分钟都有cronjob删除用户1分钟不活动。 而在今天的例子中,当有Postgres挂起时,我已经看到许多更新和从这个表中删除。 我认为这是一种竞争条件?

这个用户在线表格并不大。 在高峰时间有~800条logging。 这是模式。

Column | Type | Modifiers ------------+--------------------------+----------------------------------------------------------------- id | integer | not null default nextval('spoleczniak_online_id_seq'::regclass) postac_id | integer | not null data | timestamp with time zone | not null zalogowany | timestamp with time zone | not null Indexes: "spoleczniak_online_pkey" PRIMARY KEY, btree (id) "spoleczniak_online_postac_id_key" UNIQUE CONSTRAINT, btree (postac_id) "spoleczniak_online_data" btree (data) Foreign-key constraints: "spoleczniak_online_postac_id_fkey" FOREIGN KEY (postac_id) REFERENCES postac_postacie(id) DEFERRABLE INITIALLY DEFERRED 

通常Postgres产生的负载平均值小于1.5。 我们正在使用i7,16 GB内存,以及用于OS /数据+ RAID-1(2个磁盘)的硬件RAID-10(3×2磁盘)。 硬件RAID有512 MB的caching。

我已经试过9.0和9.1testing版(我甚至没有在9.1中为该表设置WAL日志)。

我真的想转移到MySQL,但不知道任何转换工具。 :P

PS。 我不知道它是更Serverfault或Stackoverflow的…但你可以看到我决定把它放在Serverfault。 :P

编辑:

日志中的一些信息:

 Jul 31 20:37:16 postgres postgres[1420]: [3-1] LOG: 00000: process 1420 acquired ExclusiveLock on tuple (29,7) of relation 33107 of database 20005 after 2071.481 ms Jul 31 20:37:16 postgres postgres[1420]: [3-2] LOCATION: ProcSleep, proc.c:1076 Jul 31 20:37:16 postgres postgres[1420]: [3-3] STATEMENT: UPDATE "spoleczniak_online" SET "postac_id" = 101651, "data" = '2011-07-31 20:39:18.000699', "zalogowany" = '2011-07-31 20:31:04.843741' WHERE "spoleczniak_online"."id" = 559650 Jul 31 20:37:16 postgres postgres[1493]: [3-1] LOG: 00000: process 1493 acquired ExclusiveLock on tuple (29,7) of relation 33107 of database 20005 after 1393.154 ms Jul 31 20:37:16 postgres postgres[1493]: [3-2] LOCATION: ProcSleep, proc.c:1076 Jul 31 20:37:16 postgres postgres[1493]: [3-3] STATEMENT: UPDATE "spoleczniak_online" SET "postac_id" = 101651, "data" = '2011-07-31 20:39:15.646537', "zalogowany" = '2011-07-31 20:31:04.843741' WHERE "spoleczniak_online"."id" = 559650 

所以好吧,这是locking问题…但我怎么能避免呢?

这看起来像locking问题:一些大的查询locking太多,所以其他正在运行的查询不能完成,直到locking释放。 打开慢速查询日志logging,添加更多监视。 我强烈build议使用一些监控系统(zabbix,zenoss等)来了解你的postgresql数据库状态。

作为一个快速的“监控”,在挂起期间看看pg_stat_activity和pg_locks的视图。 这是一个很好的查询,我经常从头开始:

 SELECT datname, NOW() - query_start AS duration, procpid, current_query FROM pg_stat_activity WHERE current_query <> '<IDLE>' AND NOW() - query_start > '1 second' ORDER BY duration DESC; 

它经常提供足够的信息,但有时候为了理解发生了什么,我必须跑更多。

请更新您的问题与此(或类似的)查询的输出。

我会推荐“ PostgreSQL 9.0高性能”一书第11章“数据库活动和统计”。 解决这个问题的另一个好地方就是postgresql性能邮件列表。