It also means that god forbid it did die halfway through, and PG isn't smart enough to pick up where it left off safely, you won't lose any data, and at worst would end up with a duplicate archived row (easy enough to catch with some maintenance scripts and origin ids)
PostgreSQL Data Migration Tips
11–20 of 22 posts
Re: PostgreSQL Data Migration Tips
#12The normal way to handle batch updates is to perform the loop outside of postgresql, so that each batch is in its own transaction.
Re: PostgreSQL Data Migration Tips
#13I'm not sure I understand the purpose of the loop in the last example. AFAIK top-level plpgsql statements (including DO blocks run in psql) execute in a single transaction, so it seems like you end up slowly locking the entire table, as the transaction won't commit until the loop completes. (I learned this the hard way by trying to "batch"-update a table with tens of millions of rows in production.) The normal way to…
AFAIK top-level plpgsql statements (including DO blocks run in psql) execute in a single transaction
This is true according to the docs. Anonymous code blocks are "transient anonymous functions", and functions are executed within a transaction. it seems like you end up slowly locking the entire table
The selected rows would be locked for update, delete, and select for updates, but not for regular reads. Perhaps his users table is used primarily for reads, which made this command run with negligible consequences?http://www.postgresql.org/docs/9.4/static/sql-do.html
http://www.postgresql.org/docs/9.4/static/plpgsql-structure....
Re: PostgreSQL Data Migration Tips
#14Bone to pick with the CTE that archives users. I'd rather see it insert them into the archive table first, then delete them. Not much of a difference, but my instinct is to cover all possible failures, and be especially careful around deleting rows. It also means that god forbid it did die halfway through, and PG isn't smart enough to pick up where it left off safely, you won't lose any data, and at worst would end u…
Re: PostgreSQL Data Migration Tips
#15I'm not sure I understand the purpose of the loop in the last example. AFAIK top-level plpgsql statements (including DO blocks run in psql) execute in a single transaction, so it seems like you end up slowly locking the entire table, as the transaction won't commit until the loop completes. (I learned this the hard way by trying to "batch"-update a table with tens of millions of rows in production.) The normal way to…
AFAIK top-level plpgsql statements (including DO blocks run in psql) execute in a single transaction This is true according to the docs. Anonymous code blocks are "transient anonymous functions", and functions are executed within a transaction. it seems like you end up slowly locking the entire table The selected rows would be locked for update, delete, and select for updates, but not for regular reads. Perhaps his u…
https://gist.github.com/aanari/349c7d97ed50c6f69930#file-bat...
By creating a separate function for the locking and updating of rows, we ensure that the `BEGIN/END` transaction is handled per iteration rather than at the very end, so we only lock rows while they are being processed. Since Postgres does not support nested transaction blocks, calling a defined function from within an anonymous function block seemed to be the easiest and clearest path to achieve this.
Re: PostgreSQL Data Migration Tips
#16Bone to pick with the CTE that archives users. I'd rather see it insert them into the archive table first, then delete them. Not much of a difference, but my instinct is to cover all possible failures, and be especially careful around deleting rows. It also means that god forbid it did die halfway through, and PG isn't smart enough to pick up where it left off safely, you won't lose any data, and at worst would end u…
Should be a transaction. I bet if you could a way to corrupt data on safe hardware with this query and a power-plug test, the pg developers would treat it as a high-priority bug.
Re: PostgreSQL Data Migration Tips
#17Earlier quoted context omitted.
Should be a transaction. I bet if you could a way to corrupt data on safe hardware with this query and a power-plug test, the pg developers would treat it as a high-priority bug.
That's correct, as jpitz mentioned if the code is run inside a transaction block, then we don't have to worry about the failing DELETE causing the INSERTs to fail.
Re: PostgreSQL Data Migration Tips
#18I like how SQL is becoming cool again.
Re: PostgreSQL Data Migration Tips
#19Earlier quoted context omitted.
AFAIK top-level plpgsql statements (including DO blocks run in psql) execute in a single transaction This is true according to the docs. Anonymous code blocks are "transient anonymous functions", and functions are executed within a transaction. it seems like you end up slowly locking the entire table The selected rows would be locked for update, delete, and select for updates, but not for regular reads. Perhaps his u…
Author here. That's a great point bhahn, I just updated my gist to properly handle the case that you just outlined: https://gist.github.com/aanari/349c7d97ed50c6f69930#file-bat... By creating a separate function for the locking and updating of rows, we ensure that the `BEGIN/END` transaction is handled per iteration rather than at the very end, so we only lock rows while they are being processed. Since Postgres does…
The anonymous block is implicitly called in a transaction, so all the calls to batch_at_will will be executed in the parent transaction; there's no way around this (except for using db_link but that's pretty smelly imo).
The only way to batch update while only locking rows in the batch is to run the loop outside of postgres like OP suggested.
Re: PostgreSQL Data Migration Tips
#20Earlier quoted context omitted.
That's correct, as jpitz mentioned if the code is run inside a transaction block, then we don't have to worry about the failing DELETE causing the INSERTs to fail.
The transaction is implict - in fact, I don't know of a way to do this outside the scope of a transaction. Is there?
In the end, queries are code, and code is our way to communicate or intent to the next developer, so it's better to do the delete after the insert