可怕的PostgreSQLlocking性能

我最近注意到在运行数据库服务器几个月之后,PostgreSQL的locking性能下降了。 网站的负载这几周增加了很多,但是速度越来越慢。

$ psql webspace2_db psql (9.0.1) Type "help" for help. webspace2_db=# 

数据库服务器运行FreeBSD 8.1 + PostgreSQL 9.0.1

 FreeBSD Moncalvo 8.1-RELEASE-p2 FreeBSD 8.1-RELEASE-p2 #1: Mon Jan 10 13:02:48 MYT 2011 hailang@Moncalve:/usr/obj/usr/src/sys/Moncalve amd64 

服务器上的内存总量为4GB

 Moncalvo# cat /var/run/dmesg.boot | grep memory real memory = 4294967296 (4096 MB) avail memory = 4101955584 (3911 MB) 

内核configuration中共有3GB的共享内存

 # Shared Memory options SEMMNI=256 options SEMMSL=128 options SEMMNS=32768 options SEMMAP=512 options SEMMNU=256 options SEMOPM=128 options SHMMNI=512 options SHMSEG=256 options SHMMAX=3221225472 options SHMALL=3221225472 options SHMMAXPGS=786432 

这些是关键的postgresql.conf设置

 Moncalvo# cat postgresql.conf | grep shared_buffers shared_buffers = 512MB # min 128kB Moncalvo# cat postgresql.conf | grep effective_cache_size effective_cache_size = 3276MB Moncalvo# cat postgresql.conf | grep work_mem work_mem = 256MB # min 64kB maintenance_work_mem = 128MB # min 1MB 

根据网站越来越慢的用户,我已经调整了另一台服务器上的Web服务,但没有有效的性能改进,所以我想这可能是数据库服务器的问题。 所以我logging缓慢的查询,发现其中大部分是locking机制,一些消耗的时间是可怕的。

 LOG: duration: 4768697.255 ms statement: SELECT pg_advisory_lock(93690) LOG: duration: 4739020.976 ms statement: SELECT pg_advisory_lock(93690) LOG: duration: 4709376.119 ms statement: SELECT pg_advisory_lock(93690) LOG: duration: 4679438.894 ms statement: SELECT pg_advisory_lock(93690) LOG: duration: 4649714.811 ms statement: SELECT pg_advisory_lock(93690) LOG: duration: 4619931.184 ms statement: SELECT pg_advisory_lock(93690) LOG: duration: 4590323.188 ms statement: SELECT pg_advisory_lock(93690) LOG: duration: 4560627.214 ms statement: SELECT pg_advisory_lock(93690) LOG: duration: 4530796.297 ms statement: SELECT pg_advisory_lock(93690) LOG: duration: 4501178.286 ms statement: SELECT pg_advisory_lock(93690) LOG: duration: 4471515.579 ms statement: SELECT pg_advisory_lock(93690) LOG: duration: 4441832.934 ms statement: SELECT pg_advisory_lock(93690) LOG: duration: 4410774.012 ms statement: SELECT pg_advisory_lock(93690) LOG: duration: 4382435.595 ms statement: SELECT pg_advisory_lock(93690) 

任何帮助和build议,高度赞赏。

我不是一个数据库专家,但它看起来像你的应用程序中某处的咨询锁的无效使用。

PostgreSQL提供了创build具有应用程序定义含义的锁的方法。 这些被称为咨询锁,因为系统不强制使用它 – 正确地使用它们取决于应用程序。

像PostgreSQL中的所有锁一样,任何会话当前持有的build议锁的完整列表可以在pg_locks系统视图中find。

编辑:

看着moodle 源代码 , /moodle/lib/dml/pgsql_native_moodle_database.php moodle/ /moodle/lib/dml/pgsql_native_moodle_database.php我刚刚发现了一些东西,这可能很有趣:

 public function get_session_lock($rowid) { // NOTE: there is a potential locking problem for database running // multiple instances of moodle, we could try to use // pg_advisory_lock(int, int), luckily there is not a big chance // that they would collide if (!$this->session_lock_supported()) { return; } parent::get_session_lock($rowid); $sql = "SELECT pg_advisory_lock($rowid)"; ... }