При выполнении рекурсивных запросов, постгрес создаёт временные таблицы, которые остаются на диске после завершения запроса, пока не завершится весь скрипт, который сделан в форме команды django management с использованием multiprocessing. Закрыть соединение с базой в родительском процессе нельзя - оно используется как итеративный источник исходных данных.
Запрос выполняется в виде raw-query через курсор примерно так:
def process_datum(datum):
with db.connections['world'].cursor() as cursor:
cursor.execute("SELECT ... from query_function(%s)", (datum.id,))
rows = cursor.fetchall()
for row in rows:
try:
...
A_Model.objects.create(...)
except db.IntegrityError as e:
logger.warning("%s: %s", path, e)
Функция `process_datum` вызывается из pool worker, функция `query_function` на стороне сервера реализует рекурсивный запрос.
Этих запросов дофигища и временные таблицы засирают весь диск.
Как быть?
P.S.
Исходный запрос:
select ... from features limit 1000 offset xxxx;
Рекурсивный запрос:
with recursive recursion(child_id, parent_id, node_id, path) as (
select h.child_id, h.parent_id, h.parent_id as node_id, ARRAY[h.parent_id]
from hierarchy h
where h.direct=true and h.child_id=$1
union all
select h.child_id, h.parent_id, r.node_id, r.path || ARRAY[h.parent_id]
from recursion r join hierarchy h on h.child_id = r.parent_id
where h.direct=true and h.parent_id != r.node_id
)
select * from recursion
Создающий запрос:
insert into hierarchy (parent_id, child_id, direct, path) values (%d, %d, false, %s::bigint[])