MySQL 9.0 支持 JavaScript 存储程序

MySQL 9.0 支持 JavaScript 存储程序

ShawnYan Lv.6

MySQL 9.0 企业版和 MySQL HeatWave 推出了一项令人振奋的创新特性:支持使用 JavaScript 编写存储过程和函数。

这标志着开发者可以凭借对 JavaScript 的熟悉度,以及丰富的 JavaScript 生态资源,更加高效地编写 MySQL 存储过程。不仅极大地提升了开发者的生产力,还大幅降低了存储过程编写的门槛,使得广大开发者能够投身其中。此外,这种设计巧妙地减少了数据库服务器与应用程序之间的数据传输量,优化了整体性能。

准备 MySQL 9 环境

为了深入浅出地展示 JavaScript 存储程序的强大功能,我们将利用 MySQL 企业版 9.2 的 Docker 容器进行环境搭建。

  1. 从 Oracle Container Registry(OCR) 拉取 MySQL 企业版 9.2 的镜像。
1
2
3
4
5
6
7
8
9
10
11
12
13
[root@el7 ~]# docker pull container-registry.oracle.com/mysql/enterprise-server:9.2
9.2: Pulling from mysql/enterprise-server
08b26210552c: Pull complete
c743ba8e0994: Pull complete
6ed95c0f26d2: Pull complete
cae75ca37528: Pull complete
2b352847173b: Pull complete
16a46733c092: Pull complete
b6e314a3018d: Pull complete
Digest: sha256:5225178395d4920f4675472c4207d10e127690d5704df2103d03bfaea5af992d
Status: Downloaded newer image for container-registry.oracle.com/mysql/enterprise-server:9.2
container-registry.oracle.com/mysql/enterprise-server:9.2
[root@el7 ~]#
  1. 使用以下命令运行 MySQL 企业版容器:
1
2
3
4
docker run --name=mysql9 \
--restart on-failure \
-e MYSQL_ROOT_PASSWORD=root \
-d container-registry.oracle.com/mysql/enterprise-server:9.2
  1. 连接到数据库,并查看版本。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
[root@el7 ~]# docker exec -it mysql9 mysql -uroot -proot
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 9
Server version: 9.2.0-commercial MySQL Enterprise Server - Commercial

Copyright (c) 2000, 2025, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> select version();
+------------------+
| version() |
+------------------+
| 9.2.0-commercial |
+------------------+
1 row in set (0.00 sec)

至此,我们已经成功搭建了 MySQL 9 的运行环境。

安装 MLE 组件

MySQL 的多语言引擎(MLE)组件是实现 JavaScript 存储程序的关键所在。MLE 组件赋予存储过程和函数支持 SQL 之外语言的能力,是 MySQL 企业版的专属特性。

使用 MySQL 9.2 中的 MLE 组件,您可以创建和执行用 JavaScript(ECMAScript) 编写的 MySQL 存储程序。

  1. 安装 MLE 组件:
1
2
mysql> INSTALL COMPONENT 'file://component_mle';
Query OK, 0 rows affected (0.24 sec)
  1. 查看组件状态:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
mysql> SHOW STATUS LIKE 'mle%';
+------------------------------+---------------+
| Variable_name | Value |
+------------------------------+---------------+
| mle_heap_status | Not Allocated |
| mle_languages_supported | JavaScript |
| mle_memory_used | 0 |
| mle_oom_errors | 0 |
| mle_session_resets | 0 |
| mle_sessions | 0 |
| mle_sessions_max | 0 |
| mle_status | Inactive |
| mle_stored_functions | 0 |
| mle_stored_procedures | 0 |
| mle_stored_program_bytes_max | 0 |
| mle_stored_program_sql_max | 0 |
| mle_stored_programs | 0 |
| mle_threads | 0 |
| mle_threads_max | 1 |
+------------------------------+---------------+
15 rows in set (0.00 sec)

用 JavaScript 编写的存储程序

现在,我们开始编写一个简单的 JavaScript 存储函数。

1
2
3
4
5
6
7
mysql> CREATE FUNCTION add_nos(arg1 INT, arg2 INT)
-> RETURNS INT LANGUAGE JAVASCRIPT AS
-> $$
$> return arg1 + arg2
$> $$
-> ;
ERROR 1418 (HY000): This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its declaration and binary logging is enabled (you *might* want to use the less safe log_bin_trust_function_creators variable)

但可能会遇到上面的报错。要放宽上述函数创建的条件(用户必须拥有超级特权,并且函数必须声明为确定性的,或者不修改数据),可以将全局的log_bin_trust_function_creators系统变量设置为1。默认情况下,这个变量的值为0,但你可以这样修改它:

1
2
mysql> set global log_bin_trust_function_creators = on;
Query OK, 0 rows affected, 1 warning (0.00 sec)

再次执行创建语句,成功。

1
2
3
4
5
6
7
mysql> CREATE FUNCTION add_nos(arg1 INT, arg2 INT)
-> RETURNS INT LANGUAGE JAVASCRIPT AS
-> $$
$> return arg1 + arg2
$> $$
-> ;
Query OK, 0 rows affected (0.01 sec)

通过以下命令查看存储函数的创建语句。

1
2
3
4
5
6
7
8
9
10
11
12
13
mysql> show create function add_nos\G
*************************** 1. row ***************************
Function: add_nos
sql_mode: ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION
Create Function: CREATE DEFINER=`root`@`localhost` FUNCTION `add_nos`(arg1 INT, arg2 INT) RETURNS int
LANGUAGE JAVASCRIPT
AS $$
return arg1 + arg2
$$
character_set_client: utf8mb4
collation_connection: utf8mb4_0900_ai_ci
Database Collation: utf8mb4_0900_ai_ci
1 row in set (0.00 sec)

执行该存储函数,验证其功能。

1
2
3
4
5
6
7
mysql> SELECT add_nos(20,25);
+----------------+
| add_nos(20,25) |
+----------------+
| 45 |
+----------------+
1 row in set (0.03 sec)

MLE 组件提供的会话信息方法

MLE组件提供了许多用于处理MLE用户会话的可加载函数。下面列出了这些函数。

mle_session_reset()

调用此函数将清理当前 MLE 会话状态,删除 mle_session_state() 中所有可观察的输出。它还会重置会话时区,以便后续调用 JavaScript 存储例程时使用会话中最新设置的时区。

1
2
3
4
5
6
7
mysql> select mle_session_reset();
+------------------------------------------+
| mle_session_reset() |
+------------------------------------------+
| The session state is successfully reset. |
+------------------------------------------+
1 row in set (0.00 sec)

mle_session_state()

使用此可加载函数获取最近执行的 MLE 存储程序的会话信息。mle_session_state() 接受一个参数,即会话状态键(字符串),并显示会话状态值。

1
2
3
4
5
6
7
mysql> SELECT mle_session_state("is_active") AS '-ACTIVE-';
+----------+
| -ACTIVE- |
+----------+
| 0 |
+----------+
1 row in set (0.00 sec)

mle_set_session_state()

此函数用于确定当前会话中将 MySQL 整数类型(TINYINT、SMALLINT、MEDIUMINT、INT、BIGINT)转换为 JavaScript 值的规则。这些规则适用于 JavaScript 程序的输入参数以及结果集中的值。

1
2
3
4
5
6
7
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 存储函数后,可通过如下方法查看 MLE 消耗的内存。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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: 62
COUNT_FREE: 61
SUM_NUMBER_OF_BYTES_ALLOC: 15571
SUM_NUMBER_OF_BYTES_FREE: 15363
LOW_COUNT_USED: 0
CURRENT_COUNT_USED: 1
HIGH_COUNT_USED: 7
LOW_NUMBER_OF_BYTES_USED: 0
CURRENT_NUMBER_OF_BYTES_USED: 208
HIGH_NUMBER_OF_BYTES_USED: 2341
1 row in set (0.01 sec)

总结

MySQL 9.0 企业版和 MySQL HeatWave 对 JavaScript 存储程序的支持,这一特性不仅丰富了 MySQL 的功能集,更为开发者提供了更广阔的应用场景和更高效的开发方式。

Have a nice day ~

– / END / –

  • Title: MySQL 9.0 支持 JavaScript 存储程序
  • Author: ShawnYan
  • Created at: 2025-04-11 23:00:00
  • Updated at: 2025-04-11 23:00:00
  • Link: https://shawnyan.cn/2025/mysql/mysql-ee-javascript-function/
  • License: This work is licensed under CC BY-NC-SA 4.0.
 Comments