patternsqlMinor
Alternative to CLUSTER without table lock
Viewed 0 times
withoutalternativeclustertablelock
Problem
I'm facing performance degradation and increasing storage usage as a result of frequent new and updated records causing index and storage fragmentation.
VACUUM doesn't help much.
Unfortunetely CLUSTER isn't an option as it causes downtime and pg_repack isn't available for AWS RDS.
I'm looking for hacky alternatives to CLUSTER. One that seems to work fine in my local tests is:
The ordering of
The question is: does this look fine? Is it going to lock the
Is there a way to list the locks involved in the transaction?
Related to Cluster command locking read only queries on replica
VACUUM doesn't help much.
Unfortunetely CLUSTER isn't an option as it causes downtime and pg_repack isn't available for AWS RDS.
I'm looking for hacky alternatives to CLUSTER. One that seems to work fine in my local tests is:
begin;
create temp table tmp_target as select * from target;
delete from target;
insert into target select * from tmp_target order by field1 asc, field2 desc;
drop table tmp_target;
commit;The ordering of
ctid looks correct with:select ctid, field1, field2 from target order by ctid;The question is: does this look fine? Is it going to lock the
target table for SELECT queries causing downtime in apps?Is there a way to list the locks involved in the transaction?
Related to Cluster command locking read only queries on replica
Solution
If it's just about table bloat,
There are community tools to do the same without exclusive lock:
Unfortunately, most hosted services like Amazon RDS do not allow these additional modules, currently.
Related:
Your current solution is no good, either way. You do the sort operation after deleting all rows (locking them), which will not shorten the downtime (the duration of the lock) for
If you have no concurrent write access and no depending objects, this might be better:
-
Sort in the background before taking the lock.
Strictly speaking,
-
For big tables,
You may want to drop existing indexes right before
Related:
VACUUM FULL is the tool to do it. (VACUUM only shrinks the physical file if it can opportunistically truncate it at the end.) However, VACUUM FULL also takes an exclusive lock on the table, just like CLUSTER.There are community tools to do the same without exclusive lock:
- pg_repack
- pg_squeeze
Unfortunately, most hosted services like Amazon RDS do not allow these additional modules, currently.
Related:
- VACUUM returning disk space to operating system
Your current solution is no good, either way. You do the sort operation after deleting all rows (locking them), which will not shorten the downtime (the duration of the lock) for
SELECT queries.If you have no concurrent write access and no depending objects, this might be better:
BEGIN;
CREATE TEMP TABLE tmp_target AS TABLE target ORDER BY field1, field2 DESC;
TRUNCATE target;
INSERT INTO target TABLE tmp_target;
-- DROP TABLE tmp_target; -- optional; dropped at end of session automatically
COMMIT;-
Sort in the background before taking the lock.
Strictly speaking,
INSERT without ORDER BY is free to write rows in any physical order. Practically, though, it will normally copy the current physical order of the temp table with a plain SELECT * FROM ... (TABLE ... for short). May fail for big tables that involve multiple parallel workers. Then you may need ORDER BY.-
For big tables,
TRUNCATE is faster than DELETE. Be aware of some implications. Like: TRUNCATE does not work with FK constraints. Read the manual for full coverage.You may want to drop existing indexes right before
TRUNCATE and recreate after INSERT to make this faster.Related:
- Best way to populate a new column in a large table?
- Why wouldn't VACUUM ANALYZE clear all dead tuples?
- Configuring PostgreSQL for read performance
Code Snippets
BEGIN;
CREATE TEMP TABLE tmp_target AS TABLE target ORDER BY field1, field2 DESC;
TRUNCATE target;
INSERT INTO target TABLE tmp_target;
-- DROP TABLE tmp_target; -- optional; dropped at end of session automatically
COMMIT;Context
StackExchange Database Administrators Q#174659, answer score: 7
Revisions (0)
No revisions yet.