51

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

谢谢

4

4 回答 4

77

Redshift 具有非常快的 I/O,因此对于任何集群类型或大小,操作都应该不到 1 秒。正如 diemacht 所说,这个问题是因为你与一个开放的交易有另一个联系。

我遇到了类似的问题:客户端崩溃导致事务“打开”但无法访问。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}没有工作!(查询已取消,但事务仍处于打开状态并处于锁定状态)。

于 2014-06-17T15:10:36.627 回答
41

以我的经验,正如@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使表死锁的锁。因此,如果列出了许多锁,请找到并杀死其中ACCESS EXCLUSIVE一个。

于 2015-12-22T00:20:36.477 回答
17

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

运行此查询以找出 AccessShareLock 的 pid

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();

使用杀死进程select pg_terminate_backend(<pid>);

确保所有只读应用程序关闭并释放所有连接,从而释放这些锁!

于 2017-09-10T10:07:36.860 回答
6

我遇到过同样的问题。原来是打开的交易是从其他地方运行的。

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

在我在第二个窗口中提交/回滚后,截断工作完美。

希望它有所帮助。

于 2013-11-20T14:16:37.733 回答