Fight the Future

Java言語とJVM、そしてJavaエコシステム全般にまつわること

詳説GraalVM(4) GraalVMが組み込まれたデータベース

こちらのツイートが話題になっていました。

GraalVMは組み込みが可能です。MySQL MLE PluginでMySQLにGraalVMを組み込み、JavaScript/node.jsを(将来的にはその他言語も)データベース上で実行できるようになります。

MySQL MLE Pluginはまだリリースされていないのですが、実はOracle Database Multilingual Engine (MLE) ではすでにその機能が提供されているので、試せます。

公式サイトにも手順が載っています。

http://www.graalvm.org/docs/examples/mle-oracle/

こちらのセッション録画でも紹介されています(43:30以降)。

youtu.be

Oracle Multilingual Engine (MLE) のdockerイメージ

Oracle MLEはdockerイメージが提供されています。そのため、まずはdockerをセットアップしてください。

前提

  • dockerをセットアップしていること

手順

こちらから、mle-docker-x.x.x.tar.gz をダウンロードしてください。現時点では0.2.7、サイズは8.3 GB!あります。

Oracle Database MLE Download

dockerイメージをロードします。

$ docker load --input mle-docker-0.2.7.tar.gz                                                                                                                                    
5f70bf18a086: Loading layer [==================================================>]  1.024kB/1.024kB                                                                                                      
b94907830dcf: Loading layer [==================================================>]  120.8MB/120.8MB                                                                                                      
1e4d41b493d4: Loading layer [==================================================>]  2.688GB/2.688GB                                                                                                      
aaf5200dd6bd: Loading layer [==================================================>]  30.72kB/30.72kB                                                                                                      
ceb829e4f454: Loading layer [==================================================>]  2.922GB/2.922GB                                                                                                      
fea2f9016c05: Loading layer [==================================================>]  5.538GB/5.538GB                                                                                                      
32dbe8a24ae4: Loading layer [==================================================>]  4.732MB/4.732MB                                                                                                      
c82b093d14a8: Loading layer [==================================================>]  72.92MB/72.92MB                                                                                                      
65440ff3f3b3: Loading layer [==================================================>]  440.8kB/440.8kB                                                                                                      
7bc5844c9cf9: Loading layer [==================================================>]  251.1MB/251.1MB                                                                                                      
a69d8da1ba68: Loading layer [==================================================>]  285.7kB/285.7kB                                                                                                      
e5c884dbf006: Loading layer [==================================================>]  285.7kB/285.7kB                                                                                                      
9afbeb1802b3: Loading layer [==================================================>]  564.5MB/564.5MB                                                                                                      
30e8d7f3c37e: Loading layer [==================================================>]   29.7kB/29.7kB                                                                                                       
6f8729968733: Loading layer [==================================================>]  394.8kB/394.8kB                                                                                                      
4d03774a005c: Loading layer [==================================================>]  39.92MB/39.92MB                                                                                                      
9fd0c123d07f: Loading layer [==================================================>]   2.56kB/2.56kB                                                                                                       
bc9dd8e1e968: Loading layer [==================================================>]  92.71MB/92.71MB                                                                                                      
def1dcc779f0: Loading layer [==================================================>]  341.2MB/341.2MB                                                                                                      
406ff899b75c: Loading layer [==================================================>]  433.9MB/433.9MB                                                                                                      
Loaded image: mle-docker-0.2.7:latest

実行します。

$ docker run mle-docker-0.2.7                                                                                                                                                    
ORACLE PASSWORD FOR SYS, SYSTEM AND PDBADMIN: NSIpvEWTsRg=1                                                                                                                                             
                                                                                                                                                                                                        
LSNRCTL for Linux: Version 12.1.0.2.0 - Production on 10-AUG-2018 05:10:46                                                                                                                              
                                                                                                                                                                                                        
Copyright (c) 1991, 2014, Oracle.  All rights reserved.                                                                                                                                                 
                                                                                                                                                                                                        
Starting /opt/oracle/product/12.1.0.2/dbhome_1/bin/tnslsnr: please wait...                                                                                                                              
                                                                                                                                                                                                        
TNSLSNR for Linux: Version 12.1.0.2.0 - Production                                                                                                                                                      
System parameter file is /opt/oracle/product/12.1.0.2/dbhome_1/network/admin/listener.ora                                                                                                               
Log messages written to /opt/oracle/diag/tnslsnr/e7686bae3d72/listener/alert/log.xml                                                                                                                    
Listening on: (DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=EXTPROC1)))                                                                                                                                      
Listening on: (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=0.0.0.0)(PORT=1521)))                                                                                                                           
                                                                                                                                                                                                        
Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=IPC)(KEY=EXTPROC1)))                                                                                                                                      
STATUS of the LISTENER                                                                                                                                                                                  
------------------------                                                                                                                                                                                
Alias                     LISTENER                                                                                                                                                                      
Version                   TNSLSNR for Linux: Version 12.1.0.2.0 - Production                                                                                                                            
Start Date                10-AUG-2018 05:10:46                                                                                                                                                          
Uptime                    0 days 0 hr. 0 min. 0 sec                                                                                                                                                     
Trace Level               off                                                                                                                                                                           
Security                  ON: Local OS Authentication
SNMP                      OFF
Listener Parameter File   /opt/oracle/product/12.1.0.2/dbhome_1/network/admin/listener.ora
Listener Log File         /opt/oracle/diag/tnslsnr/e7686bae3d72/listener/alert/log.xml
Listening Endpoints Summary...
  (DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=EXTPROC1)))
  (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=0.0.0.0)(PORT=1521)))
The listener supports no services
The command completed successfully
Copying database files
...
pga_aggregate_limit is 2048 MB
limit based on physical memory and SGA usage is 1199 MB

さて、ここからはdockerコンテナのシェルに入ります。

$ docker ps                                                                                                                                                                          
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                NAMES                                                                     
e7686bae3d72        mle-docker-0.2.7    "/bin/sh -c 'exec $O…"   6 minutes ago       Up 6 minutes        1521/tcp, 5500/tcp   serene_saha

$ docker exec -ti e7686bae3d72 bash -li

MLEはORCLCDBというサービスで起動しており、scott/tigerで接続できます。

[oracle@e7686bae3d72 ~]$ sqlplus scott/tiger@localhost:1521/ORCLCDB

SQL*Plus: Release 12.1.0.2.0 Production on Fri Aug 10 05:21:22 2018

Copyright (c) 1982, 2014, Oracle.  All rights reserved.


Connected to:
Oracle Database 12c Enterprise Edition Release 12.1.0.2.0_MLE - 64bit Beta
With the Partitioning, OLAP, Advanced Analytics and Real Application Testing options

このOracle MLEはすでにGraalVMが組み込まれており、データベース上でJavaSciptの関数を実行することができます。

公式サイトと同じように、validatorモジュールを使います。TypeScriptも使えますので、validatorモジュール用のTypeScriptの型定義もインストールします。

[oracle@e7686bae3d72 ~]$ mkdir validator
[oracle@e7686bae3d72 ~]$ cd validator/
[oracle@e7686bae3d72 validator]$ echo "{}" > package.json
[oracle@e7686bae3d72 validator]$ npm install validator
/home/oracle/validator
`-- validator@10.5.0

npm WARN validator No description
npm WARN validator No repository field.
npm WARN validator No license field.
[oracle@e7686bae3d72 validator]$ npm install @types/validator
/home/oracle/validator
`-- @types/validator@9.4.1

npm WARN validator No description
npm WARN validator No repository field.
npm WARN validator No license field.

dbjsコマンドでモジュールをデータベースにデプロイできます。

$ dbjs deploy -u scott -p tiger -c localhost:1521/ORCLCDB validator                                                                                                      
+ validator.js
├─┬ equals
│ └── SCALAR FUNCTION VALIDATOR.EQUALS("p0" IN VARCHAR2, "p1" IN VARCHAR2) RETURN NUMBER
...
├─┬ isEmail
│ └── SCALAR FUNCTION VALIDATOR.ISEMAIL("p0" IN VARCHAR2) RETURN NUMBER
...
└─┬ whitelist
  └── SCALAR FUNCTION VALIDATOR.WHITELIST("p0" IN VARCHAR2, "p1" IN VARCHAR2) RETURN VARCHAR2

validatorが提供する関数がずらっとデータベースに配備されます。SQL文の中でvalidator.isEmail関数を使ってみましょう。

$ sqlplus scott/tiger@localhost:1521/ORCLCDB                                                                                                                            

SQL> select validator.isEmail('alice@example.com') from dual;

VALIDATOR.ISEMAIL('ALICE@EXAMPLE.COM')
--------------------------------------
                                     1

SQL> select validator.isEmail('bob@example') from dual;

VALIDATOR.ISEMAIL('BOB@EXAMPLE')
--------------------------------
                               0

emailとして正しければ1、正しくなければ0が返ってきました。

dbjsコマンド

dbjsはユーティリティで、"Its goal is to make it easy for JavaScript developers to deploy JavaScript (or TypeScript) modules into the database"、つまりJavaScriptやTypeScriptモジュールをデータベースにデプロイするためのツールです。

Deployment (dbjs) - Oracle Database MLE 0.2.7

自作関数をデプロイする

helloworld.tsにhelloworld関数を作成し、それをOracle MLEにデプロイして使ってみましょう。

export function helloworld() : string {
  return 'HelloWorld';
}
[oracle@e7686bae3d72 ~]$ echo "export function helloworld() : string { return 'HelloWorld'; }" > helloworld.ts
[oracle@e7686bae3d72 ~]$ dbjs deploy -u scott -p tiger -c localhost:1521/ORCLCDB helloworld.ts
+ helloworld.js
└─┬ helloworld
  └── SCALAR FUNCTION HELLOWORLD.HELLOWORLD RETURN VARCHAR2
[oracle@e7686bae3d72 ~]$ sqlplus scott/tiger@localhost:1521/ORCLCDB

SQL> select helloworld() from dual;

HELLOWORLD()
--------------------------------------------------------------------------------
HelloWorld

helloworld()関数を呼び出して、文字列HelloWorldが返ってきました。

まとめ

今回はOracle MLEで組み込みGraalVMを使い、JavaSciptの関数を実行しました。MySQL MLE Pluginでも同様の手順でJavaScriptを(そしてその他言語も)組み込みGraalVMを使って実行できるようになると思います。

利用バージョン

  • docker Version 18.06.0-ce-mac70 (26399)
  • Oracle MLE 0.2.7