Динамічний SQL в MySQL зберігається підпрограми


13

Відповідно до обмежень на збережені підпрограми та тригери , не можна використовувати динамічний sql (обмеження знято для збережених процедур у версії 5.0.13 та пізніших версій). Чому це обмеження діє? І навіщо піднімати його на процедури, а не на функції чи тригери?

Відповіді:


8

Щойно почувши це питання, я змушує задуматися про два аспекти:

АСПЕКТ №1: Функції повинні бути ДЕТЕРМІНІСТИЧНІ

Якщо це так, це означає, що функція повинна послідовно представляти однакові дані повернення для заданого набору параметрів, НЕ МАТЕРІАЛИ, КОЛИ ВИ ВЗАЄМО ФУНКЦІЮ.

Тепер уявіть собі функцію, яка виробляє іншу відповідь через збирання даних у різний час доби на основі статичного SQL у функції. У певному сенсі це все ще можна вважати ДЕТЕРМІНІСТИЧНІМ, якщо ви кожен раз запитуєте один і той же набір таблиць і стовпців із заданим набором параметрів.

Що робити, якщо ви могли змінити основні таблиці функції за допомогою Dynamic SQL? Ви порушуєте визначення ДЕТЕРМІНІСТИЧНОЇ функції.

Зауважте, що MySQL додав цю опцію в /etc/my.cnf

log-bin-trust-function-creators

Хоча це може бути надмірним спрощенням, це дозволяє дозволити функціям записувати дані у бінарні журнали, не суворо виконуючи властивість DETERMINISTIC.

АСПЕКТ №2: Тригери повинні бути спроможні повернути назад

  • Чи можете ви уявити собі тригер із такою ж поведінкою як функцію, а потім ввести Dynamic SQL у суміш?
  • Чи можете ви уявити собі спробу застосувати MVCC (Multiversion Concurrecy Control) проти Dynamic SQL після застосування MVCC до базової таблиці, для якого був призначений тригер?

По суті, у вас є дані, які ростуть квадратично (навіть експоненціально) лише в MVCC. Процес управління відкатом SQL за допомогою тригерів, які можуть бути недетермінантними, був би нечесним чином складним.

Зважаючи на ці два аспекти, я впевнений, що розробники MySQL подумали про ці речі та швидко відхилили їх, встановивши обмеження.

Отже, навіщо скасовувати обмеження на процедури? Простіше кажучи, жодних проблем щодо ДЕТЕРМІНІСТИЧНИХ властивостей чи відкатів немає.


3
Не може бути настільки "безбожно складним", якщо інші СУБД можуть дуже добре підтримувати MVCC і динамічний SQL в тригерах.
a_horse_with_no_name

1
Насправді, @a_horse_with_no_name, ти маєш рацію. Для Oracle та PostgreSQL був закодований нечестивий комплекс. +1 для вашого коментаря. MySQL має обмеження щодо роботи з декількома двигунами зберігання, тому відкат та детермінізм можуть зажадати перекриття операцій двигуна зберігання. Це трохи страшно. Можливо, комусь доведеться кинути в повному обсязі "безбожно складний" InnoDB. Ще більш бажаним було б створити реалізацію тригера, що відповідає специфічному механізму зберігання, таким чином, щоб це не дозволяло змішувати двигуни зберігання даних в межах одного запиту.
RolandoMySQLDBA

5

Це чудове запитання, але я не знаю відповіді. Я думаю, що для цього доведеться зайти до команди внутрішніх служб, але я не знаю, що вони зароблять на цьому сайті. Тим часом я можу допомогти вам вивести деякі відповіді.

Для початку я бачу це:

Кеш тригера не визначає, коли змінилися метадані базових об'єктів. Якщо в тригері використовується таблиця, і таблиця змінилася з моменту завантаження тригера в кеш, тригер працює з застарілими метаданими.

Що змушує мене думати, що це має щось спільне з цим. Перекомпіляція SQL не збирається, якщо вона навіть не контролює метадані. Що означає, що це турбота про двигун.

Таким же чином, коли я читаю цей блок, то думаю те саме (двигун):

Щоб запобігти проблемам взаємодії між потоками сервера, коли клієнт видає заяву, сервер використовує знімок підпрограм і тригерів, доступних для виконання оператора. Тобто сервер обчислює перелік процедур, функцій та тригерів, які можуть бути використані під час виконання оператора, завантажує їх, а потім переходить до виконання оператора. Це означає, що поки оператор виконується, він не побачить змін у підпрограмах, виконаних іншими потоками.

Так що я в цілому не зовсім впевнений, чому вони цього не дозволяють, але я можу здогадатися. Вибачте, що я не можу вам допомогти більше, я відкритий для того, щоб висунути це ще раз. Найкраще сподіватися на деякі активні розробки MySQL, коли ми залишимо приватну бета-версію;)


1

Багато в чому це пов’язано з безпекою. Виняток для процедур полягає в тому, що динамічному SQL в рамках процедури може бути призначений контекст безпеки користувача, що виконує. Це означає, що незважаючи на те, що двигун не знає, що буде виконуватися, він може переконатися, що користувачеві дозволено отримувати доступ до посилаються об'єктів.

Крім того, ви можете підняти потворні питання того, що може статися, якщо це було б допустимо.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.