Pourquoi l'opération VACUUM d'Amazon Redshift ne récupère-t-elle pas de l'espace disque ?

Date de la dernière mise à jour : 17/08/2020

J'exécute une opération VACUUM FULL ou VACUUM DELETE ONLY sur une table Amazon Redshift qui contient les lignes marquées pour suppression. L'opération semble se terminer avec succès. Pourquoi n'y a-t-il pas d'espace disque récupéré ?

Brève description

L'espace disque peut ne pas être récupéré s'il existe des transactions de longue durée qui restent actives. Lorsque des lignes sont supprimées, une colonne d'identité de métadonnées masquée, DELETE_XID, est marquée avec l'ID de transaction qui a supprimé la ligne. S'il existe une transaction active de longue durée qui a commencé avant la suppression, VACUUM ne peut pas nettoyer les lignes. Par conséquent, l'espace disque ne peut pas être récupéré. Pour plus d'informations sur la colonne DELETE_XID consultez la section Optimisation du stockage pour les tables étroites.

Solution

1.    Pour vérifier s'il existe des transactions de longue durée sur le cluster, exécutez la requête suivante :

rsdb=# select *,datediff(s,txn_start,getdate())/86400||' days '||datediff(s,txn_start,getdate())%86400/3600||' hrs '||datediff(s,txn_start,getdate())%3600/60||' mins '||datediff(s,txn_start,getdate())%60||' secs' duration from svv_transactions where lockable_object_type='transactionid' and  pid<>pg_backend_pid() order by 3;

La sortie suivante montre que xid 50341 a été actif pendant 19 minutes et 37 secondes :

txn_owner  | txn_db |  xid  |  pid  |         txn_start          |   lock_mode   | lockable_object_type | relation | granted |           duration
-----------+--------+-------+-------+----------------------------+---------------+----------------------+----------+---------+------------------------------
 superuser | rsdb   | 50341 | 21612 | 2019-08-19 20:20:33.147622 | ExclusiveLock | transactionid        |          | t       | 0 days 0 hrs 19 mins 37 secs
(1 row)

2.    Exécutez la requête suivante pour confirmer que les lignes ont bien été supprimées de la table Amazon Redshift :

select a.query, a.xid, trim(c.name) tablename, b.deleted_rows, a.starttime, a.endtime
from stl_query a 
join (select query, tbl, sum(rows) deleted_rows from stl_delete group by 1,2) b 
on a.query = b.query
join (select id, name from stv_tbl_perm group by 1,2) c 
on c.id = b.tbl 
where a.xid in (select distinct xid from stl_commit_stats)
and trim(c.name) = 'tablename'
order by a.starttime;

La sortie suivante montre que la transaction marquée pour la suppression de ligne (xid 50350) a démarré après la transaction de longue durée (xid 50341) :

query  |  xid  | tablename | deleted_rows |         starttime          |          endtime
-------+-------+-----------+--------------+----------------------------+----------------------------
 18026 | 50350 | test      |            5 | 2019-08-19 20:20:48.137594 | 2019-08-19 20:20:50.125609
(1 rows)

Pour autoriser VACUUM DELETE à récupérer ces lignes supprimées, choisissez l'une des options suivantes, puis exécutez à nouveau l'opération VACUUM :

  • Attendez que la transaction de longue durée se termine.
  • Utilisez l'instruction PG_TERMINATE_BACKEND pour mettre fin à la session qui conserve la transaction de longue durée.

Examiner les transactions de longue durée

Interrogez la vue SVL_STATEMENTTEXT pour vérifier l'activité dans une transaction de longue durée :

rsdb=# select pid, xid, trim(label), starttime, endtime, trim(text) from svl_statementtext where xid = 50341 order by starttime , sequence;

Voici un exemple de sortie :

  pid  |  xid  |  btrim  |         starttime          |          endtime           |          btrim
-------+-------+---------+----------------------------+----------------------------+--------------------------
 21612 | 50341 | default | 2019-08-19 20:20:31.733843 | 2019-08-19 20:20:31.733844 | begin;
 21612 | 50341 | default | 2019-08-19 20:20:33.146937 | 2019-08-19 20:20:35.020556 | select * from sometable;
(2 rows)

Interrogez la vue STV_INFLIGHT afin de vérifier si des requêtes sont en cours d'exécution dans la transaction :

rsdb=# select query, xid, pid, starttime, trim(text) from stv_inflight where xid = 50341;

Voici un exemple de sortie :

 query | xid | pid | starttime | btrim
-------+-----+-----+-----------+-------
(0 rows)

Problèmes courants entraînant des transactions de longue durée

Le comportement suivant peut entraîner des transactions de longue durée :

  • Un utilisateur démarre une transaction implicite à partir d'un client où la validation automatique est désactivée. La transaction reste active jusqu'à ce que l'utilisateur ferme explicitement la transaction avec la commande COMMIT ou ROLLBACK, ou jusqu'à ce que la session soit terminée.
  • Un utilisateur démarre une transaction explicitement avec la commande BEGIN, mais ne ferme jamais la transaction avec la commande COMMIT ou ROLLBACK.

Cet article vous a-t-il été utile ?


Besoin d'aide pour une question technique ou de facturation ?