IT SERVICES - Performance/Lentidão/Travamentos - Qual comando pode ser utilizado para localizar Locks em base de dados Postgres
Dúvida
Qual comando pode ser utilizado para localizar Locks em base de dados Postgres?
Solução
Importante
O comando descrito abaixo é um exemplo de comando utilizado para coleta de Locks na base de dados (em tempo real) pela equipe de DBAs da Senior.
A responsabilidade de execução deste comando é do DBA da sua empresa. Ele também poderá utilizar outros comandos para coleta dessa informação.
Para localizar locks em base de dados Postgres o seu DBA poderá utilizar o comando abaixo:
WITH RECURSIVE ACTIVITY AS (
SELECT
PG_BLOCKING_PIDS(PID) BLOCKED_BY,
*,
AGE(CLOCK_TIMESTAMP(), XACT_START)::INTERVAL(0) AS TX_AGE,
-- "PG_LOCKS.WAITSTART" – PG14+ ONLY; FOR OLDER VERSIONS: AGE(CLOCK_TIMESTAMP(), STATE_CHANGE) AS WAIT_AGE
--AGE(CLOCK_TIMESTAMP(), (SELECT MAX(L.WAITSTART) FROM PG_LOCKS L WHERE A.PID = L.PID))::INTERVAL(0) AS WAIT_AGE
AGE(CLOCK_TIMESTAMP(), STATE_CHANGE) AS WAIT_AGE
FROM PG_STAT_ACTIVITY A
WHERE STATE IS DISTINCT FROM 'IDLE'
), BLOCKERS AS (
SELECT
ARRAY_AGG(DISTINCT C ORDER BY C) AS PIDS
FROM (
SELECT UNNEST(BLOCKED_BY)
FROM ACTIVITY
) AS DT(C)
), TREE AS (
SELECT
ACTIVITY.*,
1 AS LEVEL,
ACTIVITY.PID AS TOP_BLOCKER_PID,
ARRAY[ACTIVITY.PID] AS PATH,
ARRAY[ACTIVITY.PID]::INT[] AS ALL_BLOCKERS_ABOVE
FROM ACTIVITY, BLOCKERS
WHERE
ARRAY[PID] <@ BLOCKERS.PIDS
AND BLOCKED_BY = '{}'::INT[]
UNION ALL
SELECT
ACTIVITY.*,
TREE.LEVEL + 1 AS LEVEL,
TREE.TOP_BLOCKER_PID,
PATH || ARRAY[ACTIVITY.PID] AS PATH,
TREE.ALL_BLOCKERS_ABOVE || ARRAY_AGG(ACTIVITY.PID) OVER () AS ALL_BLOCKERS_ABOVE
FROM ACTIVITY, TREE
WHERE
NOT ARRAY[ACTIVITY.PID] <@ TREE.ALL_BLOCKERS_ABOVE
AND ACTIVITY.BLOCKED_BY <> '{}'::INT[]
AND ACTIVITY.BLOCKED_BY <@ TREE.ALL_BLOCKERS_ABOVE
)
SELECT
PID,
BLOCKED_BY,
CASE WHEN WAIT_EVENT_TYPE <> 'LOCK' THEN REPLACE(STATE, 'IDLE IN TRANSACTION', 'IDLETX') ELSE 'WAITING' END AS STATE,
WAIT_EVENT_TYPE || ':' || WAIT_EVENT AS WAIT,
WAIT_AGE,
TX_AGE,
TO_CHAR(AGE(BACKEND_XID), 'FM999,999,999,990') AS XID_AGE,
TO_CHAR(2147483647 - AGE(BACKEND_XMIN), 'FM999,999,999,990') AS XMIN_TTF,
DATNAME,
USENAME,
(SELECT COUNT(DISTINCT T1.PID) FROM TREE T1 WHERE ARRAY[TREE.PID] <@ T1.PATH AND T1.PID <> TREE.PID) AS BLKD,
FORMAT(
'%S %S%S',
LPAD('[' || PID::TEXT || ']', 9, ' '),
REPEAT('.', LEVEL - 1) || CASE WHEN LEVEL > 1 THEN ' ' END,
LEFT(QUERY, 1000)
) AS QUERY
FROM TREE
ORDER BY TOP_BLOCKER_PID, LEVEL, PID
Observação
Para mais informações sobre o questões relacionadas a Performance/Lentidão/Travamentos do Gestão Empresarial | ERP, consulte o artigo ERP - Performance/Lentidão/Travamentos - Onde é possível encontrar informações diversas sobre questões relacionadas a Performance/Lentidão/Travamentos (índice).