与MySQL服务器在执行聚合UDF过程中失去连接

huangapple go评论84阅读模式
英文:

Lost connection to MySQL server during aggregate UDF execution

问题

我在C++中创建了一个MySQL UDF,并将其上传到MySQL的插件目录中。我能够在MySQL中安装这个UDF,但当我尝试调用它时,MySQL服务器会停止。我在Windows 10操作系统上使用Visual Studio 2019来创建共享库(在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, 50, "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* is_null, 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, UDF_ARGS* args, char* is_null, 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.
...
...
(in init func)
(in clear func)
(in add func)
...
...

我添加了一些cout语句以了解我在哪个函数中。

请问有谁能帮我解决这个问题吗?我在这里做错了什么?任何形式的帮助或建议都将非常有帮助。

英文:

I created a MySQL UDF in C++ and uploaded it into the MySQL's plugin directory.
I am able to install the UDF in MySQL, but when I try to call it, the MySQL server stops.
I am using visual studio 2019 to create the shared library(.dll in windows) on windows 10 operating system.

I am calling a method from java in my MySQL C++ UDF, I am using graalVM to call the java methods from C++ functions.

I created a shared library out of my java code and I use them in my C++ code to access my java methods.

MySQL UDF code:DemoAgg.cpp

#ifdef STANDARD
#include &lt;stdlib.h&gt;
#include &lt;stdio.h&gt;
#include &lt;string.h&gt;
#ifdef __WIN__
typedef unsigned __int64 ulonglong;
typedef __int64 longlong;
#else
typedef unsigned long long ulonglong;
typedef long long longlong;
#endif /*__WIN__*/
#endif
#include &lt;mysql.h&gt;
#include &lt;iostream&gt;
#include &lt;ctype.h&gt;
#include &lt;demolibmysqlagg.h&gt;
extern &quot;C&quot; bool test_agg_init(UDF_INIT * initid, UDF_ARGS * args, char* message)
{
long long* i = new long long; 
*i = 0;                    
initid-&gt;ptr = (char*)i;
std::cout &lt;&lt; &quot;in init func&quot; &lt;&lt; std::endl;
if (args-&gt;arg_count != 1)
{
strcpy_s(message, 50, &quot;testagg() requires one arguments&quot;);
return 1;
}
if (args-&gt;arg_type[0] != INT_RESULT)
{
strcpy_s(message, 50, &quot;testagg() requires one integer&quot;);
return 1;
}
return 0;
}
extern &quot;C&quot; void test_agg_deinit(UDF_INIT * initid)
{
std::cout &lt;&lt; &quot;in deinit func&quot; &lt;&lt; std::endl;
delete (long long*)initid-&gt;ptr;
}
extern &quot;C&quot; void test_agg_clear(UDF_INIT* initid, char* is_null, char* error)
{
std::cout &lt;&lt; &quot;in clear func&quot; &lt;&lt; std::endl;
*((long long*)initid-&gt;ptr) = 0;
}
extern &quot;C&quot; void test_agg_add(UDF_INIT* initid, UDF_ARGS* args, char* is_null, char* error)
{
graal_isolate_t* isolate = NULL;
graal_isolatethread_t* thread = NULL;
std::cout &lt;&lt; &quot;in add func&quot; &lt;&lt; std::endl;
long long int_val;
int_val = *((long long*)initid-&gt;ptr);
long long int_val2;
int_val2 = *((long long*)args-&gt;args[0]);
long long sum;
sum = aggadd(thread, int_val, int_val2);     //my java method which i call from this program
std::cout &lt;&lt; sum;
*((long long*)initid-&gt;ptr) = sum;
}
extern &quot;C&quot; long long test_agg(UDF_INIT* initid, UDF_ARGS* args, char* is_null, char* error)
{
std::cout &lt;&lt;&quot;in main func&quot;&lt;&lt;std::endl;
return *((long long*)initid-&gt;ptr);
}

My Module Definition File:DemoAgg.def

LIBRARY testagg
EXPORTS
test_agg_init
test_agg_deinit
test_agg_clear
test_agg_add
test_agg

My java code:

package testmysql;
import org.graalvm.nativeimage.IsolateThread;
import org.graalvm.nativeimage.c.function.CEntryPoint;
public class demo_mysqlagg {
@CEntryPoint (name = &quot;aggadd&quot;)
public static int aggadd(IsolateThread thread, int x, int y) {
return x+y;
}
}

After building my C++ project, I get a dll file which I copy to the MySQL's plugin directory.

I install the UDF using the following query:

create aggregate function test_agg returns integer soname &#39;testagg.dll&#39;;

I call my UDF using the following query:

select test_agg(c1) from demo_agg;

where,

> demo_agg is a table with only one column.

> c1 is the column name of type integer.

But when I execute the above query, the following error pops up:

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

My error log:

2020-09-29T14:41:24.584058Z 0 [Warning] [MY-010915] [Server] &#39;NO_ZERO_DATE&#39;, &#39;NO_ZERO_IN_DATE&#39; and &#39;ERROR_FOR_DIVISION_BY_ZERO&#39; 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: &#39;::&#39; 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: &#39;8.0.21&#39;  socket: &#39;&#39;  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] &#39;NO_ZERO_DATE&#39;, &#39;NO_ZERO_IN_DATE&#39; and &#39;ERROR_FOR_DIVISION_BY_ZERO&#39; 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: &#39;::&#39; 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: &#39;8.0.21&#39;  socket: &#39;&#39;  port: 3306  MySQL Community Server - GPL.

I put some cout statements to know in which function I am.

Can anyone help me out here?
What I am doing here?
Any kind of help or suggestion will be of great help.

答案1

得分: 0

问题出在:

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

它们是空的,所以无法调用 Java 方法,连接超时。

如果我像这样初始化它们:

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

那么它就能正常工作。

英文:

the problem is with:

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

they are null, that's why it is not able to call the java method and the connection is getting timed out.

if I initialize them like this:

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

then it is working fine.

huangapple
  • 本文由 发表于 2020年9月29日 23:01:18
  • 转载请务必保留本文链接:https://go.coder-hub.com/64122336.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定