Pg_later: Asynchronous Queries for Postgres
tembo.io
tembo.io
Spending hours doing trial-and-error with image-generation prompts is also exhausting.
Are we at the point where authors can feed their entire article text into an image-generator and it repeatedly (95%?) produces appropriate, if not very apt, artwork?
Links without an image are just physically smaller on Twitter or Facebook, they don't stand out as well.
"The earliest versions of the parable of blind men and elephant is found in Buddhist, Hindu and Jain texts, as they discuss the limits of perception and the importance of complete context. The parable has several Indian variations [...]"
The thing is, both of those things can be done today without any extensions: just modify your SQL scripts to run under an Agent account, and change every `SELECT` into a `SELECT INTO` statement, all dumping into a tempdb - this technique also works on SQL Server and Oracle too.
(On the subject of Agents, I'm surprised pgAgent isn't built-in to Postgres; while MSSQL and Oracle have had it since the start)
Several bg job libs are built around native locking functionality
> Relies upon Postgres integrity, session-level Advisory Locks to provide run-once safety and stay within the limits of schema.rb, and LISTEN/NOTIFY to reduce queuing latency.
https://github.com/bensheldon/good_job
> |> lock("FOR UPDATE SKIP LOCKED")
https://github.com/sorentwo/oban/blob/8acfe4dcfb3e55bbf233aa...
As an example, a way to run an upsetting query about a cosmetic change in big table without locking rows for other transactions we care about on the same table..?
The way I've done it is, as you allude to, by managing locks. You set the transaction isolation level as appropriate.
You can also batch statements by using a cursor, rather than having a single large blocking transaction.
However, Postgres does that automatically for certain background processes like autovacuum, background worker etc. by allowing you to configure how fast / slow they go.
You could implicitly influence how fast / slow something goes by setting per role / database parameters and giving less resources to certain types of queries (https://www.postgresql.org/docs/15/sql-alterrole.html) or by using explicit locks + lock_timeout to create some kind of a priority.
CREATE OR REPLACE FUNCTION run_with_adjusted_settings(query_text text)
RETURNS SETOF record
LANGUAGE plpgsql
AS $$
DECLARE
result_record record;
BEGIN
-- set_config ( setting_name text, new_value text, is_local boolean ) → text
-- Sets the parameter setting_name to new_value, and returns that value.
-- If is_local is true, the new value will only apply during the current transaction.
PERFORM set_config('statement_timeout', '10s', true);
PERFORM set_config('work_mem', '1MB', true);
PERFORM set_config('maintenance_work_mem', '1MB', true);
PERFORM set_config('max_parallel_workers_per_gather', '1', true);
-- Execute the provided query dynamically and return the results
FOR result_record IN EXECUTE query_text
LOOP
RETURN NEXT result_record;
END LOOP;
RETURN;
END;
$$;
-- Example usage:
SELECT *
FROM run_with_adjusted_settings('SELECT 1 as id, false as some_bool;') AS (id int, some_bool boolean);Queries usually stay out of each other's way, unless they're modifying the same data, causing lock contention.
What I've done in the past for "less important background queries" is use very short lock_timeout and short statement_timeout values. The query will fail if it can't acquire the lock quickly (and in turn won't hold extra locks), so you put it in a loop with a sleep.
https://www.postgresql.org/docs/15/runtime-config-client.htm...
Years ago on db2 on AS/400 we could submit queries to "batch". It would save the results in a physical file and you could come back and query them later. We were running plenty of things that took hours or sometimes days to finish. Being able to have that running on the server, not tied to any given client and set their priority (and change the priority during the run) was a huge benefit.
Theres not too many cases where I need to run hour long queries anymore, but still would be a great feature to have for long running, lower priority jobs.
Just need this to become available for RDS / Aurora.
Under the hood, is the query ran like a normal query?
I guess I don't understand the distinction between "run queries async" or "put query in a queue, run them sync one a time, poll until the one you want is done"
I get how the latter is "async".
I use it a lot for long running queries when doing data science and machine learning work, and a lot of times when executing queries from a jupyter notebook or CLI. That way if my jupyter kernel dies, my query execution continues even if the network or my environment has an issue. I've started using it a bit more with https://github.com/postgresml/postgresml for model training tasks too, since those can be quite long running depending on the situation.