PostgreSQL Диагностика простоя в транзакции и чтение pg_locks - PullRequest
14 голосов
/ 23 июля 2010

Настройка: несколько веб-серверов, на которых запущены mod_wsgi, Apache и pgbouncer, которые подключаются к общей базе данных с Postgres 8.3.6. Приложение работает под управлением Django.

То, что мы видим: запросы «бездействия в транзакции» к БД, которые зависают в течение длительного времени. Чтобы их увидеть, я запусту что-то вроде этого:

SELECT query_start, procpid, client_addr, current_query FROM pg_stat_activity
WHERE query_start < NOW() - interval '5 minutes';

Большинство результатов, конечно, являются просто соединениями IDLE, которые pgbouncer сохраняет открытыми для использования, но иногда встречаются старые запросы «IDLE в транзакции». Я понимаю, что это означает, что существует транзакция запроса, которая ожидает чего-то или чего-то, что имеет НАЧАЛО, но не достигло COMMIT или ROLLBACK.

Мой следующий шаг - попытаться использовать pg_locks для определения того, что ожидает процесс:

select pg_class.relname, pg_locks.transactionid, pg_locks.mode,
       pg_locks.granted as "g", pg_stat_activity.current_query,
       pg_stat_activity.query_start,
       age(now(),pg_stat_activity.query_start) as "age",
       pg_stat_activity.procpid 
from pg_stat_activity,pg_locks
left outer join pg_class on (pg_locks.relation = pg_class.oid)  
where pg_locks.pid=pg_stat_activity.procpid
and pg_stat_activity.procpid = <AN IDLE TRANSACTION PROCESS>
order by query_start;

Часто получаемый результат выглядит так:

 relname | transactionid |      mode       | g |     current_query     |         query_start          |       age       |  client_addr   | procpid 
---------+---------------+-----------------+---+-----------------------+------------------------------+-----------------+----------------+---------
         |               | AccessShareLock | t | <IDLE> in transaction | 2010-07-22 15:33:11.48136-04 | 00:23:35.029045 | 192.168.100.99 |    1991
         |               | AccessShareLock | t | <IDLE> in transaction | 2010-07-22 15:33:11.48136-04 | 00:23:35.029045 | 192.168.100.99 |    1991
         |               | AccessShareLock | t | <IDLE> in transaction | 2010-07-22 15:33:11.48136-04 | 00:23:35.029045 | 192.168.100.99 |    1991
         |               | AccessShareLock | t | <IDLE> in transaction | 2010-07-22 15:33:11.48136-04 | 00:23:35.029045 | 192.168.100.99 |    1991
         |               | AccessShareLock | t | <IDLE> in transaction | 2010-07-22 15:33:11.48136-04 | 00:23:35.029045 | 192.168.100.99 |    1991
         |               | AccessShareLock | t | <IDLE> in transaction | 2010-07-22 15:33:11.48136-04 | 00:23:35.029045 | 192.168.100.99 |    1991
         |               | AccessShareLock | t | <IDLE> in transaction | 2010-07-22 15:33:11.48136-04 | 00:23:35.029045 | 192.168.100.99 |    1991
         |               | AccessShareLock | t | <IDLE> in transaction | 2010-07-22 15:33:11.48136-04 | 00:23:35.029045 | 192.168.100.99 |    1991
         |               | ExclusiveLock   | t | <IDLE> in transaction | 2010-07-22 15:33:11.48136-04 | 00:23:35.029045 | 192.168.100.99 |    1991
         |               | AccessShareLock | t | <IDLE> in transaction | 2010-07-22 15:33:11.48136-04 | 00:23:35.029045 | 192.168.100.99 |    1991
(10 rows)

Я не уверен, как это читать (наверное, это связано с не совсем пониманием pg_locks). Там нет relname, так это говорит, что он ждет ни на чем? Я думал, что если дано было «правда», у него был замок. Поскольку все эти результаты предоставлены, pg_locks показывает мне блокировки, которые он имеет, а не то, что он ожидает?

Прямо сейчас я «исправляю» это, перезапуская Apache, который, кажется, расшатывает транзакции, но, очевидно, это не настоящее решение. Я ищу Postgres, чтобы дать мне место, где можно это выяснить, тем более что Django должен автоматически управлять своими соединениями и транзакциями.

1 Ответ

3 голосов
/ 23 июля 2010

В частности, для Django эта запись подробно объясняет, почему вы видите эту проблему:

Резьбовое задание Django ...

Я говорю здесь «конкретно», потому что реальная проблема заключается в том, что веб-фреймворки / драйверы / ORM все время работают в режиме на основе транзакций (и иногда вызывают откат после каждого чертова запроса SELECT), когда они действительно должны выполняться в Режим автоматической фиксации и обработка необходимости транзакций только по мере необходимости. Модуль персистентности Apache :: Sessions PostgreSQL был катастрофой (по крайней мере, несколько лет назад), поскольку он закрывал транзакции только тогда, когда собирал мусор. Хлоп!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...