刷新 MYSQL UDF

发布于 2025-01-10 16:56:58 字数 3642 浏览 3 评论 0原文

我正在尝试使用我自己的 UDF(用 C++ 编写)作为 mysql 扩展。我能够通过安装该功能

CREATE FUNCTION  decrypt RETURNS STRING SONAME "libudf_func.so";

并使用它。我还可以通过 After 删除该函数

DROP FUNCTION decrypt;

,它不会列在 mysql.func 表中,所以我很确定它已成功删除。

现在我想使用我的函数的更新版本,因此在 mysql 中重新加载它。然而,mysql只重新加载我的文件的旧版本(我将其从计算机中完全删除)。即使我删除所有名为“libudf_func.so”的文件,它也会重新加载。

我在本地主机上的 macos12.0 上使用 mysql 版本 8.0.28。

如何删除这个缓存版本或强制 mysql 重新加载?

编辑

  • 我的所有步骤,从加载第一个版本到尝试加载更新版本:
  1. 我使用:CREATE FUNCTION解密RETURNS STRING SONAME“libudf.so”;到最初创建函数解密
  2. 我更改了 udf.cpp 文件中的某些内容。
  3. 我使用:DROP FUNCTION解密;来删除函数解密
  4. 我使用CREATE FUNCTION解密RETURNS STRING SONAME“libudf.so”;作为尝试重新加载/刷新函数解密(没有错误)
  5. 行为没有改变(除其他外,我想输出不同的错误消息,所以这显然是旧行为)
  6. 我将 libudf.so 重命名为lubudf_func.so
  7. 我用新名称复制了它。
  8. 我从我的机器上删除了名为 libudf.so 或 lubudf_func.so 的所有文件,
  9. 我仍然可以执行 CREATE FUNCTIONDecrypt RETURNS STRING SONAME "libudf.so";,没有任何错误
  10. 我尝试调用 CREATE FUNCTION解密RETURNS STRING SONAME“libudf_xyz.so”;(从未存在过),失败。错误消息:“错误代码:1126。无法打开共享库'libudf_xyz.so'(errno:2 dlopen(/usr/local/opt/mysql/lib/plugin/libudf_xyz.so,0x0002):尝试:'/ usr/local/opt/mysql/lib/plugin/libudf_xyz.so'(没有这样的f)”
  • plugin_dir: /usr/local/opt/mysql/lib/plugin/ --->(这是 .so 文件所在的位置,但现在不再是了)
  • 我如何注意到旧行为仍然存在? 致命的赠品是该函数使用了旧错误消息(“请使用纯文本(int),iv(字符串),密钥(字符串)”),而不是步骤号后的新消息(“请使用纯文本(字符串),iv(字符串),密钥(字符串)”) 。 4
  • 还要添加plugins/目录的内容,CREATE FUNCTION使用它来加载函数:我用c++编写了该库,然后将其构建为共享库。 C++ 代码如下(但我不确定这是否相关):
extern "C" {
    bool decrypt_init(UDF_INIT *initid, UDF_ARGS *args, char *message);
    char *decrypt(UDF_INIT *initid, UDF_ARGS *args, char *result, unsigned long *length, char *is_null, char *error);
    void decrypt_deinit(UDF_INIT *initid);
}
bool decrypt_init(UDF_INIT *initid, UDF_ARGS *args, char *message) {
    if (args->arg_count != 3 or
        args->arg_type[0] != STRING_RESULT or
        args->arg_type[1] != STRING_RESULT or
        args->arg_type[2] != STRING_RESULT
            ) {
        strcpy(message, "Usage: decrypt_poly(string ctext, string key, string iv)");
        return 1;
    }
    if (args->lengths[2] != 48) {
        strcpy(message, "Only 24-length IVs are allowed. Make sure IV is hexed.");
        return 1;
    }
    initid->ptr = new char[args->lengths[0]];
    initid->maybe_null = 1;

    return 0;
}
char *decrypt(UDF_INIT *initid, UDF_ARGS *args,
                  char *result, unsigned long *length,
                  char *is_null, char *error) {
    std::string dvalue;
    if (NULL != args->args[0]) {
        std::string value = std::string(args->args[0], args->lengths[0]);
        std::string key = std::string(args->args[1], args->lengths[1]);
        std::string iv = std::string(args->args[2], args->lengths[2]);

        try {
            dvalue = ((encryption::poly_based_encryption::decrypt(value, key, iv))));
        }
        catch (CryptoPP::Exception &e) {
            std::cerr << e.what() << std::endl;
            *error = 1;
        }

    } else {
        dvalue = "";
        *is_null = 1;
        *error = 1;
        return NULL;
    }
    strcpy(initid->ptr, dvalue.c_str());
    *length = dvalue.length();
    result = initid->ptr;
    *is_null = 0;
    *error = 0;
    return result;
}
void decrypt_deinit(UDF_INIT *initid) {
    if (initid->ptr)
        delete[] initid->ptr;
}

I am trying to use my own UDF (written in c++) as a mysql extension. I was able to install the function via

CREATE FUNCTION  decrypt RETURNS STRING SONAME "libudf_func.so";

and use it. I could also drop the function via

DROP FUNCTION decrypt;

After that it would not be listed in the mysql.func table, so Im pretty sure it was successfully deleted.

Now I want to use an updated version of my function, and therefore reload it in mysql. However, mysql only reloads the old version of my file (which I completely removed from the computer). Even if I remove ALL files named "libudf_func.so" it will be reloaded.

I'm using mysql version 8.0.28 for macos12.0 on localhost.

How can I remove this cached version or force mysql to reload?

EDIT

  • All my steps, from loading the first version to my attempt to load the updated version:
  1. I used: CREATE FUNCTION decrypt RETURNS STRING SONAME "libudf.so"; to initially create the function decrypt
  2. I changed something in my udf.cpp file.
  3. I used: DROP FUNCTION decrypt; to remove the function decrypt
  4. I used CREATE FUNCTION decrypt RETURNS STRING SONAME "libudf.so"; as an attempt to reload/refresh the function decrypt (NO ERRORS)
  5. the behaviors did not change (among other things I wanted to output a different error message, so that was pretty obviously the old behavior)
  6. I renamed libudf.so to lubudf_func.so
  7. I replicated this with the new name.
  8. I deleted ALL files with the names libudf.so or lubudf_func.so from my machine
  9. I could still execute CREATE FUNCTION decrypt RETURNS STRING SONAME "libudf.so"; without any errors
  10. I tried to call CREATE FUNCTION decrypt RETURNS STRING SONAME "libudf_xyz.so"; (never existed), which failed. Error message: "Error Code: 1126. Can't open shared library 'libudf_xyz.so' (errno: 2 dlopen(/usr/local/opt/mysql/lib/plugin/libudf_xyz.so, 0x0002): tried: '/usr/local/opt/mysql/lib/plugin/libudf_xyz.so' (no such f)"
  • plugin_dir: /usr/local/opt/mysql/lib/plugin/
    --->(this is where the .so file WAS located, but is not anymore)
  • How did I notice the old behavior was still present? The dead giveaway was that the function used the old error message ("Please use plaintext(int), iv(string), key(string)"), and not the new message ("Please use plaintext(string), iv(string), key(string)") after step no. 4
  • Also add the content of the plugins/ directory, which CREATE FUNCTION uses to load the function: I wrote the library in c++, then built it as a shared library. The c++ code would be as follows (but Im not sure this is relevant):
extern "C" {
    bool decrypt_init(UDF_INIT *initid, UDF_ARGS *args, char *message);
    char *decrypt(UDF_INIT *initid, UDF_ARGS *args, char *result, unsigned long *length, char *is_null, char *error);
    void decrypt_deinit(UDF_INIT *initid);
}
bool decrypt_init(UDF_INIT *initid, UDF_ARGS *args, char *message) {
    if (args->arg_count != 3 or
        args->arg_type[0] != STRING_RESULT or
        args->arg_type[1] != STRING_RESULT or
        args->arg_type[2] != STRING_RESULT
            ) {
        strcpy(message, "Usage: decrypt_poly(string ctext, string key, string iv)");
        return 1;
    }
    if (args->lengths[2] != 48) {
        strcpy(message, "Only 24-length IVs are allowed. Make sure IV is hexed.");
        return 1;
    }
    initid->ptr = new char[args->lengths[0]];
    initid->maybe_null = 1;

    return 0;
}
char *decrypt(UDF_INIT *initid, UDF_ARGS *args,
                  char *result, unsigned long *length,
                  char *is_null, char *error) {
    std::string dvalue;
    if (NULL != args->args[0]) {
        std::string value = std::string(args->args[0], args->lengths[0]);
        std::string key = std::string(args->args[1], args->lengths[1]);
        std::string iv = std::string(args->args[2], args->lengths[2]);

        try {
            dvalue = ((encryption::poly_based_encryption::decrypt(value, key, iv))));
        }
        catch (CryptoPP::Exception &e) {
            std::cerr << e.what() << std::endl;
            *error = 1;
        }

    } else {
        dvalue = "";
        *is_null = 1;
        *error = 1;
        return NULL;
    }
    strcpy(initid->ptr, dvalue.c_str());
    *length = dvalue.length();
    result = initid->ptr;
    *is_null = 0;
    *error = 0;
    return result;
}
void decrypt_deinit(UDF_INIT *initid) {
    if (initid->ptr)
        delete[] initid->ptr;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文