Reset

In Branżowe by xpil0 Comments

Od kilku godzin walczyłem z dość nietypowym problemem, który wreszcie udało mi się rozwiązać, czym się niezwłocznie chwalę :>

Otóż w ramach jednego z projektów ETL, musiałem zaktualizować tabelę docelową danymi z tabeli źródłowej. Bez zbytniego wchodzenia w szczegóły powiem tylko, że użyłem do tego celu instrukcji MERGE, która (jak wszystkie Bazyle dobrze wiedzą) jest sprytnym złożeniem INSERT, UPDATE i DELETE.

Tabele (zarówno docelowa jak i źródłowa) miały ponad 60 kolumn. Ilość rekordów – niecałe ćwierć miliona, więc zasadniczo drobiazg.

Zapuszczam więc tego MERGE-a, oczekuję, że wykona się w czasie około jednej sekundy. Czekam minutę, dwie, pięć…
… wypijam drugą kawę…
… wreszcie, po 62 minutach, zapytanie wysypuje się, z bardzo szczegółowym i wiele mówiącym komunikatem błędu:

java.sql.SQLException: ORA-00600: internal error code, arguments: [13013], [5001], [4643765], [63164389], [9], [63164389], [17], [], [], [], [], []

Ki czort, myślę sobie… Zagadałem do paru lokalnych gurów, ale wzruszali tylko ramionami.

Myślę sobie, taki ty owaki dziadygo, pewnie nie możesz przełknąć któregoś z rekordów. Metodą bisekcji próbowałem wykumać który rekord powoduje problem, ale bezskutecznie. Nawet ograniczając zapytanie do jednego rekordu, wciąż dostawałem ten sam błąd. Wyjątkiem była sytuacja, w której tabela docelowa była pusta – wówczas cały MERGE wykonywał się w 0.15 sekundy. Kolejne jednak jego uruchomienie szło już w maliny.

Stąd też wywnioskowałem, że musiał kucnąć blok UPDATE. Znów zastosowałem metodę bisekcji, tym razem na zbiorze modyfikowanych kolumn. I tu pierwszy sukces: udało mi się wyizolować jedną, jedyną kolumnę, która powodowała problem. Jeżeli usunąłem ją z zapytania, całość wykonywała się w trymiga, niezależnie od ilości danych oraz kolumn. Jeżeli wstawiłem ją do zapytania, rozsypywało się ono nawet na pojedynczym rekordzie.

Kolejnym krokiem było więc porównanie planów zapytań z tą kolumną vs bez niej. Jednak żadnej różnicy nie zauważyłem. Przyjrzałem się uważniej definicji tabeli, i okazało się, że wszystkie inne kolumny są indeksowane, a ta jedna – nie.

Pomijając zasadność zakładania ponad sześćdziesięciu indeksów, założyłem, że trzeba założyć indeks i na tej jednej. Co też zrobiłem (na trzy różne sposoby, próbując za każdym razem uruchamiać MERGE), jednak bez spodziewanego rezultatu. Pomimo indeksu na tej kolumnie, MERGE wciąż się sypał.

Sięgnąłem więc po broń ostateczną. Po miecz gordyjski. Po odpowiednik przycisku RESET na obudowie komputera. Wywaliłem tę kolumnę z tabeli po czym dodałem ją ręcznie od nowa.

I co?

I pomogło!

Człowiek spędza prawie dwadzieścia lat w różnych instytucjach edukacyjnych, a na koniec uczy się, że 99% problemów da się załatwić przyciskiem RESET. Lub jego odpowiednikiem…

Dodaj komentarz

Bądź pierwszy!

Powiadom o
avatar
wpDiscuz