2013-10-24 157 views
33

在我的redshift数据库中删除或截断一个不太大的表(4M行)时,需要非常长的时间才能完成。有人遇到同样的问题吗?redshift drop或truncate table非常慢

谢谢

+0

你可以提供一些其他信息,如表宽度,群集设置等? – bstempi

+0

如果解决了您的问题,您应该接受Gerardo的答案。 –

回答

5

我遇到过同样的问题。原来是打开的事务从别的地方跑过来。

例如,如果您有两个使用Redshift shell打开的shell,您将无法从第一个shell中删除一个表,这个表参与第二个shell中的打开事务。

在我提交/回滚到第二个窗口后,truncate完美工作。

希望它有帮助。

58

Redshift的I/O速度非常快,因此对于任何群集类型或大小,操作应该少于1秒。 正如diemacht所说,这个问题是由于您与一个公开交易有另一个联系而引起的。

我有一个类似的问题:客户端崩溃导致事务“打开”但不可缓解。 没有DB锁出现在STV_LOCKS表:(使用select table_id, last_update, lock_owner, lock_owner_pid from stv_locks;

而且,没有查询仍在运行(与检查:select pid, trim(user_name), starttime, query , substring(query,1,20), status from stv_recents where status='Running';

因此,解决办法是列出用户会话:SELECT * FROM STV_SESSIONS 然后使用杀它:SELECT pg_terminate_backend(pid)

还是KILL'EM ALL版本:

SELECT pg_terminate_backend(process) FROM STV_SESSIONS where user_name='user_name' and process != pg_backend_pid(); 

注意CANCEL {pid}没有工作! (查询被取消,但交易仍然处于打开状态并锁定)。

+4

'SELECT pg_terminate_backend(process)FROM STV_SESSIONS where user_name ='user_name'and process!= pg_backend_pid();'现在不起作用。它返回'INFO:Function“pg_terminate_backend(integer)”not supported.'消息。 –

+0

@masashimiyazaki,在从Redshift表中选择时,'pg_terminate_backend'不起作用。还有另一条消息指出该功能在Redshift表格上不可用。 获取pid列表并分别将pg_terminate_backend()应用于每个pid。也许这种行为自父母职位以来发生了变化 – Thinkable

+0

是不是可以在WLM中为用户查询添加超时? –

25

根据我的经验,正如@Gerardo Grignoli所说,锁并不出现在stv_locks表中,但它们确实出现在pg_locks中。根据您的环境,可能无法接受stv_sessions中列出的任意长时间运行的会话。我觉得pg_locks表是检测这种类型的锁非常可靠:

select * from pg_locks where relation = (select oid from pg_class where relname = 'the_table') 
select pg_cancel_backend(pid) 

通常情况下,这个问题是一个ACCESS EXCLUSIVE锁死锁真实的表。所以,如果列出了很多锁,找到并杀死其中的一个。

+0

这为我工作。 – Merlin

3

表上的IMO AccessShareLock还会导致DDL命令卡住。

运行此查询找出的AccessShareLock

select 
    current_time, 
    c.relname, 
    l.database, 
    l.transaction, 
    l.pid, 
    a.usename, 
    l.mode, 
    l.granted 
from pg_locks l 
join pg_catalog.pg_class c ON c.oid = l.relation 
join pg_catalog.pg_stat_activity a ON a.procpid = l.pid 
where l.pid <> pg_backend_pid(); 

的PID使用select pg_terminate_backend(<pid>);

杀过程确保所有只读应用程序关闭并释放所有的连接,因此这些锁!