web-dev-qa-db-fra.com

Recherche de la cause de l'erreur de blocage dans le fichier de trace Oracle

J'ai souvent cette erreur "ora-00060 détectée en attendant la ressource" souvent dans mon application lorsque plusieurs utilisateurs utilisent l'application. J'ai le fichier de trace de l'administrateur Oracle, mais j'ai besoin d'aide pour le lire. Vous trouverez ci-dessous des bits de données du fichier de trace, qui, je l'espère, aideraient à localiser la cause.

*** 2013-06-25 09:37:35.324
DEADLOCK DETECTED ( ORA-00060 )

[Transaction Deadlock]

The following deadlock is not an Oracle error. It is a deadlock due 
to user error in the design of an application
or from issuing incorrect ad-hoc SQL. The following
information may aid in determining the deadlock:

Deadlock graph:
                   ---------Blocker(s)--------  ---------Waiter(s)---------
Resource Name          process session holds waits  process session holds waits
TM-000151a2-00000000       210      72    SX   SSX      208      24    SX   SSX
TM-000151a2-00000000       208      24    SX   SSX      210      72    SX   SSX

session 72: DID 0001-00D2-000000C6  session 24: DID 0001-00D0-00000043 
session 24: DID 0001-00D0-00000043  session 72: DID 0001-00D2-000000C6 

Rows waited on:
 Session 72: no row
 Session 24: no row

----- Information for the OTHER waiting sessions -----
Session 24:
 sid: 24 ser: 45245 audsid: 31660323 user: 90/USER
  flags: (0x45) USR/- flags_idl: (0x1) BSY/-/-/-/-/-
  flags2: (0x40009) -/-/INC
 pid: 208 O/S info: user: zgrid, term: UNKNOWN, ospid: 2439
   image: [email protected]
 client details:
   O/S info: user: , term: , ospid: 1234
   machine: xyz.local program: 
 current SQL:
  delete from EMPLOYEE where EMP_ID=:1

 ----- End of information for the OTHER waiting sessions -----

Information for THIS session:

 ----- Current SQL Statement for this session (sql_id=dyfg1wd8xa9qt) -----
 delete from EMPLOYEE where EMP_ID=:1
===================================================

J'apprécierais que quelqu'un me dise ce que dit le "Deadlock graph ::". De plus, les lignes attendues dans la section ne contiennent aucune ligne.

J'ai également lu dans certains blogs que la section "sqltxt" du fichier de trace peut suggérer la cause. Voici la requête que je vois dans cette section.

 select /*+ all_rows */ count(1) from "USERS"."EMPLOYEE_SALARY" where EMPSAL_EMP_ID=:1

La table employee_salary a une contrainte de clé étrangère sur la colonne EMPSAL_EMP_ID.

Le conseil sql indique "all_rows", donc cela signifie-t-il que cette table obtient le verrouillage au niveau de la table lors de la suppression des enregistrements de la table des employés? je n'ai pas d'index sur la colonne de clé étrangère actuellement. L'ajout d'un index sur cette colonne serait-il utile?

Veuillez poster, au cas où plus d'informations seraient nécessaires.

Merci

15
shashikanthb

Tout d'abord, l'instruction select ne verrouille jamais rien dans Oracle, utilise uniquement la dernière version cohérente disponible des données. Ce n'est pas un cas pour select ... for update qui verrouille les données comme update depuis Oracle 9i, mais il n'y a pas for update clause dans la requête de la question.

Resource Name          process session holds waits  process session holds waits
TM-000151a2-00000000       210      72    SX   SSX      208      24    SX   SSX

La session n ° 72 contient un verrou de niveau table (TM) avec le type "Row Exclusive" (SX) et souhaite acquérir un verrou "Partager Row Exclusive" (SSX) sur la même table. Cette session bloquée par la session # 24 qui détient déjà un verrou de niveau table d'un même type (SX) et attend que le verrou SSX soit disponible.

Resource Name          process session holds waits  process session holds waits
TM-000151a2-00000000       208      24    SX   SSX      210      72    SX   SSX

Cette (deuxième ligne) montre exactement la même situation, mais dans la direction opposée: la session # 24 attend que le verrouillage SSX soit disponible, mais bloqué par la session # 72 qui détient déjà le verrouillage SX sur la même table.

Ainsi, les sessions # 24 et session # 72 se bloquent: un blocage se produit.

Les deux types de verrous (SX et SSX) sont des verrous de niveau table.
Pour comprendre la situation, je recommande de lire cet article par Franck Pachot.

Vous trouverez ci-dessous la citation de cet article, qui concerne directement votre situation (notez que les abréviations SSX et SRX sont équivalentes):

L'intégrité référentielle acquiert également des verrous TM. Par exemple, le problème courant avec les clés étrangères non indexées conduit à des verrous S sur la table enfant lorsque vous effectuez une suppression ou une mise à jour sur la clé, sur la table parent. En effet, sans index, Oracle n'a pas de ressource de niveau inférieur unique à verrouiller afin d'empêcher une insertion simultanée pouvant violer l'intégrité référentielle.
Lorsque les colonnes de clé étrangère sont les colonnes de tête d'un index normal, la première entrée d'index avec la valeur parent peut être utilisée comme une ressource unique et verrouillée avec un verrou TX au niveau de la ligne.
Et si l'intégrité référentielle a une cascade de suppression? En plus du mode S, il est prévu de mettre à jour les lignes de la table enfant, comme avec le mode Row X (RX). C'est là que la ligne de partage exclusive (SRX) se produit: S + RX = SRX.

Ainsi, la variante la plus probable est que la session # 72 et la session # 24 suppriment en même temps certaines lignes de la table EMPLOYEE, et il y a on delete cascade contrainte pour EMPSAL_EMP_ID en conjonction avec l'absence d'index sur EMPLOYEE_SALARY table dans laquelle EMPSAL_EMP_ID colonne répertoriée en premier.

30
ThinkJet