Reputation: 21
Already tried delete and truncate but it took ever long time. Also tried to find out any lock process is there on that table using the below query
SELECT bl.pid AS blocked_pid,
a.usename AS blocked_user,
kl.pid AS blocking_pid,
ka.usename AS blocking_user,
a.current_query AS blocked_statement
FROM pg_catalog.pg_locks bl
JOIN pg_catalog.pg_stat_activity a ON a.procpid = bl.pid
JOIN pg_catalog.pg_locks kl ON kl.transactionid = bl.transactionid AND kl.pid != bl.pid
JOIN pg_catalog.pg_stat_activity ka ON ka.procpid = kl.pid
WHERE NOT bl.GRANTED;
which doesn't return any row
Upvotes: 0
Views: 5372
Reputation: 61506
TRUNCATE should be fast unless it cannot acquire an AccessExclusiveLock on the object, in which case it can wait indefinitely.
The mentioned query that is supposed to reveal the blocking session doesn't identify object-level locks, which is the kind of lock that TRUNCATE acquires.
It's mentioned here, which is I assume where this query has been taken from:
https://wiki.postgresql.org/wiki/Lock_Monitoring
The following query may be helpful to see what processes are blocking SQL statements (these only find row-level locks, not object-level locks).
Here's a demo of the problem with PG 9.1:
Session #1:
test=> create table footable(id int);
CREATE TABLE
test=> begin;
BEGIN
test=> insert into footable values(1);
INSERT 0 1
test=>
(left uncommited)
Session #2
test=> truncate table footable;
(is blocked by session #1)
Session #3
test=> SELECT bl.pid AS blocked_pid,
a.usename AS blocked_user,
kl.pid AS blocking_pid,
ka.usename AS blocking_user,
a.current_query AS blocked_statement
FROM pg_catalog.pg_locks bl
JOIN pg_catalog.pg_stat_activity a ON a.procpid = bl.pid
JOIN pg_catalog.pg_locks kl ON kl.transactionid = bl.transactionid AND kl.pid != bl.pid
JOIN pg_catalog.pg_stat_activity ka ON ka.procpid = kl.pid
WHERE NOT bl.GRANTED;
blocked_pid | blocked_user | blocking_pid | blocking_user | blocked_statement
-------------+--------------+--------------+---------------+-------------------
(0 rows)
According to this query, no session is blocked, so it's clearly wrong.
I'd suggest that you try this other query, here: https://wiki.postgresql.org/wiki/Find_Locks
which in this example, produces this output:
-[ RECORD 1 ]------+--------------------
locktype | relation
database | 113270
relation | 2660062
page |
tuple |
virtualxid |
transactionid |
classid |
objid |
objsubid |
virtualtransaction | 5/2548
pid | 4419
mode | AccessExclusiveLock
granted | f
virtualtransaction | 4/2031
pid | 31775
mode | RowExclusiveLock
granted | t
Upvotes: 1
Reputation: 18803
TRUNCATE
is the fastest way to delete a table. From the docs:
TRUNCATE quickly removes all rows from a set of tables. It has the same effect as an unqualified DELETE on each table, but since it does not actually scan the tables it is faster. Furthermore, it reclaims disk space immediately, rather than requiring a subsequent VACUUM operation. This is most useful on large tables.
You can also DROP
and recreate the table, which will be the same as TRUNCATE
.
Your DELETE
will also eventually finish, you just need to give Postgres some time.
If you need to clear everything without locking the table up, you can delete in batches:
DELETE FROM things LIMIT 1000;
Set that in a loop somewhere until the table's empty, then go grab a snack.
Upvotes: 0