web-dev-qa-db-ja.com

赤方偏移のドロップまたはテーブルの切り捨てが非常に遅い

Redshiftデータベースで大きすぎないテーブル(4M行)を削除または切り捨てると、完了するのに非常に長い(時間)かかります。誰も同じ問題を経験していますか?

ありがとう

41
user2916054

Redshiftは非常に高速なI/Oを備えているため、操作はクラスターの種類やサイズに関係なく1秒未満で完了します。 diemachtが言ったように、オープントランザクションとの別の接続があるため、問題が発生します。

同様の問題がありました。クライアントのクラッシュにより、トランザクションが「オープン」になりましたが、到達できませんでした。 STV_LOCKSテーブルにdbロックが表示されませんでした:(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}は機能しませんでした! (クエリはキャンセルされましたが、トランザクションはまだ開いていてロックされていました)。

67

私の経験では、@ 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ロックを見つけて強制終了します。

31
kuujo

テーブルの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>);を使用してプロセスを強制終了します

すべての読み取り専用アプリケーションがすべての接続を閉じて解放し、これらのロックが解除されることを確認してください!

12
swatisinghi

同じ問題が発生しました。開かれたトランザクションは他の場所から実行されたことが判明しました。

たとえば、redshiftシェルで2つのシェルを開いている場合、2番目のシェルで開いているトランザクションに参加している最初のシェルからテーブルを削除することはできません。

2番目のウィンドウでコミット/ロールバックした後、truncateは完全に機能しました。

お役に立てば幸いです。

6
diemacht