Oracle Ref Partitioning: Deadlock aufgrund der Migration von untergeordneten Tabellenzeilen


7

Meine Bestellanwendung verwendet die Oracle 11g-Datenbank. Diese Datenbank verfügt über eine Primärtabelle ORDERS und mehrere untergeordnete Tabellen wie ORDER_DETAILS, PLAN usw.

Die Tabelle ORDERS ist in der Spalte STATUS LIST-partitioniert, und alle anderen Tabellen sind referenziert und mit ORDERID als Fremdschlüssel partitioniert.

Bei Spitzenlast, wenn der Auftragsstatus geändert wird und die ORDERS-Tabellenzeile von einer Partition auf eine andere verschoben wird, führt Oracle eine Zeilenmigration für alle untergeordneten Tabellen durch, auf die durch die ORDERS-Tabelle partitioniert wird. Aufgrund vieler Tabellen, die von der Tabelle ORDERS abhängen, kommt es zu einer großen Anzahl von Zeilenbewegungen, die zu einem Deadlock in einer der untergeordneten Tabellen führen.

Meine Frage ist, wie ein Deadlock behoben werden kann, der im internen Zeilenmigrationsschritt von ORACLE verursacht wurde.

Hier ist ein Beispielsetup:

ORDERS Tabelle:

CREATE TABLE ORDERS (
       orderID   NUMBER PRIMARY KEY,
       description    VARCHAR2(30),
       status   VARCHAR2(30))
  PARTITION BY LIST (status) (  
       PARTITION A VALUES ('COMPLETED'), 
       PARTITION B VALUES ('ACTIVE'), 
       PARTITION C VALUES ('SUBMITTED'))

Kindertisch: PLAN

CREATE TABLE PLAN (
       planID   NUMBER PRIMARY KEY,
       orderID    NUMBER,
       description   VARCHAR2(30),
       CONSTRAINT FKC64393AD1EC7235 FOREIGN KEY (orderID) 
       REFERENCES ORDERS (orderID) ON DELETE CASCADE
 )
 PARTITION BY REFERENCE (FKC64393AD1EC7235);

Es gibt viel mehr untergeordnete Tabellen, in denen ORDERS übergeordnete Tabellen enthält.

Wenn unter schwerer Last der ORDER-Status geändert wird, der eine Zeilenverschiebung zwischen Partitionen verursacht, wird der folgende Deadlock-Fehler im Protokoll ORA-00060 gedruckt: Deadlock beim Warten auf Ressource erkannt

Im Oracle-Ablaufverfolgungsprotokoll wird folgende SQL angezeigt, die einen Deadlock verursacht

update /*+ opt_param('_and_pruning_enabled', 'false') */ "TEST"."PLAN" partition (dataobj_to_partition( "TEST"."ORDERS" , :1)) move to partition (dataobj_to_partition( "TEST"."ORDERS" , :1)) set "ORDERID" = "ORDERID" where "ORDERID" = :1

Jetzt wird diese SQL intern von Oracle generiert, um die Zeilenmigration für die untergeordnete PLAN-Tabelle durchzuführen.

Um das Problem zu beheben, habe ich folgende Änderungen versucht:

  1. Ich habe bestätigt, dass die OrderID-Spalte (Fremdschlüsselspalte) in der PLAN-Tabelle einen Index enthält.
  2. Es wurde versucht, den PCTFREE-Parameter in der Tabelle zu erhöhen.

Aber ich habe noch keinen Erfolg. Wie gehe ich mit Deadlocks für dieses Szenario um?

------------------------- UPDATE ------------------------ - -

Gemäß den Vorschlägen von Wernfried und Gandolf989 habe ich überprüft, ob alle meine Fremdschlüssel Indizes enthalten, indem ich die in der Antwort von Gandolf989 angegebene Abfrage ausgeführt habe.

Ergebnis war "Keine Zeilen gefunden". Es bedeutet also, dass alle Indizes vorhanden zu sein scheinen. Bei der Analyse wurde mir jedoch klar, dass beim Überprüfen eines Erklärungsplans für eine einfache Abfrage wie unten ein vollständiger Tabellenscan für die PLAN-Tabelle angezeigt wird, selbst nachdem ein Index für die ORDERID-Spalte vorhanden ist.

 UPDATE PLAN SET DESCRIPTION = 'ABC' WHERE orderid= '234';

Im Folgenden finden Sie die Indexanweisung, die ursprünglich für diese Tabelle ausgeführt wurde.

 CREATE INDEX IDX_PLAN_ORDERID ON  PLAN(ORDERID);

Aus irgendeinem Grund berücksichtigt ORACLE den Index nicht, während die Aktualisierungsabfrage für die PLAN-Tabelle ausgeführt wird. Vermisse ich etwas


Versuchen Sie, einen Index für die Spalte zu erstellen, orderIDund prüfen Sie, ob dies hilfreich ist.
Wernfried Domscheit

@Wernfried, danke für die Kommentare, ich habe meine Frage mit einer Analyse der laufenden fehlenden Indexabfrage aktualisiert. Bitte überprüfen Sie
Sauchin

1
Ist orderideine Nummer? Oder eine Schnur? Der Name impliziert eine Nummer. Die von Ihnen gepostete Abfrage impliziert eine Zeichenfolge. Was ist das Deadlock-Diagramm? Ein Deadlock bedeutet, dass A eine Sperre hat, auf die B wartet, und B eine Sperre hat, auf die A wartet. Sie haben uns gezeigt, worauf eine der Abfragen wartet, aber nicht, worauf die andere Sitzung wartet. Ist es möglich, dass andere Sitzungen zur gleichen Zeit mit derselben Reihenfolge arbeiten? Möglicherweise benötigen Sie die Sitzung, die den Status ändert, um exklusiven Zugriff auf die Bestellung zu haben.
Justin Cave

Wird bei der Abfrage zum Aktualisieren des Bestellstatus eine Select for Update-Klausel für alle relevanten Tabellen verwendet? Dies würde den Schreibzugriff auf die möglichen Ursachen für den Deadlock blockieren. Wenn dies möglich ist, muss die Leistung getestet werden.
Grimaldi

1
Wenn Ihre plan.orderid eine Nummer ist, warum erzwingen Sie sie dann als varchar2? Versuchen Sie, die einfachen Anführungszeichen um die Bestellnummer 234 im Update zu entfernen.
Raj

Antworten:


0

Dies kann durch nicht indizierte Fremdschlüssel verursacht werden. Tom Kyte hat eine Abfrage, mit der Sie sie finden können. Es könnte so einfach sein, wie ein paar Indizes zu den untergeordneten Tabellen hinzuzufügen.

Nicht indizierte Fremdschlüssel


Ich denke, eine solche Vermutung in Kombination mit einem Link sollte als Kommentar, aber auch nicht als Antwort veröffentlicht werden.
Wunder173

@ Gandolf989, danke für die Kommentare, ich habe meine Frage mit der Analyse der laufenden fehlenden Indexabfrage aktualisiert. Bitte überprüfen Sie
Sauchin
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.