Блокировка индекса - PullRequest
0 голосов
/ 10 июня 2018

Моя версия Postgres - 9,6

Я пытался сегодня удалить индекс из моей БД с помощью этой команды:

drop index index_name;

И это вызвало много блокировок - все приложение завислопока я не уничтожил все сеансы отбрасывания (почему он был разделен на несколько сеансов?).

Когда я проверял блокировки, я видел, что почти все заблокированные сеансы выполняют этот запрос:

SELECT a.attname, format_type(a.atttypid, a.atttypmod),
pg_get_expr(d.adbin, d.adrelid), a.attnotnull, a.atttypid, a.atttypmod    
FROM
pg_attribute a LEFT JOIN pg_attrdef d
                       ON a.attrelid = d.adrelid AND a.attnum = d.adnum
WHERE a.attrelid = <index_able_name>::regclass
AND a.attnum > 0 AND NOT a.attisdropped
ORDER BY a.attnum;

Имеет ли смысл блокировать действия системы?

Поэтому я решил удалить индекс с одновременной опцией для предотвращения блокировок.

drop index concurrently index_name;

Я выполняю его сейчас из PGAdmin (потому что вы не можете запустить его из транзакции noraml).

Прошло 20 минут и еще не закончилось.Размер индекса составляет 20 МБ + -.

И когда я проверяю БД на наличие блокировок, я вижу, что в этой таблице есть запрос на выборку, и это блокирует команду удаления.

Но когда я взялэто выберите и выполните в другом сеансе - это было быстро (2-3) секунды.

Так почему же это блокирует мое падение?Есть ли другой вариант сделать это?может, вместо этого отключить индекс?

1 Ответ

0 голосов
/ 11 июня 2018

drop index и drop index concurrently обычно являются очень быстрыми командами, но обе они, как и все команды DDL, требуют эксклюзивного доступа к таблице.

Они отличаются только тем, как они пытаются получить этот эксклюзивный доступ.,Обычная drop index просто запросит эксклюзивную блокировку на столе.Это блокирует все запросы (даже выборки), которые пытаются использовать таблицу после начала запроса drop.Он будет делать это до тех пор, пока не получит монопольную блокировку - когда все транзакции, которые каким-либо образом касаются таблицы, которые были запущены до команды удаления, завершатся и транзакция с drop будет зафиксирована.Это объясняет, почему ваше приложение перестало работать.

Версия concurrently также нуждается в кратком эксклюзивном доступе.Но он работает по-другому - он не будет блокировать таблицу, а подождет, пока к нему не коснется другой запрос, а затем выполнит свою (обычно краткую) работу.Но если стол постоянно занят, он никогда не найдет такого момента и будет ждать его бесконечно.Кроме того, я полагаю, что он просто пытается блокировать таблицу несколько раз каждые X миллисекунд, пока не завершится успешно, поэтому последующее параллельное выполнение может быть более удачным и завершиться быстрее.

Если вы видите несколько одновременных сеансов, пытающихся удалить индекс, ивы этого не ожидаете, тогда у вас есть ошибка в вашем приложении.База данных никогда не сделает это самостоятельно.

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