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:
- Ich habe bestätigt, dass die OrderID-Spalte (Fremdschlüsselspalte) in der PLAN-Tabelle einen Index enthält.
- 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
orderid
eine 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.
orderID
und prüfen Sie, ob dies hilfreich ist.