In meiner Oracle RAC-Datenbank mit 3 Knoten (Version 11.2.0.4) wird ein Deadlock gemeldet, wie im Warnprotokoll zu sehen ist. Da es sich um eine Oracle RAC-Datenbank handelt, werden Ressourcen global verwaltet und der Lock Manager Daemon (LMD) wird einbezogen. Die Nachricht im Alert-Log wies mich auf eine LMD-Trace-Datei hin, die diesen Global Wait-For-Graph (GWFG) enthielt.
*** 2015-02-27 04:16:33.183 Submitting asynchronized dump request [1c]. summary=[ges process stack dump (kjdglblkrdm1)]. Global blockers dump end:----------------------------------- Global Wait-For-Graph(WFG) at ddTS[0.394d] : BLOCKED 0x551b2c698 2 wq 2 cvtops x1 TM 0x11ffa3.0x0(ext 0x0,0x0)[6B000-0004-0000022D] inst 4 BLOCKER 0x5513ed318 2 wq 2 cvtops x1 TM 0x11ffa3.0x0(ext 0x0,0x0)[B6000-0006-00000099] inst 6 BLOCKED 0x5513ed318 4 wq 2 cvtops x1 TM 0x11ffa3.0x0(ext 0x0,0x0)[B6000-0006-00000099] inst 6 BLOCKER 0x5513ef5b8 4 wq 2 cvtops x1 TM 0x11ffa3.0x0(ext 0x0,0x0)[66000-0005-00000FDB] inst 5 BLOCKED 0x5513ef5b8 4 wq 2 cvtops x1 TM 0x11ffa3.0x0(ext 0x0,0x0)[66000-0005-00000FDB] inst 5 BLOCKER 0x551b2c698 4 wq 2 cvtops x1 TM 0x11ffa3.0x0(ext 0x0,0x0)[6B000-0004-0000022D] inst 4 * Cancel deadlock victim lockp 0x551b2c698
Hinweis: Das eigentliche SQL und einige andere Details wurden möglicherweise geändert, um Unschuldige zu schützen.
Da habe ich also 3 Sitzungen in den Deadlock verwickelt. Jeweils eine auf den Instanz-IDs 4, 5 und 6.
Ich habe mir die Ablaufverfolgungsdatei angesehen, die auf Instanz-ID 4 generiert wurde. Über dem GWFG befanden sich diese Informationen:
user session for deadlock lock 0x551b2c698 sid: 1727 ser: 539 audsid: 996549224 user: 13944/MP_SYS flags: (0x41) USR/- flags_idl: (0x1) BSY/-/-/-/-/- flags2: (0x40009) -/-/INC pid: 107 O/S info: user: oracle, term: UNKNOWN, ospid: 11229 image: [email protected] client details: O/S info: user: web-svc, term: web-server1, ospid: 4276:864 machine: DOMAIN\web-server1 program: iis.exe client info: user: WEBSERVICE current SQL: INSERT INTO MP_SYS.T2( column_list) SELECT column_list FROM MP_SYS.T1 WHERE MP_SYS.T1.P_ID=:B1 DUMP LOCAL BLOCKER: initiate state dump for DEADLOCK possible owner[107.11229] on resource TM-0011FFA3-00000000
So kann ich Informationen über die ausgeführte Maschine, das Programm und die SQL-Anweisung sehen. Die Benutzersitzungskennung in Rot oben entspricht dem ID-Wert im GWFG. Schauen wir uns noch einmal die ersten beiden Zeilen der GFWG an.
BLOCKED 0x551b2c698 2 wq 2 cvtops x1 TM 0x11ffa3.0x0(ext 0x0,0x0)[6B000-0004-0000022D] inst 4 BLOCKER 0x5513ed318 2 wq 2 cvtops x1 TM 0x11ffa3.0x0(ext 0x0,0x0)[B6000-0006-00000099] inst 6
Die SQL-Anweisung und Sitzungsdetails stimmen also mit dieser ersten Zeile überein. Diese Sitzung wird auf inst 4 blockiert. Der Blocker befindet sich auf inst6 und wird als 0x5513ed318 identifiziert . Na wer ist das? Es gibt keine weiteren Details in diesem GWFG, die uns beim BLOCKER helfen könnten.
Um mehr über den Blocker zu erfahren, ging ich zu inst 6 und tat Folgendes:
cd /u01/app/oracle/diag/rdbms/admin/orcl/orcl6/trace
grep 0x5513ed318 *
Also habe ich gerade einen grep für den Sitzungsidentifizierungswert durchgeführt und eine LMD-Trace-Datei erhalten. Ein Blick in diese LMD-Trace-Datei auf der anderen Instanz gibt mir Details über die blockierende Sitzung.
user session for deadlock lock 0x5513ed318 sid: 1206 ser: 2673 audsid: 996459926 user: 13944/MP_SYS flags: (0x41) USR/- flags_idl: (0x1) BSY/-/-/-/-/- flags2: (0x40009) -/-/INC pid: 182 O/S info: user: oracle, term: UNKNOWN, ospid: 7049 image: [email protected] client details: O/S info: user: web-svc, term: web-server2, ospid: 4276:864 machine: DOMAIN\web-server2 program: iis.exe client info: user: WEBSERVICE current SQL: DELETE FROM MP_SYS.T1 WHERE P_ID = :B1 DUMP LOCAL BLOCKER: initiate state dump for DEADLOCK possible owner[182.7049] on resource TM-0011FFA3-00000000
Ich kann sehen, dass die blockierte Sitzung eine INSERT-Anweisung für eine Tabelle ausgegeben hat und der Blocker eine DELETE-Anweisung für dieselbe Tabelle ausgegeben hat.
Es ist eine andere Sitzung beteiligt, aber an diesem Punkt ist es elementar, Sitzungsdetails mit denselben Schritten wie oben abzurufen.
Hoffentlich hat dieser Blogeintrag gezeigt, wie man die GWFG verwendet, um die SQL-Anweisungen und das am globalen Deadlock beteiligte Objekt zu diagnostizieren. Ich kenne die genauen SQL-Anweisungen, die an dem Deadlock beteiligt sind, und damit auch die beteiligten Objekte. Die Lösung des Problems unterscheidet sich nicht von der Deadlock-Auflösung in Einzelinstanzdatenbanken.
Weitere Informationen zu Oracle RAC Global Enqueue Services (GES) finden Sie in Kapitel 2 meines Oracle RAC Performance Tuning-Buchs.