Em um ambiente bancário, com considerável carga no banco, um determinado owner apresenta mais de 450 locks de mais de 2horas na execução de vários de seus processos. Isso acaba onerando a performance dos demais owners no banco, causando uma lentidão geral.
=>Os locks são de SQLs diferentes, não foi possível pegar o SQL gerador do lock.
DÚVIDA: Teoricamente, o SQL que está a mais tempo em execução seria o gerador do lock?
No final, está o SQL utilizado para buscar os locks.
=> Os locks gerados são do tipo locks TX onde mais transações estão buscando atualizar um mesmo registro e este está locado.
=> Um dos SQLs que está nas sessões com lock, chama uma package de 2 mil linhas. Essa package possui DMLs de update, delete e insert. O commit é realizado a cada 1000 linhas retornadas no contador do código.
=> Gerado plano de execução dos SQLs envolvidos nas sessões com locks e o plano é bom.
=> Ao verificar as Foreign keys não indexadas para esse owner, foram 546 listadas. Há necessidade de indexadas todas as Foreign keys ou somente as que possuirem ON DELETE CASCADE?
=> A coleta de estatísticas está atualizada para esse owner, feita full diariamente.
=> Gerado relatório AWR referente ao período da geração de locks: Em Segments by Row Lock Waits outro owner estava apresentando contenção. Seria porque esse outro owner representa a metade do banco em bytes? Ou seja, o volume de dados desse owner é muito maior que do owner que está apresentando os locks a baixo.
SET LINESIZE 130
SET PAGESIZE 999
COLUMN Object FORMAT a30 HEADING 'Object'
COLUMN Type FORMAT a4 HEADING 'Type'
COLUMN UserID FORMAT a20 HEADING 'OS/Oracle'
COLUMN Hold FORMAT a10 HEADING 'Hold'
COLUMN Program FORMAT a15 HEADING 'Program'
COLUMN usercode FORMAT a12 HEADING 'SID/Serial#'
COLUMN WaitMin FORMAT 999,999 HEADING 'Wait Time (minutes)'
SELECT
FROM
WHERE
a.osuser || ':' || a.username UserID
, a.sid || ',' || a.serial# usercode
, b.lock_type Type, b.mode_held Hold
, c.owner || '.' || c.object_name Object
, a.program Program
, ROUND(d.seconds_in_wait/60,2) WaitMin
gv$session a
, dba_locks b
, sys.dba_objects c
, gv$session_wait d
a.sid = b.session_id
AND b.lock_type IN ('DML','DDL')
AND b.lock_id1 = c.object_id
AND b.session_id = d.sid
ORDER BY 7
/
OS/Oracle SID/Serial# Type Hold Object Program Wait Time(minutos)
-------------------- ------------ ---- ---------- ------------------------------ --------------- ------------------
usuarioX:ownerX 252,46365 DML Row-X (SX) ownerX.tablex PCSIS316.EXE 31
usuarioX:ownerX 252,46365 DML Row-X (SX) ownerX.tabley PCSIS316.EXE 50
usuarioX:ownerX 252,46365 DML Row-X (SX) ownerX.tablef PCSIS316.EXE 45
usuarioX:ownerX 252,46365 DML Row-X (SX) ownerX.tablex PCSIS316.EXE 92
=> Como identificar a sessão geradora de lock e a sessão que está sofrendo lock?
Desde já, agradeço por toda atenção
