暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

5.7 | MySQL 9.0 支持 JavaScript 存储程序

原创 严少安 2025-05-12
222

MySQL 9.0 支持 JavaScript 存储程序

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

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

准备 MySQL 9 环境

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

  1. 从 Oracle Container Registry(OCR) 拉取 MySQL 企业版 9.2 的镜像。
[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 企业版容器:
docker run --name=mysql9 \
--restart on-failure \
-e MYSQL_ROOT_PASSWORD=root \
-d container-registry.oracle.com/mysql/enterprise-server:9.2
  1. 连接到数据库,并查看版本。
[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 组件:
mysql> INSTALL COMPONENT 'file://component_mle';
Query OK, 0 rows affected (0.24 sec)
  1. 查看组件状态:
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 存储函数。

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,但你可以这样修改它:

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

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

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)

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

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)

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

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 存储例程时使用会话中最新设置的时区。

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() 接受一个参数,即会话状态键(字符串),并显示会话状态值。

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 程序的输入参数以及结果集中的值。

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 消耗的内存。

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 / –

👉 这里可以找到我

👉 这里有得聊

如果对国产基础软件(操作系统、数据库、中间件)感兴趣,可以加群一起聊聊。
关注微信公众号:少安事务所,后台回复[群],即可看到入口。

如果这篇文章为你带来了灵感或启发,请帮忙『三连』吧,感谢!ღ( ´・ᴗ・` )~

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

文章被以下合辑收录

评论