Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Повисшая транзакция / 14 сообщений из 14, страница 1 из 1
03.10.2006, 10:13
    #34027680
thedix
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Повисшая транзакция
Всех приветствую.

Работаю с pgsql 8.1.4.
Запускаю транзакцию, которая изменяет некоторые строки в таблице.
Код выглядит примерно так:
Код: plaintext
1.
2.
3.
4.
5.
$db->begin();
$res = $db->execute("INSERT INTO mytable (id, num, str, ts) VALUES (125, 1, 'str1', now())");
echo "waiting 10 seconds...\n";
sleep( 10 );
$db->execute("UPDATE mytable SET num = num+1 WHERE id=1");
$db->end();

Во время sleep-а скрипта обрываю подключение к бд, а потом убиваю скрипт.
Скрипт умирает, но процесс, обрабатывающий транзакцию остается работать на сервере в режиме "idle" 2 часа, при этом остаются заблокированными записи, которые начала править повисшая транзакция.
Это приводит к тому, что новая транзакция на тех же данных ждет время, указанное в statement_timeout. (по умолчанию - бесконечно)
Как сие разрулить?

Порылся в документации и нашел системную таблицу pg_locks, в которой хранится список текущих блокировок. К сожалению, там не указывается, с какого момента началась та или иная блокировка.
Для этого создается отдельная таблица примерно такой структуры:

Код: plaintext
1.
2.
3.
4.
5.
6.
CREATE TABLE trans
(
  pid int4 NOT NULL,
  xid int4 NOT NULL,
  ts timestamp NOT NULL
) 
где pid и xid - pid процесса и id транзакции, которая ожидает,
ts - с какого времени началась транзакция.

Далее каждую минуту в кроне читаем pg_locks, собираем инфу о начавшихся транзакциях и обновляем вышеописанную таблицу.
Как только ts достигла какого-то значения, посылаем процессу SIGTERM.

Думается, что существует какое-то стандартное решение, но я его не нашел.

Или можно ли как-то штатно изменить время ожидания процесса?
...
Рейтинг: 0 / 0
03.10.2006, 11:00
    #34027853
landy
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Повисшая транзакция
Насколько я понял суть в следующем
Работаем по TCP/IP, после того как убили процесс в sleep
backend об этом никак не догадывается. Далее он работает и слушает сокет, через 90 минут(если не изменяет мне память) неактивный сокет закрывается
стеком, бакенд отваливается
...
Рейтинг: 0 / 0
03.10.2006, 12:20
    #34028197
thedix
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Повисшая транзакция
landybackend об этом никак не догадывается
Да, вы все правильно поняли.
...
Рейтинг: 0 / 0
03.10.2006, 13:46
    #34028641
Andrew Sagulin
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Повисшая транзакция
Может покрутить tcp_keepalives_* в postgresql.conf?
...
Рейтинг: 0 / 0
03.10.2006, 19:22
    #34029899
thedix
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Повисшая транзакция
Andrew SagulinМожет покрутить tcp_keepalives_* в postgresql.conf?
Да, действительно, попробую. Спасибо.

Порыл еще мануалы, нашел, что если включить stats_command_string, то в системной вьюхе pg_stat_activity появляется время начала запроса и его текущий статус.
Таким образом, свою таблицу создавать не надо, достаточно выполнить запрос вида:
Код: plaintext
1.
2.
3.
SELECT procpid AS pid, EXTRACT(EPOCH FROM (now()-query_start))::integer AS duration
FROM pg_stat_activity
WHERE current_query='<IDLE> in transaction';

Задача упрощается, но все равно как-то через одно место.
Есть еще варианты?
...
Рейтинг: 0 / 0
04.10.2006, 13:31
    #34031494
wbear
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Повисшая транзакция
мож попробовать подписывать такие стремные коннекны на нотифаи..
те.

в приложении сразу после конекта делаеш например
Listen hup_notify;
потом все остальное..долгий селект...и т.д.

и переодически слать откудани-будь из крона например notify hup_notify;

есть подозрение что сразуже по приходу нотифая бакенд попытается его клиенту отправить по соединению .. и соответственно "узнает" что оно дохлое и благополучно помрет...
если получится отпиши плз.. т.к. самому интерестно.
...
Рейтинг: 0 / 0
05.10.2006, 09:13
    #34033464
thedix
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Повисшая транзакция
wbearмож попробовать подписывать такие стремные коннекны на нотифаи

Пробовал - бэкенд все равно продолжает висеть.
...
Рейтинг: 0 / 0
05.10.2006, 10:29
    #34033681
st_serg
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Повисшая транзакция
из моего опыта, нотифаи приходят только после того как клиент чтото послал серверу и ожидает от него результата. Т.е. что бы получать notify от сервера необходимо было выполнять периодически какой либо запрос (например select 1)
...
Рейтинг: 0 / 0
05.10.2006, 15:45
    #34035193
wbear
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Повисшая транзакция
не богатый опыт..
вот кусок на перле:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
my $fd = $db->func('getfd') or die "cant func getfd $!";
$db->do("LISTEN che");
my $rin ='';
my $rout;
vec($rin,$fd, 1 ) =  1 ;
my $timeout =  1 ;

while( 1 )
{
         ($nfound,$timeleft) = select($rout=$rin, undef, undef, $timeout ) or die "$!\n";
         while($ret = $db->func('pg_notifies'))
         {
              log_message("Event arrive ".$ret->[ 0 ]);
         }
}


асинхронные запросы обрабатываются аналогично.. так что как-то странно что
автор
Пробовал - бэкенд все равно продолжает висеть.

либо я чаво-то недо понимаю.
...
Рейтинг: 0 / 0
05.10.2006, 17:49
    #34035705
st_serg
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Повисшая транзакция
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.


т.е., насколько я понял, в любом случае активность должен проявлять клиент.
...
Рейтинг: 0 / 0
05.10.2006, 18:00
    #34035743
st_serg
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Повисшая транзакция
точнее в любом случае клиент должен проявлять активность (читать или проверять наличие данных на бекенде)

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.
...
Рейтинг: 0 / 0
06.10.2006, 08:38
    #34036470
thedix
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Повисшая транзакция
wbearлибо я чаво-то недо понимаю.
Видимо, я тоже.
С нотифаями не работал, но сделал так, как вы писали.
То есть один клиент вызывает listen, потом после еще одного запроса связь отрубаю.
Одновременно другим клиентом делаю периодические notify.
А бэкенд как висел, так и висит, умирать не хочет.
...
Рейтинг: 0 / 0
09.10.2006, 15:05
    #34041887
wbear
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Повисшая транзакция
st_serg
т.е., насколько я понял, в любом случае активность должен проявлять клиент.

нет.. посмотри внимательно.. перед $db->func('pg_notifies')
селект стоит с ожинадием возможности ЧТЕНИЯ с сокета..т.е ожиданием того что что-то придет на сокет.. т.е. сначало что-то отсылает бакенд клиенту, а только потом(если таймаут стоит в 0 есесно) мы вывалимся из селекта и заберем это функцией $db->func('pg_notifies') . т.е. в данном случае кокраз сервер инициатор..
вероятно ситуация меняется когда бакенд "занят" выполнением запроса.
...
Рейтинг: 0 / 0
10.10.2006, 08:30
    #34043188
thedix
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Повисшая транзакция
wbear
т.е. в данном случае кокраз сервер инициатор..

Получается, что послав нотифай с одного клиента для другого, получатель должен сначала выполнить запрос и только потом уже проверить наличие нотифая.

Если получатель отвалился, то он не сможет послать бакэнду селект и потом спросить нотифай.
...
Рейтинг: 0 / 0
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Повисшая транзакция / 14 сообщений из 14, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]