Этот баннер — требование Роскомнадзора для исполнения 152 ФЗ.
«На сайте осуществляется обработка файлов cookie, необходимых для работы сайта, а также для анализа использования сайта и улучшения предоставляемых сервисов с использованием метрической программы Яндекс.Метрика. Продолжая использовать сайт, вы даёте согласие с использованием данных технологий».
Политика конфиденциальности
|
|
|
SAVEPOINT в ХП
|
|||
|---|---|---|---|
|
#18+
Привет всем! Вопрос такой: имеется ХП с куском кода внутри вида ... for i in select * from table_1 loop insert into table_2 (id,name) values (i.id,i.name); end loop; ... Если table_1 достаточно велика, то ХП выполняется продолжительное время. Если table_1 активно используемая таблица, то ХП начинает лочить другие запросы. Никак не могу найти вразумительного описания, возможно ли использование savepoint в виде ... for i in select * from table_1 loop insert into table_2 (id,name) values (i.id,i.name); SAVEPOINT p_1; end loop; ... для решения моей проблемы? Иными словами: ХП выполняется долго, лочит другие транзакции, нужно сделать, чтобы и другие запросы работали. Возможно ли это сделать с помощью SAVEPOINT? Заранее спасибо. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.04.2006, 17:03 |
|
||
|
SAVEPOINT в ХП
|
|||
|---|---|---|---|
|
#18+
Я чего-то, наверное, не понимаю. Каким образом возникла мысль, что Savepoint может помочь в такой ситуации? ;) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.04.2006, 17:15 |
|
||
|
SAVEPOINT в ХП
|
|||
|---|---|---|---|
|
#18+
Да были, конечно, смутные сомнения, что это не из той оперы, но не было определенности. Значит, не поможет? Выход - вынести цикл во вне ХП или есть что-то более изящное? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.04.2006, 17:59 |
|
||
|
SAVEPOINT в ХП
|
|||
|---|---|---|---|
|
#18+
Код: plaintext 1. 2. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.04.2006, 18:37 |
|
||
|
SAVEPOINT в ХП
|
|||
|---|---|---|---|
|
#18+
Дело не в том, работает или нет. Дело в том, что лочит, если table_1 большая и частоиспользуемая. А нужно чтобы всем было хорошо. Кроме того, пример утрирован. На самом деле в ХП на одной итерации делается несколько select и insert :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.04.2006, 10:49 |
|
||
|
SAVEPOINT в ХП
|
|||
|---|---|---|---|
|
#18+
SOmniДело не в том, работает или нет. Дело в том, что лочит, если table_1 большая и частоиспользуемая. А нужно чтобы всем было хорошо. Кроме того, пример утрирован. На самом деле в ХП на одной итерации делается несколько select и insert :) Может из за ключей лочится таблица? Ваще можно структуру таблицы ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.04.2006, 15:52 |
|
||
|
SAVEPOINT в ХП
|
|||
|---|---|---|---|
|
#18+
К сожалению, структуру раскрыть не могу. Но ключи (ИМХО, разумеется) тут не при чем. При чем тут то, что таблица активно update-ится / insert-ится / select-ится, а тут ее лочит одна очень долгая транзакция. Да я уже вынес цикл во вне, так что моя конкретная проблема решена (может, не совсем изящно, но другого способа не нашел). Можно, видимо, подумать еще что-то с уровнями изоляции, но заморочки не стоят эффекта, думается мне... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.04.2006, 16:17 |
|
||
|
SAVEPOINT в ХП
|
|||
|---|---|---|---|
|
#18+
Вообще (насколько я понимаю) в postgres не явно можно залочить только попыткой конурирующего апдейта одной строки (или select for update, или select for share + select for update или update) Правда еще была заморочка с foreign key, утверждают, что исправили. В любом случае - транзакция, делающая только select по таблице, не может лочит эту таблицу, если никто не пытается использовать явный lock table ... in mode ... . Видимо лочатся другие таблицы. Я могу ошибаться - почему вы думаете, что залочена именно эта таблица (table_1)? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.04.2006, 17:23 |
|
||
|
SAVEPOINT в ХП
|
|||
|---|---|---|---|
|
#18+
Funny_FalconВообще (насколько я понимаю) в postgres не явно можно залочить только попыткой конурирующего апдейта одной строки (или select for update, или select for share + select for update или update) Правда еще была заморочка с foreign key, утверждают, что исправили. В любом случае - транзакция, делающая только select по таблице, не может лочит эту таблицу, если никто не пытается использовать явный lock table ... in mode ... . Видимо лочатся другие таблицы. Я могу ошибаться - почему вы думаете, что залочена именно эта таблица (table_1)? А с ключами что правда исправили??!?!? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.04.2006, 17:25 |
|
||
|
SAVEPOINT в ХП
|
|||
|---|---|---|---|
|
#18+
Я могу ошибаться - почему вы думаете, что залочена именно эта таблица (table_1)? Хммм... и правда. Хотя, возможность залочки других важных таблиц крайне мала. Вообще, дейсвия такие (прошу прощения, что сразу не описал должным образом): for i in select * from table_1 loop insert into j count(*) as cnt from MEGA_TABLE where id_1=i.id and ещё много всего if j.cnt>1 then insert into table_a (j.cnt,...); end if; insert into j count(*) as cnt from MEGA_TABLE where id_1=i.id and ещё много всего другого if j.cnt>1 then insert into table_b (j.cnt,...); end if; ...................... end if; end loop; Так вот эти самые table_a, table_b - это редко используемые справочники. В это время клиенты начинают делать insert into MEGA_TABLE, на on_insert которой стоит в том числе update table_1. Т.к. все эти клиенты подвисают, а по ps ax | grep postgre видим застопорившиеся соединения (в различных стадиях), то делаю вывод, что лочится либо table_1 либо MEGA_TABLE. ------------------ Структуру, триггеры и ХП не могу предоставить не только потому, что проект коммерческий и у меня договор, но и потому, что там очень много всего, разбираться будет невозможно или лень. Уж лучше попробовать на таких абстракциях, мне кажется... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.04.2006, 18:14 |
|
||
|
SAVEPOINT в ХП
|
|||
|---|---|---|---|
|
#18+
ВАХ-ВАХ, опечатка, конечно же :) всё выглядит так (в ХП insert = select): ---------- Я могу ошибаться - почему вы думаете, что залочена именно эта таблица (table_1)? Хммм... и правда. Хотя, возможность залочки других важных таблиц крайне мала. Вообще, дейсвия такие (прошу прощения, что сразу не описал должным образом): for i in select * from table_1 loop select into j count(*) as cnt from MEGA_TABLE where id_1=i.id and ещё много всего if j.cnt>1 then insert into table_a (j.cnt,...); end if; select into j count(*) as cnt from MEGA_TABLE where id_1=i.id and ещё много всего другого if j.cnt>1 then insert into table_b (j.cnt,...); end if; ...................... end if; end loop; Так вот эти самые table_a, table_b - это редко используемые справочники. В это время клиенты начинают делать insert into MEGA_TABLE, на on_insert которой стоит в том числе update table_1. Т.к. все эти клиенты подвисают, а по ps ax | grep postgre видим застопорившиеся соединения (в различных стадиях), то делаю вывод, что лочится либо table_1 либо MEGA_TABLE. ------------------ Структуру, триггеры и ХП не могу предоставить не только потому, что проект коммерческий и у меня договор, но и потому, что там очень много всего, разбираться будет невозможно или лень. Уж лучше попробовать на таких абстракциях, мне кажется... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.04.2006, 18:16 |
|
||
|
SAVEPOINT в ХП
|
|||
|---|---|---|---|
|
#18+
пробовал конкретно локи посмотреть? есть такая табличка (или вьюшка) называется pg_locks в ней даже написано лочит одна транзакция другую или нет.. есть еще табличка pg_stat_activity в ней текущие запросы.. это все можно заджойнить с pg_class и ты точно узнаеш.. лочится что то или у тебя винт проседает. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.04.2006, 18:48 |
|
||
|
SAVEPOINT в ХП
|
|||
|---|---|---|---|
|
#18+
wbear дело говорит. on_insert которой стоит в том числе update table_1 Так если два клиента пытаются апдейтить одну строку, то второй залочиться, пока первый не с коммититься/откатнется. А если он еще кого-то ждет, то и получаем. А соединение, где этот цикл пашет, точно не трогает table_1 кроме как для селекта? Или может оно еще где строку апдейтит, которую другие тож пытаются ? Тогда и получится - dead lock-а нет, а все ждет наш цикл. PS. Правда еще была заморочка с foreign key, утверждают, что исправили. - в версии 8.1 введен shared lock на строку (в частности появилось select for share) - за счет этого и foreing keys разлочились :-) говорят ... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.04.2006, 17:20 |
|
||
|
SAVEPOINT в ХП
|
|||
|---|---|---|---|
|
#18+
Funny_Falcon wbear дело говорит. on_insert которой стоит в том числе update table_1 Так если два клиента пытаются апдейтить одну строку, то второй залочиться, пока первый не с коммититься/откатнется. А если он еще кого-то ждет, то и получаем. А соединение, где этот цикл пашет, точно не трогает table_1 кроме как для селекта? Или может оно еще где строку апдейтит, которую другие тож пытаются ? Тогда и получится - dead lock-а нет, а все ждет наш цикл. одну строку они не должны трогать, т.к. ХП работает с уже отработанными записями, т.е. которые не подлежат изменению (это прописано в условии ... from MEGA_TABLE where ...), причем за вчера. Когда делается insert into MEGA_TABLE, то это происходит сегодня и не должно удовлетворить условию where... Что касается вышеуказанных таблиц, то сейчас на них смотрю, но пока ничего не понимаю :) Если лочивший запрос можно увидеть в pg_stat_activity.current_query, так там у меня везде <command string not enabled>, а вообще интересно, конечно... буду ковырять... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.04.2006, 13:18 |
|
||
|
SAVEPOINT в ХП
|
|||
|---|---|---|---|
|
#18+
P.S. винт вряд ли проседает, ибо своп не юзается... или это не связано? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.04.2006, 13:25 |
|
||
|
SAVEPOINT в ХП
|
|||
|---|---|---|---|
|
#18+
своп почти на 100% тут не причем... просто ты пытаешся выяснить что чем лочится при этом есть только догадка что что-то чем то лочится.. а ты в этом уверен прям на 100%? это всеравно что говорить.. "оно должно использоват индекс и работать быстро, а оно работает медленно" при этом даж не заглянув в explain.. мож у тебя какой-нить вакум ее лочит.. или еще чтонить про что ты забыл.. посмотри в pg_locks найди запрос который залочен и посмотри запросы которые залочили эту таблицу ...мож и вопрос моментально отпадет. а так годать можно долго... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.04.2006, 13:51 |
|
||
|
SAVEPOINT в ХП
|
|||
|---|---|---|---|
|
#18+
wbearесть такая табличка (или вьюшка) называется pg_locks хм. вот сморю у себя дико долго сполняющийся в 7.3. заброс вида Код: plaintext 1. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. (унутре у нее неонка - в триггере бефоре инсерт идет проверка всех вставляемых полей (а поскоку IS DISTINCT FROM в 7.3. в процедурах наворачиваецца, то гробоватыми конструкциями) и, затем, либо RETURN NULL, либо UPDATE (поля "actual" другой записи) +RETURN NEW, либо проосто RETURN NEW. и всего 8000 записей "впендюливаюцца" у меня (сейчас) уже дольше 1500 секунд (одна запись ~ 20-ки милисекунд) И с чем это можно связать? Картина блокировок практицки не меняецца (порядок разве что). сижу и чешу репу. - по смыслу и триггер и набор записей таков, что дважды запись меняцца не может. т.е., кажецца, должен итти линейный рост времени с ростом числа "вставляемых" записев. Ну разве уникальный индекс есь в таблитце назначения. Но я вставляю в тесте уже ранее вставленный набор, для которого вообще должно всегда быть RETURN NULL; - т.е. ваще ничего не должно перестраивацца. И чо еще можно проверить? (наверное придецца вернуться к варианту без UPDATE - с отдельной табличкой актуальных ключей) Там, вродеба, не было такого напряга. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.04.2006, 14:23 |
|
||
|
SAVEPOINT в ХП
|
|||
|---|---|---|---|
|
#18+
PS: дождался Query returned successfully: 0 rows affected, 1977031 ms execution time. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.04.2006, 14:25 |
|
||
|
SAVEPOINT в ХП
|
|||
|---|---|---|---|
|
#18+
добавил лишнюю та-блитцу (шобы не апдейтить длинные записи, значица, а ключики онли) получил Query returned successfully: 0 rows affected, 1159312 ms execution time.мдя-с. кажецца в кансерватории чото нада минять. буду пробовать пес триккеров - одной ха-пой (при большом кол-ве совпадений должно полегчать?). кхммм. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.04.2006, 15:38 |
|
||
|
SAVEPOINT в ХП
|
|||
|---|---|---|---|
|
#18+
wbearсвоп почти на 100% тут не причем... просто ты пытаешся выяснить что чем лочится при этом есть только догадка что что-то чем то лочится.. а ты в этом уверен прям на 100%? это всеравно что говорить.. "оно должно использоват индекс и работать быстро, а оно работает медленно" при этом даж не заглянув в explain.. мож у тебя какой-нить вакум ее лочит.. или еще чтонить про что ты забыл.. посмотри в pg_locks найди запрос который залочен и посмотри запросы которые залочили эту таблицу ...мож и вопрос моментально отпадет. а так годать можно долго... Да я ж говорю, что там не видно, то за запрос лочит (или я еще не научился, как)... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.04.2006, 16:17 |
|
||
|
SAVEPOINT в ХП
|
|||
|---|---|---|---|
|
#18+
а это чаво тада -враки? PgDoc8 ACCESS SHARE Conflicts with the ACCESS EXCLUSIVE lock mode only. The commands SELECT and ANALYZE acquire a lock of this mode on referenced tables. In general, any query that only reads a table and does not modify it will acquire this lock mode. ......... ACCESS EXCLUSIVE Conflicts with locks of all modes (ACCESS SHARE, ROW SHARE, ROW EXCLUSIVE, SHARE UPDATE EXCLUSIVE, SHARE, SHARE ROW EXCLUSIVE, EXCLUSIVE, and ACCESS EXCLUSIVE). This mode guarantees that the holder is the only transaction accessing the table in any way. Acquired by the ALTER TABLE, DROP TABLE, REINDEX, CLUSTER, and VACUUM FULL commands. This is also the default lock mode for LOCK TABLE statements that do not specify a mode explicitly. Tip Only an ACCESS EXCLUSIVE lock blocks a SELECT (without FOR UPDATE/SHARE) statement. ну мож инсерт неявно индекс ковыряет и никому не говорит об этом.. но энто бред помойму... или я вообще чего-то не понимаю. :/ ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.04.2006, 17:11 |
|
||
|
SAVEPOINT в ХП
|
|||
|---|---|---|---|
|
#18+
мож опция какая не включена... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.04.2006, 17:52 |
|
||
|
SAVEPOINT в ХП
|
|||
|---|---|---|---|
|
#18+
4321 Query returned successfully: 0 rows affected, 1159312 ms execution time.мдя-с. кажецца в кансерватории чото нада минять. буду пробовать пес триккеров - одной ха-пой (при большом кол-ве совпадений должно полегчать?). кхммм. оффтоп. простой хапой в LOOP-е палучилась ~200-300 сек - просто сэмулировал вставку и отработку триккера внутри цикла. Изгитрившись засандалить логику в 2 SQL инсрукции (UPDATE + INSERT ) получилась без LOOP-ы ~3 сек. Мдя-с. "Парядка 2 туда, парядка 2 сюда". чёб такое фыппить? /оффтоп. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.04.2006, 18:59 |
|
||
|
SAVEPOINT в ХП
|
|||
|---|---|---|---|
|
#18+
4321 оффтоп./оффтоп.на [оффтоп.]8.1 то же самое, что и в 7.хх, тот же объем: триггер на кажинную запиздь 130.906 сек луп по усем запиздям 11.437 сек скл ф-я 0.513 сек[/оффтоп.] таки скл на массовую обработку работает на порядок быстрее лупа в плпг, и на более чем 2 порядка шибче триггера на кажную запись (особливо, видимо, когда результат работы практицки пуст). Странно? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.04.2006, 13:58 |
|
||
|
SAVEPOINT в ХП
|
|||
|---|---|---|---|
|
#18+
вероятно это потому что в хп все запросы по одному и томуже плану выполняются, а когда внешний луп оно новый создает план на каждый запрос который может быть ефективнее первого. попробуй тожесамое тока в хп через execute запросы выполнять... заодно проверим мою гипотезу :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.04.2006, 15:50 |
|
||
|
|

start [/forum/topic.php?fid=53&msg=33661768&tid=2006462]: |
0ms |
get settings: |
8ms |
get forum list: |
12ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
80ms |
get topic data: |
10ms |
get forum data: |
2ms |
get page messages: |
63ms |
get tp. blocked users: |
1ms |
| others: | 267ms |
| total: | 449ms |

| 0 / 0 |
