有关 MySQL 中存储例程的一般信息,请参见 第 27.2 节,“使用存储例程”.
MLE 组件提供了一些可加载函数,用于处理 MLE 用户会话。这些函数在下面列出并进行了描述。
调用此函数将清理当前 MLE 会话状态,删除来自
mle_session_state()
的任何可观察输出。它还会重置会话时区,以便后续调用 JavaScript 存储例程使用最近在会话中设置的时区。使用此可加载函数来获取有关最近执行的 MLE 存储程序的会话信息。
mle_session_state()
接受一个参数,会话状态键(字符串),并显示会话状态值。会话状态值的大小限制为最大 64K(相当于 16000 个 4 字节字符)。这是一个循环缓冲区;当可用空间已用完时,新条目将覆盖最旧的条目。下面列出了可能的会话状态键及其描述。is_active
:如果当前 MySQL 用户会话是 MLE 会话,则返回1
,否则返回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)
注意用反引号 (
`
) 字符引用字符串允许我们在输出中使用变量插值。如果您不熟悉这种引用机制,请参见 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)
此外,
mle_session_state()
的stored_functions
、stored_procedures
和stored_programs
键的值分别为0
、2
和2
——我们创建了 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 例程中清除stdout
和stderr
。MLE 组件提供此函数作为一种方法,用于确定当前会话中用于将 MySQL 整数类型 (
TINYINT
、SMALLINT
、MEDIUMINT
、INT
、BIGINT
) 转换为 JavaScript 值的规则。这些规则适用于 JavaScript 程序的输入参数以及结果集中的值。下面按名称列出了可能的转换规则。BIGINT
:始终转换为 JavaScriptBigInt
。STRING
:始终转换为 JavaScriptString
。UNSAFE_BIGINT
:如果该值是安全的,则转换为 JavaScriptNumber
;否则转换为 JavaScriptBigInt
。UNSAFE_STRING
:如果该值是安全的,则转换为 JavaScriptNumber
;否则转换为 JavaScriptString
。如果未指定任何规则,则这是默认行为。
在这些转换规则的上下文中,“安全” 表示要转换的值在
-(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()
的描述。
您可以通过查询 Performance Schema memory_summary_by_thread_by_event_name
和 memory_summary_global_by_event_name
表来获取有关 MLE 组件资源使用情况的信息,使用键 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
服务器系统变量施加的限制。有关更多信息,请参阅此变量的描述。