Dlaczego niektóre DBMS nie pozwalają na wycofanie niektórych instrukcji DDL?

21

Niedawno dowiedziałem się, że MySQL nie obsługuje wycofywania DDL, takich jak „alter table” ... Przyzwyczajony do PostgreSQL, co wydało mi się dziwne, ale mój przyjaciel powiedział mi, że nawet Oracle nie pozwala na to. Czy istnieją techniczne powody, aby go nie obsługiwać? Czy jest to dla nich po prostu „nieciekawa” funkcja?

Edycja: właśnie znalazłem to porównanie . Wygląda na to, że istnieje wiele DBMS, które obsługują transakcyjny DDL.

Joril
źródło
3
MySQL nie zezwala na DDL wewnątrz transakcji. Przed wykonaniem instrukcji DDL zatwierdza bieżącą transakcję (wszystkie bieżące instrukcje DML wewnątrz tej transakcji!) Bez żadnego ostrzeżenia.
Frank Heikens
Dokładnie, dość denerwujące IMO :)
Joril
Osobiście jestem zaskoczony, że Postgres na to pozwala - czy możesz nawet cofnąć a DROPlub a RENAME?
Joe
1
Tak długo, jak nie upuścisz całej bazy danych, tak :) Zobacz link, który właśnie dodałem
Joril
Dlatego tylko Oracle i MySQL nie zezwalają na instrukcje DDL w ramach transakcji. Ta funkcja naprawdę umożliwia łatwe wdrażanie schematów.
Marian

Odpowiedzi:

19

Powodem, dla którego działa to w PostgreSQL, jest to, że katalogi systemowe są zwykłymi tabelami. Tak więc na przykład utworzenie nowej funkcji wymaga tylko wstawienia wiersza do pg_proctabeli, zmiana domyślnej wartości kolumny wymaga jedynie aktualizacji niektórych wierszy pg_attrdefi tak dalej. Ponieważ tabele i tak są transakcyjne, prawie musisz zejść z siebie, aby nie działały w ten sposób. (Wiele bolesnych szczegółów implementacji pominięto tutaj ;-))

Podejrzewam, że nie znając kodu źródłowego, inne silniki baz danych używają niestandardowych struktur wewnętrznych do reprezentowania informacji z katalogu systemowego. Musieliby więc włożyć dodatkowy wysiłek, prawdopodobnie duży wysiłek, aby transakcyjny DDL działał i najwyraźniej nie jest to dla nich priorytetem.

Wadą tego jest to, że główne aktualizacje PostgreSQL są tak bolesne. Inne produkty mogą prawdopodobnie projektować swoje wewnętrzne struktury metadanych z myślą o zmianach i aktualizacjach, więc nie ma problemów z aktualizacją do nowej głównej wersji. W PostgreSQL nie ma możliwości zmiany tabeli katalogu systemowego, aby nagle wyglądała jak nowsza wersja tabeli katalogu systemowego, przynajmniej nie podczas utrzymywania systemu w trybie online, ponieważ wymagałoby to dostępu do katalogów systemowych. Urgh.

Peter Eisentraut
źródło
1
Cóż, wolę mój DB w spójnym stanie przez cały czas niż łatwość aktualizacji DB, ale myślę, że to kwestia opinii :) Dziękuję za wyjaśnienie!
Joril,
Może to wyjaśniać problem niektórych baz danych, ale katalogi systemowe to zwykłe tabele w Oracle.
Leigh Riffel,
10

Większość nie? Bummer.

Używam głównie SQL Server i tak się dzieje. Wiem, że Oracle nie, ale myślałem, że może to być aberracja.

W SQL Server jestem pewien, że możesz uruchomić wiele instrukcji DDL w jednej transakcji, chociaż uważam również, że istnieje kilka ograniczeń (o których wszyscy zapomniałem). Możesz stworzyć lub zmienić lub upuścić większość rzeczy i cofnąć, jeśli chcesz. Red-Gate SQL Compare (narzędzie, które kocham) korzysta z tego.

Problem polega na tym, że zakres transakcji staje się dość interesujący ... Gdy zaangażujesz katalogi systemowe w transakcję aktualizacji (DDL), ryzykujesz podjęcie naprawdę ważnych blokad i możesz zablokować dostęp do katalogów systemowych. Użytkownicy nie mogą wiele zrobić, jeśli ich zapytania nie mogą znaleźć tabel w katalogach!

Podsumowując, przydatne jest włączenie DDL do transakcji zawierającej wiele wyciągów.

Bardziej użyteczne polecenie SQL Server DDL TRUNCATE może być również elementem transakcji zawierającej wiele wyciągów . Możesz obciąć tabelę docelową (bardzo szybko), zbudować ją, a następnie wykonać zatwierdzenie, jeśli podoba ci się wynik. Jeśli coś pójdzie nie tak, wycofujesz się i voila !, to tak, jakbyś nigdy nie zakłócał stołu. Przestrzeń dziennika jest również zminimalizowana. Korzystam z tego dość często.

KillerDBA
źródło
2
Oto odpowiedź, która pokazuje przykład DDL związanego z transakcją w SQL Server. Poza tym zawsze myślałem, TRUNCATEże nie można tego cofnąć. Myliłem się.
Nick Chammas
5

W SQL Server możemy wycofać instrukcje DDL, nie używa automatycznego zatwierdzania na końcu instrukcji. W innych DBMS nie wiem, ale pamiętam, że w Oracle nie można zrobić tego samego. Uważam, że jest specyficzny dla każdego DBMS, nie jestem pewien, co powiedziałby na ten temat standard SQL, ale jestem pewien, że żaden producent nie implementuje 100% standardu.

Podobne pytanie dotyczy SO: Czy można uruchomić wiele instrukcji DDL w ramach transakcji (w programie SQL Server)?

Marian
źródło
5

Oracle współużytkuje parsowanie zapytań, więc WYBIERZ * Z table_a wykonany przez jedną sesję jest (zwykle) taki sam jak w innej sesji. To by się załamało, gdyby jedna sesja myślała, że ​​w tabeli jest dziesięć kolumn, a inna, że ​​jedenaście.

Gary
źródło
Interesujące, że powinieneś powiedzieć, że miałem podobny problem innego dnia, aplikacja miała być „gorąca” do wdrożenia, ale zmieniając strukturę tabeli dla nowej wersji, nie było sposobu na rekompilację JDBC PreparedStatements poza ponownym uruchomieniem , tyle za to!
Gajusz
2
Nawiasem mówiąc, wersja 11gR2 wprowadza koncepcję Edycji, aby pomóc w gorących aktualizacjach. Skutecznie istniejące połączenia używają jednej edycji (z pięcioma kolumnami). Zaczynasz nową edycję, dodajesz kolumnę i nawiązujesz nowe połączenia, używając nowej edycji do nowych sesji. Po zakończeniu wszystkich zaległych sesji stare wydanie jest sflaczałe i wszystko korzysta z nowego wydania. Bez wycofywania, ale nie nakładasz nowej aktywności na nowe wydanie, dopóki wszystko nie zacznie działać.
Gary