Dynamiczny SQL w procedurach przechowywanych w MySQL

Odpowiedzi:

8

Samo usłyszenie pytania kojarzy mi się z dwoma aspektami:

ASPEKT 1: Funkcje mają być DETERMINISTYCZNE

Jeśli tak, oznacza to, że funkcja powinna konsekwentnie prezentować te same dane zwrotne dla danego zestawu parametrów, BEZ WZGLĘDU NA WYWOŁANIE FUNKCJI.

Teraz wyobraź sobie funkcję, która daje inną odpowiedź z powodu gromadzenia danych o różnych porach dnia w oparciu o statyczny SQL w funkcji. W pewnym sensie można to nadal uznać za DETERMINISTYCZNE, jeśli za każdym razem pytasz ten sam zestaw tabel i kolumn, biorąc pod uwagę ten sam zestaw parametrów.

Co jeśli możesz zmienić podstawowe tabele funkcji za pomocą Dynamicznego SQL? Naruszasz definicję funkcji DETERMINISTYCZNEJ.

Zauważ, że MySQL dodał tę opcję w /etc/my.cnf

log-bin-trust-function-creators

Chociaż może to być nadmierne uproszczenie, pozwala to funkcjom na zapis danych w dziennikach binarnych bez ścisłego egzekwowania właściwości DETERMINISTIC.

ASPEKT 2: Wyzwalacze powinny mieć możliwość wycofania

  • Czy możesz sobie wyobrazić wyzwalacz z tymi samymi zachowaniami jako funkcją, a następnie wprowadzający dynamiczny SQL do miksu?
  • Czy możesz sobie wyobrazić próbę zastosowania MVCC (Multiversion Concurrecy Control) wobec Dynamic SQL po zastosowaniu MVCC do tabeli podstawowej, dla której przeznaczony był wyzwalacz?

Zasadniczo miałbyś dane, które rosną kwadratowo (nawet wykładniczo) tylko w samym MVCC. Proces zarządzania wycofywaniem SQL za pomocą wyzwalaczy, które mogą nie być DETERMINISTYCZNE, byłby, co najmniej, bezbożny.

W świetle tych dwóch aspektów jestem pewien, że programiści MySQL pomyśleli o tych rzeczach i szybko je odrzucili, nakładając ograniczenia.

Po co więc znosić ograniczenie procedur? Mówiąc najprościej, nie ma obaw co do właściwości DETERMINISTYCZNYCH ani wycofywania.

RolandoMySQLDBA
źródło
3
Nie może być tak „bezbożny”, jeśli inne DBMS mogą bardzo dobrze obsługiwać MVCC i dynamiczny SQL w wyzwalaczach.
a_horse_w_no_name
1
Właściwie, @a_horse_w_no_name masz rację. W przypadku Oracle i PostgreSQL kodowano bezbożny kompleks. +1 za komentarz. MySQL ma utrudnienia w radzeniu sobie z wieloma silnikami pamięci, więc wycofanie i determinizm mogą wymagać nakładania się operacji silnika pamięci. To trochę przerażające. Może ktoś będzie miał dość odwagi, by wcisnąć „bezbożny kompleks” w InnoDB w całości. Jeszcze bardziej pożądane byłoby stworzenie implementacji wyzwalacza specyficznej dla silnika pamięci masowej w taki sposób, aby nie pozwalało mieszać silników pamięci masowej w ramach tego samego zapytania.
RolandoMySQLDBA
5

To świetne pytanie, ale nie znam odpowiedzi. Wyobrażam sobie, że będzie to wymagało dołączenia do zespołu internals, ale nie wiem, czy będą duże na tej stronie. W międzyczasie mogę ci pomóc wydedukować kilka odpowiedzi.

Na początek widzę to:

Pamięć podręczna wyzwalacza nie wykrywa zmiany metadanych obiektów podstawowych. Jeśli wyzwalacz korzysta z tabeli, a tabela uległa zmianie od czasu załadowania wyzwalacza do pamięci podręcznej, wyzwalacz działa przy użyciu nieaktualnych metadanych.

Co sprawia, że ​​myślę, że to ma z tym coś wspólnego. Nie będzie ponownej kompilacji SQL, jeśli nawet nie monitoruje metadanych. Co oznacza, że ​​dotyczy to silnika.

Z tego samego powodu, gdy czytam ten blok, myślę o tym samym (silniku):

Aby zapobiec problemom z interakcją między wątkami serwera, gdy klient wydaje instrukcję, serwer używa migawki procedur i wyzwalaczy dostępnych do wykonania instrukcji. Oznacza to, że serwer oblicza listę procedur, funkcji i wyzwalaczy, których można użyć podczas wykonywania instrukcji, ładuje je, a następnie przystępuje do wykonania instrukcji. Oznacza to, że podczas wykonywania instrukcji nie zobaczy zmian w procedurach wykonywanych przez inne wątki.

Podsumowując, nie jestem do końca pewien, dlaczego na to nie pozwalają, ale zgaduję. Przepraszam, że nie mogę ci więcej pomóc, jestem otwarty na wyjaśnienie tego bardziej. Najlepiej jest mieć nadzieję na niektórych aktywnych deweloperów MySQL, kiedy opuścimy prywatną wersję beta;)

jcolebrand
źródło
1

W dużej mierze wynika to z bezpieczeństwa. Wyjątkiem dla procedur jest to, że dynamicznemu SQL w ramach procedury można przypisać kontekst bezpieczeństwa wykonującego użytkownika. Oznacza to, że chociaż silnik nie wie, co ma zostać wykonane, może upewnić się, że użytkownik ma dostęp do obiektów, do których istnieją odniesienia.

Poza tym możesz podnieść brzydkie kwestie tego, co mogłoby się zdarzyć, gdyby było to dopuszczalne.

dba4life
źródło