Quiero encontrar y resolver los bloqueos de tablas que bloquean mis consultas en Amazon Redshift.
Descripción corta
Es posible que experimentes conflictos de bloqueo al realizar instrucciones frecuentes del lenguaje de definición de datos (DDL) en tablas de usuario o consultas del lenguaje de manipulación de datos (DML).
Amazon Redshift tiene los tres modos de bloqueo siguientes:
- AccessExclusiveLock bloquea todos los demás intentos de bloqueo y se obtiene principalmente durante las operaciones de DDL, como ALTER TABLE, DROP o TRUNCATE.
- AccessShareLock bloquea solo los intentos de AccessExclusiveLock y se obtiene durante las operaciones UNLOAD, SELECT, UPDATE o DELETE. AccessShareLock no bloquea otras sesiones que intentan leer o escribir en la tabla.
- ShareRowExclusiveLock bloquea AccessExclusiveLock y otros intentos de ShareRowExclusiveLock, pero no bloquea los intentos de AccessShareLock. ShareRowExclusiveLock se obtiene durante las operaciones COPY, INSERT, UPDATE o DELETE.
Para resolver este problema, identifica los bloqueos de la tabla de problemas, identifica la consulta de problemas (si es necesario) y, a continuación, libera los bloqueos de la tabla de problemas.
Resolución
Nota: Si se muestran errores al ejecutar comandos de la Interfaz de la línea de comandos de AWS (AWS CLI), consulte Solución de problemas de AWS CLI. Además, asegúrate de utilizar la versión más reciente de la AWS CLI.
Detección de los bloqueos
Para identificar los procesos que mantienen los bloqueos, ejecuta la siguiente consulta:
SELECT
a.txn_start,
datediff(s,a.txn_start,getdate())/86400||' days '||datediff(s,a.txn_start,getdate())%86400/3600||' hrs '||datediff(s,a.txn_start,getdate())%3600/60||' mins '||datediff(s,a.txn_start,getdate())%60||' secs' AS txn_duration,
a.txn_owner,
a.txn_db,
a.pid,
a.xid,
a.lock_mode,
a.relation AS table_id,
nvl(trim(c."table"),d.relname) AS tablename,
a.granted,
b.pid AS blocking_pid
FROM SVV_TRANSACTIONS a
LEFT JOIN (SELECT pid, relation, granted FROM PG_LOCKS GROUP BY 1,2,3) b
ON a.relation = b.relation AND a.granted='f' AND b.granted='t'
LEFT JOIN (SELECT * FROM SVV_TABLE_INFO) c
ON a.relation = c.table_id
LEFT JOIN PG_CLASS d
ON a.relation = d.oid
WHERE
a.relation IS NOT NULL
AND txn_db = 'database name'
AND tablename = 'table name';
Para detectar los bloqueos en una tabla específica, sustituye database name por el nombre de tu base de datos y table name por el nombre de tu tabla.
Nota: Puedes ejecutar la consulta anterior tanto en un clúster aprovisionado de Amazon Redshift como en Amazon Redshift sin servidor.
Ejemplo de salida:
txn_start | txn_duration | txn_owner | txn_db | pid | xid | lock_mode | table_id | tablename | granted | blocking_pid
---------------------------+-----------------------------+-----------+--------+------------+---------+---------------------+----------+-----------+---------+--------------
2025-02-07 15:22:54.62833 | 0 days 0 hrs 3 mins 46 secs | admin | dev | 1073905801 | 3950326 | AccessExclusiveLock | 1410058 | abctbl | t |
2025-02-07 15:22:57.67816 | 0 days 0 hrs 3 mins 43 secs | admin | dev | 1073963119 | 3950380 | AccessShareLock | 1410058 | abctbl | f | 1073905801
Si el resultado de la columna granted es f (falso), la transacción está a la espera de que se bloquee porque otra transacción mantiene el bloqueo. La columna blocking_pid muestra el ID del proceso (PID) de la sesión que mantiene el bloqueo.
Detección de la consulta del problema
Si el problema de bloqueo de la tabla específica se produce de forma constante, utiliza SYS_QUERY_HISTORY para ver qué consulta causa el problema.
SELECT * FROM SYS_QUERY_HISTORY WHERE transaction_id = transaction ID;
Liberación de bloqueos
Para liberar los bloqueos, sigue estos pasos:
- Espera hasta que se libere la transacción que mantiene el bloqueo.
- Ejecuta la función PG_TERMINATE_BACKEND para liberar el bloqueo manualmente.
Nota: La consulta PG_TERMINATE_BACKEND(PID) devuelve el valor 1 cuando el comando solicita correctamente la detención del proceso. Se recomienda comprobar SYS_SESSION_HISTORY para confirmar que el proceso está detenido.
- En el caso de un clúster aprovisionado de Redshift, si PG_TERMINATE_BACKEND no detiene correctamente el proceso, ejecuta la función REBOOT_CLUSTER.
Nota: REBOOT_CLUSTER reinicia el clúster sin cerrar las conexiones.
- En el caso de un clúster aprovisionado de Redshift, si REBOOT_CLUSTER no detiene correctamente el proceso, reinicia el clúster desde la consola de Amazon Redshift o ejecuta el comando reboot-cluster de la AWS CLI.
Nota: reboot-cluster cierra todas las conexiones actuales.