Этот баннер — требование Роскомнадзора для исполнения 152 ФЗ.
«На сайте осуществляется обработка файлов cookie, необходимых для работы сайта, а также для анализа использования сайта и улучшения предоставляемых сервисов с использованием метрической программы Яндекс.Метрика. Продолжая использовать сайт, вы даёте согласие с использованием данных технологий».
Политика конфиденциальности
|
|
|
Повисшая транзакция
|
|||
|---|---|---|---|
|
#18+
Всех приветствую. Работаю с pgsql 8.1.4. Запускаю транзакцию, которая изменяет некоторые строки в таблице. Код выглядит примерно так: Код: plaintext 1. 2. 3. 4. 5. Во время sleep-а скрипта обрываю подключение к бд, а потом убиваю скрипт. Скрипт умирает, но процесс, обрабатывающий транзакцию остается работать на сервере в режиме "idle" 2 часа, при этом остаются заблокированными записи, которые начала править повисшая транзакция. Это приводит к тому, что новая транзакция на тех же данных ждет время, указанное в statement_timeout. (по умолчанию - бесконечно) Как сие разрулить? Порылся в документации и нашел системную таблицу pg_locks, в которой хранится список текущих блокировок. К сожалению, там не указывается, с какого момента началась та или иная блокировка. Для этого создается отдельная таблица примерно такой структуры: Код: plaintext 1. 2. 3. 4. 5. 6. ts - с какого времени началась транзакция. Далее каждую минуту в кроне читаем pg_locks, собираем инфу о начавшихся транзакциях и обновляем вышеописанную таблицу. Как только ts достигла какого-то значения, посылаем процессу SIGTERM. Думается, что существует какое-то стандартное решение, но я его не нашел. Или можно ли как-то штатно изменить время ожидания процесса? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.10.2006, 10:13 |
|
||
|
Повисшая транзакция
|
|||
|---|---|---|---|
|
#18+
Насколько я понял суть в следующем Работаем по TCP/IP, после того как убили процесс в sleep backend об этом никак не догадывается. Далее он работает и слушает сокет, через 90 минут(если не изменяет мне память) неактивный сокет закрывается стеком, бакенд отваливается ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.10.2006, 11:00 |
|
||
|
Повисшая транзакция
|
|||
|---|---|---|---|
|
#18+
landybackend об этом никак не догадывается Да, вы все правильно поняли. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.10.2006, 12:20 |
|
||
|
Повисшая транзакция
|
|||
|---|---|---|---|
|
#18+
Может покрутить tcp_keepalives_* в postgresql.conf? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.10.2006, 13:46 |
|
||
|
Повисшая транзакция
|
|||
|---|---|---|---|
|
#18+
Andrew SagulinМожет покрутить tcp_keepalives_* в postgresql.conf? Да, действительно, попробую. Спасибо. Порыл еще мануалы, нашел, что если включить stats_command_string, то в системной вьюхе pg_stat_activity появляется время начала запроса и его текущий статус. Таким образом, свою таблицу создавать не надо, достаточно выполнить запрос вида: Код: plaintext 1. 2. 3. Задача упрощается, но все равно как-то через одно место. Есть еще варианты? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.10.2006, 19:22 |
|
||
|
Повисшая транзакция
|
|||
|---|---|---|---|
|
#18+
мож попробовать подписывать такие стремные коннекны на нотифаи.. те. в приложении сразу после конекта делаеш например Listen hup_notify; потом все остальное..долгий селект...и т.д. и переодически слать откудани-будь из крона например notify hup_notify; есть подозрение что сразуже по приходу нотифая бакенд попытается его клиенту отправить по соединению .. и соответственно "узнает" что оно дохлое и благополучно помрет... если получится отпиши плз.. т.к. самому интерестно. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.10.2006, 13:31 |
|
||
|
Повисшая транзакция
|
|||
|---|---|---|---|
|
#18+
wbearмож попробовать подписывать такие стремные коннекны на нотифаи Пробовал - бэкенд все равно продолжает висеть. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.10.2006, 09:13 |
|
||
|
Повисшая транзакция
|
|||
|---|---|---|---|
|
#18+
из моего опыта, нотифаи приходят только после того как клиент чтото послал серверу и ожидает от него результата. Т.е. что бы получать notify от сервера необходимо было выполнять периодически какой либо запрос (например select 1) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.10.2006, 10:29 |
|
||
|
Повисшая транзакция
|
|||
|---|---|---|---|
|
#18+
не богатый опыт.. вот кусок на перле: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. асинхронные запросы обрабатываются аналогично.. так что как-то странно что автор Пробовал - бэкенд все равно продолжает висеть. либо я чаво-то недо понимаю. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.10.2006, 15:45 |
|
||
|
Повисшая транзакция
|
|||
|---|---|---|---|
|
#18+
documentation With the libpq library, the application issues LISTEN as an ordinary SQL command, and then must periodically call the function PQnotifies to find out whether any notification events have been received. ... documentation ... A better way to check for NOTIFY messages when you have no useful commands to execute is to call PQconsumeInput, then check PQnotifies. т.е., насколько я понял, в любом случае активность должен проявлять клиент. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.10.2006, 17:49 |
|
||
|
Повисшая транзакция
|
|||
|---|---|---|---|
|
#18+
точнее в любом случае клиент должен проявлять активность (читать или проверять наличие данных на бекенде) You should, however, remember to check PQnotifies after each PQgetResult or PQexec, to see if any notifications came in during the processing of the command. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.10.2006, 18:00 |
|
||
|
Повисшая транзакция
|
|||
|---|---|---|---|
|
#18+
wbearлибо я чаво-то недо понимаю. Видимо, я тоже. С нотифаями не работал, но сделал так, как вы писали. То есть один клиент вызывает listen, потом после еще одного запроса связь отрубаю. Одновременно другим клиентом делаю периодические notify. А бэкенд как висел, так и висит, умирать не хочет. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.10.2006, 08:38 |
|
||
|
Повисшая транзакция
|
|||
|---|---|---|---|
|
#18+
st_serg т.е., насколько я понял, в любом случае активность должен проявлять клиент. нет.. посмотри внимательно.. перед $db->func('pg_notifies') селект стоит с ожинадием возможности ЧТЕНИЯ с сокета..т.е ожиданием того что что-то придет на сокет.. т.е. сначало что-то отсылает бакенд клиенту, а только потом(если таймаут стоит в 0 есесно) мы вывалимся из селекта и заберем это функцией $db->func('pg_notifies') . т.е. в данном случае кокраз сервер инициатор.. вероятно ситуация меняется когда бакенд "занят" выполнением запроса. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.10.2006, 15:05 |
|
||
|
Повисшая транзакция
|
|||
|---|---|---|---|
|
#18+
wbear т.е. в данном случае кокраз сервер инициатор.. Получается, что послав нотифай с одного клиента для другого, получатель должен сначала выполнить запрос и только потом уже проверить наличие нотифая. Если получатель отвалился, то он не сможет послать бакэнду селект и потом спросить нотифай. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.10.2006, 08:30 |
|
||
|
|

start [/forum/topic.php?fid=53&msg=34035705&tid=2006049]: |
0ms |
get settings: |
9ms |
get forum list: |
19ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
138ms |
get topic data: |
12ms |
get forum data: |
3ms |
get page messages: |
70ms |
get tp. blocked users: |
2ms |
| others: | 233ms |
| total: | 494ms |

| 0 / 0 |
