聚合UDF执行期间失去与MySQL服务器的连接

问题描述

我用C ++创建了一个MysqL UDF,并将其上传MysqL插件目录中。 我可以在MysqL中安装UDF,但是当我尝试调用它时,MysqL服务器将停止。 我正在使用Visual Studio 2019在Windows 10操作系统上创建共享库(Windows中的.dll)。

我正在MysqL C ++ UDF中从Java调用方法,我正在使用graalVM从C ++函数调用Java方法

我用Java代码创建了一个共享库,然后在C ++代码中使用它们来访问我的Java方法

MysqL UDF代码:DemoAgg.cpp

#ifdef STANDARD

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#ifdef __WIN__
typedef unsigned __int64 ulonglong;
typedef __int64 longlong;
#else
typedef unsigned long long ulonglong;
typedef long long longlong;
#endif /*__WIN__*/
#endif
#include <MysqL.h>
#include <iostream>
#include <ctype.h>
#include <demolibMysqLagg.h>

extern "C" bool test_agg_init(UDF_INIT * initid,UDF_ARGS * args,char* message)
{
    long long* i = new long long; 
    *i = 0;                    
    initid->ptr = (char*)i;

    std::cout << "in init func" << std::endl;

    if (args->arg_count != 1)
    {
        strcpy_s(message,50,"testagg() requires one arguments");
        return 1;
    }

    if (args->arg_type[0] != INT_RESULT)
    {
        strcpy_s(message,"testagg() requires one integer");
        return 1;
    }
    return 0;
}

extern "C" void test_agg_deinit(UDF_INIT * initid)
{
    std::cout << "in deinit func" << std::endl;
    delete (long long*)initid->ptr;
}

extern "C" void test_agg_clear(UDF_INIT* initid,char* is_null,char* error)
{
    std::cout << "in clear func" << std::endl;
    *((long long*)initid->ptr) = 0;
}

extern "C" void test_agg_add(UDF_INIT* initid,UDF_ARGS* args,char* error)
{
    graal_isolate_t* isolate = NULL;
    graal_isolatethread_t* thread = NULL;

    std::cout << "in add func" << std::endl;

    long long int_val;
    int_val = *((long long*)initid->ptr);

    long long int_val2;
    int_val2 = *((long long*)args->args[0]);

    long long sum;
    sum = aggadd(thread,int_val,int_val2);     //my java method which i call from this program
    std::cout << sum;

    *((long long*)initid->ptr) = sum;
}

extern "C" long long test_agg(UDF_INIT* initid,char* error)
{
    std::cout <<"in main func"<<std::endl;
    return *((long long*)initid->ptr);
}

我的模块定义文件:DemoAgg.def

LIBRARY testagg

EXPORTS
         test_agg_init
         test_agg_deinit
         test_agg_clear
         test_agg_add
         test_agg

我的Java代码

package testMysqL;

import org.graalvm.nativeimage.IsolateThread;
import org.graalvm.nativeimage.c.function.CEntryPoint;

public class demo_MysqLagg {

    @CEntryPoint (name = "aggadd")
    public static int aggadd(IsolateThread thread,int x,int y) {
            return x+y;
    }
}

构建C ++项目后,我得到一个dll文件,该文件复制到MysqL插件目录中。

我使用以下查询安装UDF:

create aggregate function test_agg returns integer soname 'testagg.dll';

我使用以下查询呼叫UDF:

select test_agg(c1) from demo_agg;

哪里

demo_agg是只有一列的表。

c1是整数类型的列名称

但是当我执行以上查询时,会弹出以下错误

18:52:53    select test_agg(c1) from demo_agg LIMIT 0,1000 Error Code: 2013. Lost connection to MysqL server during query  0.063 sec

我的错误日志:

2020-09-29T14:41:24.584058Z 0 [Warning] [MY-010915] [Server] 'NO_ZERO_DATE','NO_ZERO_IN_DATE' and 'ERROR_FOR_DIVISION_BY_ZERO' sql modes should be used with strict mode. They will be merged with strict mode in a future release.
2020-09-29T14:41:24.587014Z 0 [System] [MY-010116] [Server] C:\Program Files\MysqL\MysqL Server 8.0\bin\MysqLd.exe (MysqLd 8.0.21) starting as process 48276
2020-09-29T14:41:24.653757Z 1 [System] [MY-013576] [InnoDB] InnoDB initialization has started.
2020-09-29T14:41:28.123852Z 1 [System] [MY-013577] [InnoDB] InnoDB initialization has ended.
2020-09-29T14:41:28.958692Z 0 [System] [MY-011323] [Server] X Plugin ready for connections. Bind-address: '::' port: 33060
2020-09-29T14:41:30.249252Z 0 [Warning] [MY-010068] [Server] CA certificate ca.pem is self signed.
2020-09-29T14:41:30.250713Z 0 [System] [MY-013602] [Server] Channel MysqL_main configured to support TLS. Encrypted connections are Now supported for this channel.
2020-09-29T14:41:30.653518Z 0 [System] [MY-010931] [Server] C:\Program Files\MysqL\MysqL Server 8.0\bin\MysqLd.exe: ready for connections. Version: '8.0.21'  socket: ''  port: 3306  MysqL Community Server - GPL.
in init func
in clear func
in add func
2020-09-29T14:42:49.045501Z 0 [Warning] [MY-010915] [Server] 'NO_ZERO_DATE','NO_ZERO_IN_DATE' and 'ERROR_FOR_DIVISION_BY_ZERO' sql modes should be used with strict mode. They will be merged with strict mode in a future release.
2020-09-29T14:42:49.053090Z 0 [System] [MY-010116] [Server] C:\Program Files\MysqL\MysqL Server 8.0\bin\MysqLd.exe (MysqLd 8.0.21) starting as process 188880
2020-09-29T14:42:49.102031Z 1 [System] [MY-013576] [InnoDB] InnoDB initialization has started.
2020-09-29T14:42:53.150956Z 1 [System] [MY-013577] [InnoDB] InnoDB initialization has ended.
2020-09-29T14:42:53.914379Z 0 [System] [MY-011323] [Server] X Plugin ready for connections. Bind-address: '::' port: 33060
2020-09-29T14:42:54.728381Z 0 [System] [MY-010229] [Server] Starting XA crash recovery...
2020-09-29T14:42:54.737801Z 0 [System] [MY-010232] [Server] XA crash recovery finished.
2020-09-29T14:42:55.464369Z 0 [Warning] [MY-010068] [Server] CA certificate ca.pem is self signed.
2020-09-29T14:42:55.465965Z 0 [System] [MY-013602] [Server] Channel MysqL_main configured to support TLS. Encrypted connections are Now supported for this channel.
2020-09-29T14:42:56.133327Z 0 [System] [MY-010931] [Server] C:\Program Files\MysqL\MysqL Server 8.0\bin\MysqLd.exe: ready for connections. Version: '8.0.21'  socket: ''  port: 3306  MysqL Community Server - GPL.

我放置了一些cout语句来知道我在哪个函数中。

有人可以在这里帮助我吗? 我在这里做什么? 任何帮助或建议都会有很大帮助。

解决方法

问题在于:

graal_isolate_t* isolate = NULL;
graal_isolatethread_t* thread = NULL;

它们为null,这就是为什么它无法调用java方法并且连接超时的原因。

如果我这样初始化它们:

if (graal_create_isolate(NULL,&isolate,&thread) != 0) {
        fprintf(stderr,"initialization error\n");
        return;
    }

然后运行正常。