如何截断大小超过5231MB的postgresql中的大表?

时间:2016-01-22 15:28:40

标签: postgresql truncate

已经尝试删除和截断但是花了很长时间。还尝试使用以下查询找出该表上的任何锁定进程

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;

不返回任何行

2 个答案:

答案 0 :(得分:0)

TRUNCATE是删除表格的最快方法。来自docs

  

TRUNCATE会快速删除一组表中的所有行。它与每个表上的非限定DELETE具有相同的效果,但由于它实际上不扫描表,因此速度更快。此外,它立即回收磁盘空间,而不是需要后续的VACUUM操作。这对大型表格最有用。

您还可以DROP重新创建表格the same as TRUNCATE

你的DELETE也将最终完成,你只需要给Postgres一些时间。

如果您需要在不锁定表的情况下清除所有内容,可以批量删除:

DELETE FROM things LIMIT 1000;

将它设置在一个循环中,直到桌子为空,然后去吃零食。

答案 1 :(得分:0)

TRUNCATE应该很快,除非它无法在对象上获取AccessExclusiveLock,在这种情况下它可以无限期地等待。

应该揭示阻塞会话的上述查询不识别对象级锁,这是TRUNCATE获取的那种锁。

这里提到了,我假设这个查询来自哪里:

https://wiki.postgresql.org/wiki/Lock_Monitoring

  

以下查询可能有助于查看哪些进程正在阻止   SQL语句(这些只查找行级锁,而不是对象级   锁)。

以下是PG 9.1问题的演示:

会话#1:

test=> create table footable(id int);
CREATE TABLE
test=> begin;
BEGIN
test=> insert into footable values(1);
INSERT 0 1
test=> 

(未选择)

会话#2

test=> truncate table footable;

(被会话#1阻止)

会话#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)

根据此查询,没有会话被阻止,所以显然是错误的。

我建议您在此处尝试此其他查询: https://wiki.postgresql.org/wiki/Find_Locks

在此示例中,生成此输出:

-[ 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