最近、DBサーバーを数か月実行した後、非常にひどいPostgreSQLロックパフォーマンスの低下に気づきました。ウェブサイトの負荷はここ数週間大幅に増加しましたが、速度は遅くなっています。
$ psql webspace2_db
psql (9.0.1)
Type "help" for help.
webspace2_db=#
DBサーバーはFreeBSD8.1 + PostgreSQL9.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)
カーネル構成では、合計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
最近はウェブサイトがどんどん遅くなっているとのことで、別のサーバーでウェブサービスをたくさん調整しましたが、効果的なパフォーマンスの向上は見られなかったので、DBサーバーに問題があるのではないかと思います。だから私は遅いクエリを記録し、それらのほとんどがロックメカニズムを備えていることを発見しました、そして消費された時間のいくつかはひどいです。
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)
どんな助けや提案も大歓迎です。
私はDBの専門家ではありませんが、アプリケーションのどこかで Advisory Locks を無効に使用しているようです。
PostgreSQLは、アプリケーション定義の意味を持つロックを作成するための手段を提供します。システムがそれらの使用を強制しないため、これらはアドバイザリロックと呼ばれます—それらを正しく使用するのはアプリケーション次第です。
そして
PostgreSQLのすべてのロックと同様に、現在任意のセッションで保持されているアドバイザリロックの完全なリストは、 pg_locks システムビューにあります。
編集:
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)";
...
}