[pgsql-ru-general] Re: [pgsql-ru-general] Re: [pgsql-ru-general] deadlock при drop index concurrently - Mailing list pgsql-ru-general

From Oleksii Kliukin
Subject [pgsql-ru-general] Re: [pgsql-ru-general] Re: [pgsql-ru-general] deadlock при drop index concurrently
Date
Msg-id 1490354827.2909511.922069000.70D450ED@webmail.messagingengine.com
Whole thread Raw
In response to [pgsql-ru-general] Re: [pgsql-ru-general] deadlock при drop index concurrently  (Вавржин Игорь <igor.vavrjin@gmail.com>)
List pgsql-ru-general

On Thu, Mar 23, 2017, at 02:09 PM, Вавржин Игорь wrote:
Лог я прочитал :) вопрос в другом: почему конкурентное удаление индекса просто не подаждало, пока локи снимутся, как это описано в документации!? Баг? Или я что-то не понимаю?

Возможно, но это также должно произойти, если LOCK TABLE был в транзакции, которая до этого обращалась к той же таблице, и началась перед тем, как стал выполняться DROP INDEX CONCURRENTLY;

Пример:
Допустим есть таблица CREATE TABLE foobar(id INTEGER) и на ней (поле id) создан индекс CREATE INDEX ON foobar(id);

T     TX1                                          TX2
1     BEGIN
2     SELECT * FROM foobar;
3                                                       DROP INDEX CONCURRENTLY foobar_id_idx
4      LOCK TABLE foobar;
ERROR:  40P01: deadlock detected
DETAIL:  Process 17989 waits for AccessExclusiveLock on relation 24662 of database 16385; blocked by process 17796.
Process 17796 waits for ShareLock on virtual transaction 3/2; blocked by process 17989.

В T=3 DROP INDEX concurrently будет ждать окончания TX1, чтобы убедиться, что все работающие транзакции завершились (в обычном случае DROP INDEX без CONCURRENTLY для этого эксклюзивно блокируется таблица).
При этом та транзакция, которой он ждет, попыталась взять AccessExclusiveLock, который конфликтует со всеми остальными блокировками, в т.ч. и с ShareUpdateExclusiveLock у DROP INDEX CONCURRENTLY.

Вообще делать LOCK TABLE не вначале транзакции - это провоцировать подобные дедлоки.


23 марта 2017 г. 18:41 пользователь "Dmitry Igrishin" <dmitigr@gmail.com> написал:


2017-03-23 12:45 GMT+03:00 Вавржин Игорь <igor.vavrjin@gmail.com>:
Вот что видим в логах:

Mar 23 15:45:07 mdb postgres[26481]: [177-1] user=pgsql,db=geo,client=10.77.255.13 ERROR:  deadlock detected
Mar 23 15:45:07 mdb postgres[26481]: [177-2] user=pgsql,db=geo,client=10.77.255.13 DETAIL:  Process 26481 waits for ShareLock on virtual transaction 8/29343079; blocked by process 15087.
Mar 23 15:45:07 mdb postgres[26481]: [177-3]        Process 15087 waits for AccessExclusiveLock on relation 24694 of database 17701; blocked by process 26481.
Mar 23 15:45:07 mdb postgres[26481]: [177-4]        Process 26481: DROP INDEX CONCURRENTLY IF EXISTS geo_11_2gis_get_route_platform_ids_from_json
Mar 23 15:45:07 mdb postgres[26481]: [177-5]        
Mar 23 15:45:07 mdb postgres[26481]: [177-6]        Process 15087: LOCK TABLE geo_11 IN ACCESS EXCLUSIVE MODE
Mar 23 15:45:07 mdb postgres[26481]: [177-7] user=pgsql,db=geo,client=10.77.255.13 HINT:  See server log for query details.
Mar 23 15:45:07 mdb postgres[26481]: [177-8] user=pgsql,db=geo,client=10.77.255.13 STATEMENT:  DROP INDEX CONCURRENTLY IF EXISTS geo_11_2gis_get_route_platform_ids_from_json
Mar 23 15:45:07 mdb postgres[26481]: [177-9]

кто-нибудь может объяснить откуда мог взяться при указании конкурентности дедлок?
версия postgres 9.4.4
Судя по тому, что написано, процесс 15087 получил некий уровень блокировки (скажем, ShareLock), потом запустил процесс 26481 для конкурентного создания индекса (которому требуется ShareLock), а потом затребовал блокировку уровня AccessExclusiveLock, которую получить не может, так как процесс 26481 ждёт получения блокировки уровня ShareLock.

Alex

pgsql-ru-general by date:

Previous
From: Вавржин Игорь
Date:
Subject: [pgsql-ru-general] st_equals от пустых геометрий
Next
From: Антон Мазунин
Date:
Subject: Re: [pgsql-ru-general] [pgsql-ru-general] сменить пароли/доступы к БД без даунтайма