文件首頁
MySQL 9.0 參考手冊
相關文件 下載本手冊
PDF (美式信紙) - 40.0Mb
PDF (A4) - 40.1Mb
Man Pages (TGZ) - 258.2Kb
Man Pages (Zip) - 365.3Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb


MySQL 9.0 參考手冊  /  ...  /  JavaScript 儲存程式 — 會話資訊和選項

27.3.5 JavaScript 儲存程式 — 會話資訊和選項

如需 MySQL 中儲存常式的一般資訊,請參閱第 27.2 節「使用儲存常式」

MLE 元件提供多個可載入的函數,用於處理 MLE 使用者會話。這些函數在此列出並說明

  • mle_session_reset()

    呼叫此函數會清除目前的 MLE 會話狀態,從 mle_session_state() 中移除任何可觀察到的輸出。它也會重設會話時區,以便後續對 JavaScript 儲存常式的呼叫使用會話中最近設定的時區。

  • mle_session_state()

    使用此可載入的函數來取得最近執行的 MLE 儲存程式的會話資訊。mle_session_state() 接受一個引數,即會話狀態鍵 (字串),並顯示會話狀態值。會話狀態值的最大大小限制為 64K (相當於 16000 個 4 位元組字元)。這是一個循環緩衝區;當可用空間用完時,新條目會覆寫最舊的條目。此處列出可能的會話狀態鍵及其描述

    • is_active:如果目前的 MySQL 使用者會話是 MLE 會話,則傳回 1,否則傳回 0

    • stdout:輸出儲存程式使用 console.log() 寫入的任何內容。

    • stderr:輸出儲存程式使用 console.error() 寫入的任何內容。

    • stack_trace:如果 MLE 儲存程式的執行不成功,則此項會包含堆疊追蹤,這可能有助於找出錯誤的來源。

      不成功的 CREATE FUNCTIONCREATE 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() 多次寫入 stdoutstderr,如下所示

    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)
    注意

    使用反引號 (`) 字元括住字串,可讓我們在輸出中使用變數插值。如果您不熟悉此引用機制,請參閱 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

    在同一會話中,連續寫入 stdoutstderr 會附加到任何現有的內容。若要查看此內容,請再次呼叫 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() 時,我們會看到,由於我們在同一個會話中,stdoutstderr 欄位仍然包含先前寫入它們的內容。剛剛顯示的錯誤堆疊追蹤顯示在輸出的最後一欄

    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)

    此外,mle_session_state()stored_functionsstored_proceduresstored_programs 鍵的值分別為 022 — 我們建立了 2 個儲存的 JavaScript 程序,沒有儲存的 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)

    或者,您可以使用 console.clear() 從 JavaScript 常式內清除 stdoutstderr

  • mle_set_session_state()

    MLE 元件提供此函數作為一種方法,用於判斷目前會話中將 MySQL 整數類型 (TINYINTSMALLINTMEDIUMINTINTBIGINT) 轉換為 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() 的說明。

您可以透過查詢效能結構描述 memory_summary_by_thread_by_event_namememory_summary_global_by_event_name 表格,使用鍵 memory/language_component/session,取得 MLE 元件的資源使用資訊,此鍵追蹤每個 MLE 使用者會期的記憶體使用量。此鍵由 MLE 元件提供;它包含在安裝 MLE 元件時的 setup_instruments 表格中,如下所示

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)

有關這些和相關效能結構描述表格的更多資訊,請參閱 第 29.12.20.10 節「記憶體摘要表格」

在給定使用者會期中,MLE 元件的記憶體使用量受 connection_memory_limit 伺服器系統變數所設定的限制約束。有關更多資訊,請參閱此變數的說明。