Обложка канала

Хмельной Девопс

Будничный хаос и мрак при поддержке ИТ систем.

Хмельной Девопс

8 лет назад
Открыть в
История одного запроса или переезд с mssql на postgresql.

В табличках начали пропадать данные, поиск по логам и прочим источникам указал на причину - unlogged таблицы после креша полностью транкейтятся. Причиной креша оказался OOM. Ну ладно, подумали мы и увеличили память. Ровно через день история повторилась. Причем крешилось все на запросе update к не очень большой табличке.

Первое подозрение было на триггеры. Отключили, запустили, упало. Памяти оно отжирало будь здоров (видно на скриншоте). Начали копать плотнее. Ну точнее решили не гадать, а посмотреть на execution plan:

DB=# explain update table1 set column = True from table1 t1 join table2 t2 on t2.id = t1.id where t1.id < 100000 and t2.column in (0, 4) and t12bool;

Update on table1 (cost=159112.16..2527607960.95 rows=202168723468 width=48)
-> Nested Loop (cost=159112.16..2527607960.95 rows=202168723468 width=48)
-> Seq Scan on table1 (cost=0.00..199305.87 rows=8276887 width=35)
-> Materialize (cost=159112.16..268192.87 rows=24426 width=12)

... skipped ...


WTF?! 200 000 000 000 строк?! Как оно вообще работало до этого (спойлер: видимо не работало). После глубокого и вдумчивого чтения документации переписали запрос (не я, спасибо доброму и очень умному человеку!):

DB=# explain update table1 t1 set column = True from table2 t2 where t2.id = t1.id and t1.id < 100000 and t2.column in (0, 4) and t2.bool;

Update on synonyms s (cost=159112.16..268440.74 rows=24426 width=42)
-> Hash Join (cost=159112.16..268440.74 rows=24426 width=42)
Hash Cond: (s.entity_id = e.id)

... skipped ...


Ура! 24 000 строк выглядят намного лучше 200 млрд. И как результат - никаких проблем с памятью, да и запрос выполняется за секунды. Кому интересно, ответ кроется в документации (кто бы мог подумать!) - https://www.postgresql.org/docs/10/static/sql-update.html:

Note that the target table must not appear in the from_list, unless you intend a self-join


В общем, друзья, смотрите на свои запросы через призму explain и читайте документацию.