ORA-12860 i _high w OCI - gdy równoległość robi pod górkę

Autor
Damian
Terlecki
3 minuty
Bazy danych

Ostatnio prototypowałem małą aplikację korzystającą z Oracle Autonomous Database na OCI (Oracle Cloud Infrastructure). Bez większego zastanowienia wybrałem pierwszą dostępną usługę o nazwie "_high", nie przeczuwając nadchodzących problemów. Przecież "_high" brzmi lepiej niż "_low", prawda?

Kilka dni później zacząłem zauważać dziwne zachowanie, szczególnie podczas usuwania i ponownego wstawiania rekordów do tabeli w ramach jednej transakcji.

Tabela była prosta:

CREATE TABLE foo (
    bar_id      VARCHAR2(255) PRIMARY KEY,
    bar_user_id VARCHAR2(255) NOT NULL,
    bar_content VARCHAR2(2000)
);

Miałem tam kilka rekordów i próbowałem je usunąć, a następnie ponownie dodać - zarówno stare, jak i nowe:

DELETE FROM foo WHERE bar_user_id = 'some_user_id';

INSERT INTO foo (bar_id, bar_user_id, bar_content) VALUES ('old_id_1', 'some_user_id', 'new_content');
INSERT INTO foo (bar_id, bar_user_id, bar_content) VALUES ('old_id_2', 'some_user_id', 'new_content');
-- ...more inserts

i nagle dostałem błędem w twarz:

ORA-12860: deadlock detected while waiting for a sibling row lock

Nie tego się spodziewałem po tak prostym przypadku.

Sprawdziłem ustawienia tabeli, indeksy, triggery - nic podejrzanego. I wtedy mnie tknęło - przypomniałem sobie, że różne usługi bazy danych w OCI są zoptymalizowane pod różne obciążenia.

Rzeczywisty problem leżał w poziomie zrównoleglenia sesji przy połączeniu przez usługę _high. Szybkie spojrzenie na widok gv$px_session z konta DBA pokazało degree większy niż 1.

Po połączeniu v$session z v$transaction po saddr wyciągnąłem nieco więcej informacji. Początkowy DELETE uruchomił 4 równoległe procesy. Późniejsze INSERTy, próbujące dodać rekordy usunięte w tej samej transakcji, wywołały wspomniany wcześniej deadlock.

Jak można się domyślić, przełączenie na usługę _low, która wyłącza równoległość, rozwiązało problem.

Jeśli trafiłeś tutaj z podobnym błędem ORA-12860, mam nadzieję, że to krótkie wyjaśnienie zaoszczędziło Ci trochę nerwów. W chwili pisania tego posta wyniki wyszukiwania dla tego błędu nie są zbyt pomocne do szybkiej diagnozy.

Po więcej informacji, ruć okiem na opis predefiniowanych usług Oracle Autonomous Database w OCI.