web-dev-qa-db-fra.com

redshift drop ou truncate table très très lent

Lorsque je supprime ou tronque une table pas trop grande (4 millions de lignes) dans ma base de données redshift, cela prend très très longtemps (heures). Quelqu'un rencontre-t-il le même problème?

Merci

41
user2916054

Redshift a des E/S très rapides, de sorte que l'opeation devrait prendre moins de 1 seconde pour tout type ou taille de cluster. Comme l'a dit diemacht, le problème est dû au fait que vous avez une autre connexion avec une transaction ouverte.

J'ai eu un problème similaire: un crash sur le client a laissé une transaction "ouverte" mais inaccessible. Aucun verrou DB n'apparaissait sur la table STV_LOCKS: (en utilisant select table_id, last_update, lock_owner, lock_owner_pid from stv_locks;)

De plus, aucune requête n'était toujours en cours d'exécution: (vérifié avec: select pid, trim(user_name), starttime, query , substring(query,1,20), status from stv_recents where status='Running';)

La solution était donc de lister les sessions utilisateur: SELECT * FROM STV_SESSIONS Et puis de le tuer en utilisant: SELECT pg_terminate_backend(pid)

Ou la version KILL'EM ALL:

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

Notez que CANCEL {pid} N'a pas fonctionné! (la requête a été annulée mais la transaction était toujours ouverte et verrouillée).

67
Gerardo Grignoli

D'après mon expérience, comme le dit @Gerardo Grignoli, les verrous n'apparaissent pas dans le stv_locks table, mais ils apparaissent dans pg_locks. Selon votre environnement, il peut ne pas être acceptable de supprimer une session arbitraire de longue durée répertoriée dans stv_sessions. Je trouve le pg_locks table pour être très fiable pour détecter ce type de verrou:

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

En règle générale, le problème est un ACCESS EXCLUSIVE verrou qui bloque la table. Ainsi, si de nombreux verrous sont répertoriés, recherchez et supprimez le ACCESS EXCLUSIVE un.

31
kuujo

IMO AccessShareLock sur les tables entraîne également le blocage des commandes DDL.

Exécutez cette requête pour comprendre les pids d'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();

Tuez les processus en utilisant select pg_terminate_backend(<pid>);

Assurez-vous que toutes vos applications en lecture seule se ferment et libèrent toutes les connexions et donc ces verrous!

12
swatisinghi

J'ai rencontré le même problème. Il s'est avéré que la transaction était ouverte ailleurs.

Par exemple, si vous avez 2 shells ouverts avec redshift Shell, vous ne pourrez pas supprimer une table du premier shell, qui participe à une transaction ouverte dans le second shell.

Après avoir validé/annulé dans la deuxième fenêtre, tronquer a parfaitement fonctionné.

J'espère que cela a aidé.

6
diemacht