Una operación de VACUUM se completa correctamente en una tabla de Amazon Redshift. Sin embargo, el uso del disco sigue siendo alto.
Descripción corta
Cuando se eliminan filas de la tabla, la columna de identidad de metadatos oculta (DELETE_XID) se marca con el id. de transacción que eliminó la fila.
Si hay una transacción activa y de larga duración que comenzó antes de la eliminación, VACUUM no puede limpiar las filas y no se puede recuperar espacio en disco.
Para obtener más información sobre la columna DELETE_XID, consulta Optimización del almacenamiento para tablas angostas.
Resolución
Para comprobar si hay transacciones de larga duración en el clúster de Amazon Redshift, ejecuta la siguiente consulta:
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;
El siguiente resultado muestra que xid 50341 ha estado activo durante 19 minutos y 37 segundos:
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)
Para confirmar que has eliminado filas de la tabla de Amazon Redshift, ejecuta la siguiente consulta:
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;
El siguiente resultado muestra que la transacción marcada para eliminar filas (xid 50350) se inició después de la transacción de larga duración (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)
Para permitir que VACUUM DELETE recupere estas filas eliminadas, elige una de las siguientes opciones:
- Espera a que se complete la transacción de larga duración.
- Utiliza la instrucción PG_TERMINATE_BACKEND para terminar la sesión que está obstaculizando la transacción de larga duración.
Tras completar la acción anterior, vuelve a ejecutar la operación VACUUM.
Investigación de las transacciones de larga duración
Consulta la vista SVL_STATEMENTTEXT para comprobar la actividad en una transacción de larga duración:
rsdb=# select pid, xid, trim(label), starttime, endtime, trim(text) from svl_statementtext where xid = 50341 order by starttime , sequence;
Resultado de ejemplo:
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)
Para comprobar que las consultas se ejecutan en la transacción, consulta la vista STV_INFLIGHT:
rsdb=# select query, xid, pid, starttime, trim(text) from stv_inflight where xid = 50341;
Resultado de ejemplo:
query | xid | pid | starttime | btrim
-------+-----+-----+-----------+-------
(0 rows)
**Causas comunes de transacciones de larga duración **
El siguiente comportamiento puede dar lugar a transacciones de larga duración:
- Un usuario inicia una transacción implícita desde un cliente donde la confirmación automática está desactivada. La transacción permanecerá activa hasta que el usuario la cierre con el comando COMMIT o ROLLBACK, o hasta que se termine la sesión.
- Un usuario inicia una transacción mediante BEGIN, pero no la cierra con los comandos COMMIT ni ROLLBACK.
Información relacionada
Limpieza de tablas
Minimización de los tiempos de limpieza