Re: [RFC] Add an until-0 loop in psql

Поиск
Список
Период
Сортировка
От Pavel Stehule
Тема Re: [RFC] Add an until-0 loop in psql
Дата
Msg-id CAFj8pRCKTUTmxMjj2+hzXAj_uvPm0o5QFJqqSq8yzb3R6iMdyA@mail.gmail.com
обсуждение исходный текст
Ответ на Re: [RFC] Add an until-0 loop in psql  (Corey Huinker <corey.huinker@gmail.com>)
Ответы Re: [RFC] Add an until-0 loop in psql  (Corey Huinker <corey.huinker@gmail.com>)
Список pgsql-hackers
Hi

2018-04-27 21:40 GMT+02:00 Corey Huinker <corey.huinker@gmail.com>:
As of v11, DO blocks can do transactions. I think this will meet your needs.

A loop that starts at point X in the code and terminates at point Y has to know how to jump back in the file (if there even is a file!) to point X and re-interpret commands as it makes it's way back through the "file" toward point Y again... a place it might not reach, or it might reach some other loop termination first. \commands can be hidden inside psql variables, files can be conditionally included based on \if statements, and those files might have loop starters/terminators in them. And those commands are processed.

That, or you'd have to capture the code by somehow parsing ahead to the next \until-0 (processing all inner loops as you go, and the files they include, etc), but that means that variables that were expanded the first time are not expanded on subsequent iterations, and that makes it hard to set an exit-condition variable. It would also seriously alter what psql is when inside that loop.

I once did a presentation on ways to (ab)use psql, and one thing I did was recursion via include files. Adapting your loop as literally as possible, it would look like this:

loop_file.sql:
BEGIN;
WITH deleted_rows AS (DELETE FROM big_table 
                      WHERE id in (SELECT id FROM big_table WHERE bad = true LIMIT 1000)
                      RETURNING 1)
SELECT (COUNT(*) > 0) as deleted_some_rows FROM deleted_rows
\gset
VACUUM big_table;
COMMIT;
\if :deleted_some_rows
   \include loop_file.sql
\endif

What you don't see here is that you're using your psql process's available open file handles as a stack, and when you hit that limit psql will fail. If you remove that limit, then you get a bit further before psql segfaults on you. I think I got ~2700 files deep before that happened. Your stackage may vary.

I'm not saying this is a good solution, quite the contrary. I think the sane solution is right around the corner in Version 11.

Now if we just had a way of passing parameters into DO blocks...

I hope so there will be schema (temporal) variables:

create temp variable foo int default 10;

do $$
begin
  for i in 1..foo loop
    raise notice '%', i;
  end loop;
end;
$$;

 


On Tue, Apr 24, 2018 at 3:59 AM Pierre Ducroquet <pierre.ducroquet@people-doc.com> wrote:
Hi

When running database migrations with .sql files on a live database, it's not
uncommon to have to run a migration in a loop to prevent a big lock on a
table.
For instance if one want to delete some old datas from a big table one would
write :

DELETE FROM big_table WHERE id IN (SELECT id FROM big_table WHERE bad = true
LIMIT 1000);
VACUUM big_table;

Right now, doing this is quite inefficient. We either have to write a script
in another language, or run psql in a shell loop and wait for the migration to
stop altering rows.

The attached **proof of concept** patch (I insist, it's a 15 minutes hack
sprint with no previous knowledge of psql code) implements an 'until-0' loop
in psql.
The previous migration could be simply written as :

\until-0
BEGIN;
DELETE FROM big_table WHERE id IN (SELECT id FROM big_table WHERE bad = true
LIMIT 1000);
VACUUM big_table;
COMMIT;
\end-until

And psql will execute it until there is no row affected in the inner queries.

I am willing to write a proper patch for this (I hope the tell/seek is an
acceptable implementation…), but I prefer having some feedback first.

Thanks

 Pierre

В списке pgsql-hackers по дате отправления:

Предыдущее
От: "ZHUO QL (KDr2)"
Дата:
Сообщение: Fix some trivial issues of the document/comment
Следующее
От: Atri Sharma
Дата:
Сообщение: Re: GSoC 2018: Sorting Algorithm and Benchmarking