我最近注意到在运行数据库服务器几个月之后,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)"; ... }