Spec-Zone.ru › MySQL 9.2

27.3.5 JavaScript-сохранённые программы—информация о сеансе и параметры

Для получения общей информации о сохранённых процедурах в MySQL, см. Раздел 27.2, «Использование сохранённых процедур».

Компонент MLE предоставляет ряд загружаемых функций для работы с пользовательскими сеансами MLE. Эти функции перечислены и описаны ниже:

  • mle_session_reset()

    Вызов этой функции очищает текущее состояние сеанса MLE, удаляя любой наблюдаемый вывод из mle_session_state(). Также она сбрасывает часовой пояс сеанса, поэтому последующие вызовы JavaScript-сохранённых процедур используют часовой пояс, последний раз установленный в сеансе.

  • mle_session_state()

    Используйте эту загружаемую функцию для получения информации о сеансе о последней выполненной сохранённой программе MLE. mle_session_state() принимает один аргумент, ключ состояния сеанса (строка), и отображает значение состояния сеанса. Значение состояния сеанса ограничено максимальным размером 64 КБ (что эквивалентно 16000 4-байтовым символам). Это циклический буфер; когда доступное место закончится, новая запись перезапишет самую старую. Возможные ключи состояния сеанса перечислены здесь со своими описаниями:

    • is_active: Возвращает 1, если текущий сеанс MySQL-пользователя — сеанс MLE, иначе 0.

    • stdout: Выводит всё, что было выведено сохранённой программой, используя console.log().

    • stderr: Выводит всё, что было выведено сохранённой программой, используя console.error().

    • stack_trace: Если выполнение сохранённой программы MLE не удалось, здесь содержится трассировка стека, которая может помочь в определении источника ошибки.

      Синтаксические и аналогичные ошибки, возникшие во время неуспешного выполнения оператора CREATE FUNCTION или CREATE PROCEDURE, не записываются сюда, записываются только ошибки выполнения, возникшие во время выполнения сохранённой функции или сохранённой процедуры.

    • stored_functions: Возвращает количество текущих кэшированных сохранённых функций в текущем сеансе.

    • stored_procedures: Возвращает количество текущих кэшированных сохранённых процедур в текущем сеансе.

    • stored_programs: Возвращает количество текущих кэшированных сохранённых программ (сохранённых функций и сохранённых процедур) в текущем сеансе.

    Ключ состояния сеанса — это значение литеральной строки и должен быть заключён в кавычки.

    Перед вызовом любых сохранённых программ MLE все три значения состояния сеанса пустые. Выход из клиента и перезапуск сеанса очищает все из них.

    Два следующих примера иллюстрируют получение значений состояния сеанса. Начнём с создания сохранённой процедуры mle_states(), которая отображает все значения состояния сеанса, так:

    mysql> delimiter //
    mysql> CREATE PROCEDURE mle_states()
        -> BEGIN
        ->   SELECT
        ->     mle_session_state("is_active") AS '-ACTIVE-',
        ->     mle_session_state("stdout") AS '-STDOUT-',
        ->     mle_session_state("stderr") AS '-STDERR-',
        ->     mle_session_state("stack_trace") AS '-STACK-',
        ->     mle_session_state("stored_functions") AS '-FUNCS-',
        ->     mle_session_state("stored_procedures") AS '-PROCS-',
        ->     mle_session_state("stored_programs") AS '-PROGS-';
        -> END//
    Query OK, 0 rows affected (0.02 sec)
    
    mysql> delimiter ;
    

    Перед запуском любых сохранённых программ MLE все значения в выводе из mle_states() равны 0 или пусты, как показано здесь:

    mysql> CALL mle_states();
    +----------+----------+----------+---------+---------+---------+---------+
    | -ACTIVE- | -STDOUT- | -STDERR- | -STACK- | -FUNCS- | -PROCS- | -PROGS- |
    +----------+----------+----------+---------+---------+---------+---------+
    | 0        |          |          |         | 0       | 0       | 0       |
    +----------+----------+----------+---------+---------+---------+---------+
    1 row in set (0.00 sec)
    
    Query OK, 0 rows affected (0.00 sec)
    

    Теперь создадим JavaScript-сохранённую процедуру pc1(), которая использует console.log() и console.error() в коротком цикле, чтобы многократно записывать в stdout и в stderr, вот так:

    mysql> CREATE PROCEDURE pc1()
        -> LANGUAGE JAVASCRIPT AS
        -> $$
        $>   let x = 0
        $>
        $>   do  {
        $>     console.log(`This is message #${++x} to stdout.`)
        $>     console.error(`This is message #${x} to stderr.`)
        $>   }
        $>   while(x < 3)
        $> $$
        -> ;
    Query OK, 0 rows affected (0.02 sec)
    

    После выполнения оператора CREATE PROCEDURE, только что показанного, mle_states() показывает активный сеанс MLE. Сохранённые программы ещё не были запущены, поэтому они не были кэшированы; это означает, что столбцы, отражающие JavaScript-сохранённые функции, процедуры и программы, все показывают 0. Вывод показан здесь:

    mysql> CALL mle_states;
    +----------+----------+----------+---------+---------+---------+---------+
    | -ACTIVE- | -STDOUT- | -STDERR- | -STACK- | -FUNCS- | -PROCS- | -PROGS- |
    +----------+----------+----------+---------+---------+---------+---------+
    | 1        |          |          |         | 0       | 0       | 0       |
    +----------+----------+----------+---------+---------+---------+---------+
    1 row in set (0.00 sec)
    
    Query OK, 0 rows affected (0.00 sec)
    
    Примечание

    Использование кавычек с символами обратной косой черты (`) позволяет нам использовать интерполяцию переменных в выводе. Если вы не знакомы с этим механизмом цитирования, см. Template Literals на Mozilla Developer для получения дополнительной информации.

    Вызов pc1(), за которым следует mle_states(), даёт результат, показанный здесь:

    mysql> CALL pc1();
    Query OK, 0 rows affected (0.00 sec)
    
    mysql> CALL mle_states()\G
    *************************** 1. row ***************************
    -ACTIVE-: 1
    -STDOUT-: This is message #1 to stdout.
    This is message #2 to stdout.
    This is message #3 to stdout.
    
    -STDERR-: This is message #1 to stderr.
    This is message #2 to stderr.
    This is message #3 to stderr.
    
     -STACK-:
     -FUNCS-: 0
     -PROCS-: 1
     -PROGS-: 1
    1 row in set (0.00 sec)
    
    Query OK, 0 rows affected (0.00 sec)
    

    Выполнение сохранённой процедуры запускает сеанс MLE, поэтому is_active (-ACTIVE-) теперь 1.

    Последовательные записи в stdout или stderr в рамках одного сеанса добавляются к любому существующему содержимому. Чтобы увидеть это, вызовите pc1() ещё раз, затем проверьте вывод из mle_states(), как показано здесь:

    mysql> CALL pc1();
    Query OK, 0 rows affected (0.00 sec)
    
    mysql> CALL mle_states()\G
    *************************** 1. row ***************************
    -ACTIVE-: 1
    -STDOUT-: This is message #1 to stdout.
    This is message #2 to stdout.
    This is message #3 to stdout.
    This is message #1 to stdout.
    This is message #2 to stdout.
    This is message #3 to stdout.
    
    -STDERR-: This is message #1 to stderr.
    This is message #2 to stderr.
    This is message #3 to stderr.
    This is message #1 to stderr.
    This is message #2 to stderr.
    This is message #3 to stderr.
    
     -STACK-:
     -FUNCS-: 0
     -PROCS-: 1
     -PROGS-: 1
    1 row in set (0.00 sec)
    
    Query OK, 0 rows affected (0.00 sec)
    

    Поскольку ошибок при выполнении pc1() не возникло, трассировка стека остаётся пустой. Чтобы проверить трассировку стека, можно создать изменённую копию pc1(), в которой мы изменим ссылку на console.log() на неопределённую функцию console.lob(), как показано здесь:

    mysql> CREATE PROCEDURE pc2()
        -> LANGUAGE JAVASCRIPT AS
        -> $$
        $>   let x = 0
        $>   do  {
        $>     console.lob(`This is message #${++x} to stdout.`)
        $>     console.error(`This is message #${x} to stderr.`)
        $>   }
        $>   while(x < 3)
        $> $$
        -> ;
    Query OK, 0 rows affected (0.02 sec)
    
    CREATE PROCEDURE pc2()
    LANGUAGE JAVASCRIPT AS
      $$
       let x = 0
       do  {
         console.lob(`This is message #${++x} to stdout.`)
         console.error(`This is message #${x} to stderr.`)
       }
       while(x < 3)
      $$
    ;
    
    mysql> CREATE PROCEDURE pc2()
        -> LANGUAGE JAVASCRIPT AS
        -> $$
        $>   let x = 0
        $>   do  {
        $>     console.lob(`This is message #${++x} to stdout.`)
        $>     console.error(`This is message #${x} to stderr.`)
        $>   }
        $>   while(x < 3)
        $> $$
        -> ;
    Query OK, 0 rows affected (0.02 sec)
    

    Оператор CREATE PROCEDURE выполняется успешно, но при попытке вызова pc2() возникает ошибка, как показано здесь:

    mysql> CALL pc2();
    ERROR 6113 (HY000): JavaScript> TypeError: (intermediate value).lob is not a function
    

    После этого, при повторном вызове mle_states(), мы видим, что, поскольку мы находимся в том же сеансе, поля stdout и stderr всё ещё содержат содержимое, записанное в них ранее. Трассировка стека из только что показанной ошибки отображается в последнем столбце вывода:

    mysql> CALL mle_states()\G
    *************************** 1. row ***************************
    -ACTIVE-: 1
    -STDOUT-: This is message #1 to stdout.
    This is message #2 to stdout.
    This is message #3 to stdout.
    This is message #1 to stdout.
    This is message #2 to stdout.
    This is message #3 to stdout.
    
    -STDERR-: This is message #1 to stderr.
    This is message #2 to stderr.
    This is message #3 to stderr.
    This is message #1 to stderr.
    This is message #2 to stderr.
    This is message #3 to stderr.
    
    -STACK-: <js> pc2:3:6-54
    
    -FUNCS-: 0
    -PROCS-: 2
    -PROGS-: 2
    1 row in set (0.00 sec)
    
    Query OK, 0 rows affected (0.00 sec)
    

    Кроме того, значения ключей stored_functions, stored_procedures и stored_programs для mle_session_state() равны 0, 2 и 2 соответственно—мы создали 2 сохранённые JavaScript-процедуры и 0 JavaScript-сохранённых функций, в общей сложности 2 JavaScript-сохранённые программы.

    Трассировка стека не сохраняется между вызовами JavaScript-сохранённой программы.

    Чтобы очистить всю информацию из всех полей в выводе из mle_states(), вызовите mle_session_reset(), например:

    mysql> SELECT mle_session_reset();
    mysql> SELECT mle_session_reset();
    +------------------------------------------+
    | mle_session_reset()                      |
    +------------------------------------------+
    | The session state is successfully reset. |
    +------------------------------------------+
    1 row in set (0.00 sec)
    

    Повторный вызов mle_states() даёт тот же результат, что и первоначальный результат, прежде чем какие-либо сохранённые JavaScript-программы были использованы.

    mysql> CALL mle_states;
    +----------+----------+----------+---------+---------+---------+---------+
    | -ACTIVE- | -STDOUT- | -STDERR- | -STACK- | -FUNCS- | -PROCS- | -PROGS- |
    +----------+----------+----------+---------+---------+---------+---------+
    | 0        |          |          |         | 0       | 0       | 0       |
    +----------+----------+----------+---------+---------+---------+---------+
    1 row in set (0.00 sec)
    
    Query OK, 0 rows affected (0.00 sec)
    

    В качестве альтернативы вы можете очистить stdout и stderr изнутри JavaScript-процедуры, используя console.clear().

  • mle_set_session_state()

    Компонент MLE предоставляет эту функцию для определения правил, действующих в текущем сеансе для преобразования целочисленных типов MySQL (TINYINT, SMALLINT, MEDIUMINT, INT, BIGINT) в значения JavaScript. Эти правила применяются к входным аргументам JavaScript-программ, а также к значениям в наборах результатов. Возможные правила преобразования перечислены здесь по имени:

    • BIGINT: Всегда преобразовывать в JavaScript BigInt.

    • STRING: Всегда преобразовывать в JavaScript String.

    • UNSAFE_BIGINT: Если значение безопасно, преобразовать в JavaScript Number; в противном случае преобразовать в JavaScript BigInt.

    • UNSAFE_STRING: Если значение безопасно, преобразовать в JavaScript Number; в противном случае преобразовать в JavaScript String. Это поведение по умолчанию, если правило не указано.

    В контексте этих правил преобразования “безопасный” означает, что преобразуемое значение находится в диапазоне от -(253-1) (-9007199254740991) до (253-1) (9007199254740991) включительно.

    Этот функцию можно вызывать только если в текущем сеансе пользователя нет кэшированных сохранённых программ. При успешном выполнении функция возвращает 1. В противном случае попытка вызова её вызывает ошибку, как показано здесь:

    mysql> SELECT gcd(536, 1676); // Call JS stored function
    +----------------+
    | gcd(536, 1676) |
    +----------------+
    |              4 |
    +----------------+
    1 row in set (0.00 sec)
    
    mysql> SELECT mle_set_session_state('{"integer_type":"BIGINT"}');
    ERROR 1123 (HY000): Can't initialize function 'mle_set_session_state'; Cannot
    set options of an active session. Please reset the session first.
    

    Как предполагает сообщение об ошибке, вам нужно сбросить сеанс, чтобы очистить активный сеанс. Для этого используйте mle_session_reset(), как показано здесь:

    mysql> SELECT mle_session_reset();
    +------------------------------------------+
    | mle_session_reset()                      |
    +------------------------------------------+
    | The session state is successfully reset. |
    +------------------------------------------+
    1 row in set (0.00 sec)
    

    Теперь вы можете вызвать mle_set_session_state(), как показано здесь:

    mysql> SELECT mle_set_session_state('{"integer_type":"BIGINT"}');
    +----------------------------------------------------+
    | mle_set_session_state('{"integer_type":"BIGINT"}') |
    +----------------------------------------------------+
    |                                                  1 |
    +----------------------------------------------------+
    1 row in set (0.00 sec)
    

    Вы можете установить тип преобразования для определённого запроса перед его выполнением, используя методы JavaScript API Session, такие как sql(), runSql() и prepare(). См. описание Session.sql() для получения дополнительной информации и примеров.

Информацию об использовании ресурсов компонентом MLE можно получить, обратившись к таблицам Performance Schema memory_summary_by_thread_by_event_name и memory_summary_global_by_event_name с помощью ключа memory/language_component/session, который отслеживает использование памяти каждой сессией пользователя MLE. Этот ключ предоставляется компонентом MLE; он включён в таблицу setup_instruments при установке компонента MLE, как показано здесь:

mysql> SELECT * FROM performance_schema.setup_instruments
     > WHERE NAME LIKE '%language_component%'\G
*************************** 1. row ***************************
         NAME: memory/language_component/session
      ENABLED: YES
        TIMED: NULL
   PROPERTIES: controlled_by_default
        FLAGS: controlled
   VOLATILITY: 0
DOCUMENTATION: Session-specific allocations for the Language component
1 row in set (0.00 sec)

До создания, выполнения или запуска любых хранимых программ JavaScript, запросов, MLE остаётся неактивным, поэтому использование этого ключа возвращает пустые результаты или результаты, состоящие в основном из нулей, как показано здесь:

mysql> SELECT * FROM performance_schema.memory_summary_by_thread_by_event_name
    -> WHERE
    ->   EVENT_NAME = 'memory/language_component/session'
    ->     AND
    ->   COUNT_ALLOC < 0\G
Empty set (0.02 sec)

mysql> SELECT * FROM performance_schema.memory_summary_global_by_event_name
    -> WHERE EVENT_NAME LIKE 'memory/language_component/%'\G
*************************** 1. row ***************************
                  EVENT_NAME: memory/language_component/session
                 COUNT_ALLOC: 0
                  COUNT_FREE: 0
   SUM_NUMBER_OF_BYTES_ALLOC: 0
    SUM_NUMBER_OF_BYTES_FREE: 0
              LOW_COUNT_USED: 0
          CURRENT_COUNT_USED: 0
             HIGH_COUNT_USED: 0
    LOW_NUMBER_OF_BYTES_USED: 0
CURRENT_NUMBER_OF_BYTES_USED: 0
   HIGH_NUMBER_OF_BYTES_USED: 0
1 row in set (0.01 sec)

После вызова хранимой функции JavaScript те же запросы теперь отражают потребляемую память MLE, как показано здесь:

mysql> SELECT * FROM performance_schema.memory_summary_by_thread_by_event_name
    -> WHERE
    ->   EVENT_NAME = 'memory/language_component/session'
    ->     AND
    ->   COUNT_ALLOC < 0\G
*************************** 1. row ***************************
                   THREAD_ID: 46
                  EVENT_NAME: memory/language_component/session
                 COUNT_ALLOC: 25
                  COUNT_FREE: 20
   SUM_NUMBER_OF_BYTES_ALLOC: 4445
    SUM_NUMBER_OF_BYTES_FREE: 2989
              LOW_COUNT_USED: 0
          CURRENT_COUNT_USED: 5
             HIGH_COUNT_USED: 14
    LOW_NUMBER_OF_BYTES_USED: 0
CURRENT_NUMBER_OF_BYTES_USED: 1456
   HIGH_NUMBER_OF_BYTES_USED: 3239
1 row in set (0.00 sec)

mysql> SELECT * FROM performance_schema.memory_summary_global_by_event_name
    -> WHERE EVENT_NAME LIKE 'memory/language_component/%'\G
*************************** 1. row ***************************
                  EVENT_NAME: memory/language_component/session
                 COUNT_ALLOC: 25
                  COUNT_FREE: 20
   SUM_NUMBER_OF_BYTES_ALLOC: 4445
    SUM_NUMBER_OF_BYTES_FREE: 2989
              LOW_COUNT_USED: 0
          CURRENT_COUNT_USED: 5
             HIGH_COUNT_USED: 14
    LOW_NUMBER_OF_BYTES_USED: 0
CURRENT_NUMBER_OF_BYTES_USED: 1456
   HIGH_NUMBER_OF_BYTES_USED: 3239
1 row in set (0.00 sec)

Дополнительную информацию об этих и связанных с ними таблицах Performance Schema см. в разделе 29.12.20.10 «Таблицы сводного анализа памяти».

Использование памяти компонентом MLE в данной сессии пользователя ограничено пределом, заданным системной переменной сервера connection_memory_limit. Дополнительную информацию см. в описании этой переменной.

© 2025 Oracle
Licensed under the GPLv2 License.
https://docs.oracle.com/cd/E17952_01/mysql-9.2-en/srjs-session-info.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API