【问题标题】:MySQL UDF returns "Error Code: 1127. Can't find symbol 'xx' in library"MySQL UDF 返回“错误代码:1127。在库中找不到符号 'xx'”
【发布时间】:2020-06-10 20:19:37
【问题描述】:

我有一个用 Go 编写的 MySQL UDF,以前可以正常工作,但如果我现在编译它不再起作用,并显示错误消息

错误代码:1127。在库中找不到符号“get_url_param”

UDF 在 GitHub 上:https://github.com/StirlingMarketingGroup/mysql-get-url-param

如果我像这样检查旧编译文件的导出

$ nm get_url_param.old.so | grep get_url_param
00000000000f21f0 T _cgoexp_38fa52dfc07b_get_url_param
00000000000f20c0 T _cgoexp_38fa52dfc07b_get_url_param_deinit
00000000000f2130 T _cgoexp_38fa52dfc07b_get_url_param_init
00000000000f2af0 T get_url_param
00000000000f2a00 T get_url_param_deinit
00000000000f2a70 T get_url_param_init
00000000000f2250 t main._cgoexpwrap_38fa52dfc07b_get_url_param
00000000000f2690 t main._cgoexpwrap_38fa52dfc07b_get_url_param.func1
00000000000f2120 t main._cgoexpwrap_38fa52dfc07b_get_url_param_deinit
00000000000f2190 t main._cgoexpwrap_38fa52dfc07b_get_url_param_init
00000000000f24f0 t main.get_url_param
00000000000f2460 t main.get_url_param_init

而且这个文件在运行时工作得很好

create function`get_url_param`returns string soname'get_url_param.so';

但是当我用相同的命令编译相同的代码时

go build -buildmode=c-shared -o get_url_param.so

然后以同样的方式检查导出

$ nm get_url_param.so | grep get_url_param
0000000000109360 T _cgoexp_d994eb9c9c89_get_url_param
0000000000109230 T _cgoexp_d994eb9c9c89_get_url_param_deinit
00000000001092a0 T _cgoexp_d994eb9c9c89_get_url_param_init
0000000000109a50 T get_url_param
0000000000109960 T get_url_param_deinit
00000000001099d0 T get_url_param_init
00000000001093c0 t main._cgoexpwrap_d994eb9c9c89_get_url_param
0000000000109820 t main._cgoexpwrap_d994eb9c9c89_get_url_param.func1
0000000000357cb0 d main._cgoexpwrap_d994eb9c9c89_get_url_param.stkobj
0000000000109290 t main._cgoexpwrap_d994eb9c9c89_get_url_param_deinit
0000000000109300 t main._cgoexpwrap_d994eb9c9c89_get_url_param_init
0000000000109680 t main.get_url_param
0000000000357cd0 d main.get_url_param.stkobj
00000000001095f0 t main.get_url_param_init

看起来一切正常。而且我可以说我正在检查正确的文件,因为所有地址都不同(另外,main.get_url_param.stkobj 是一个新行)。但是这次尝试添加它会给我关于 MySQL 如何在库中找不到符号的错误。

我非常确定编译命令保持不变,而且我认为它与 Go 版本没有任何关系,因为我测试回 Go 1.9 并且它做同样的事情,但仍然无法正常工作。

我已经上传了二进制文件以及带有old one that worksnew one that doesn't work 的版本。两个 .so 文件都以相同的方式复制到我的插件目录,所以我认为这与权限无关。此外,Go func 名称为小写肯定与此无关,因为即使我将函数重命名为 GetURLParam,行为也是完全相同的,并且我可以看到带有 nm 的导出。

我确定我遗漏了一些东西,可能是编译命令,或者可能是一些 cgo 标志,但我只是不知道那会是什么。

【问题讨论】:

  • 我在 docker docker run --rm -d -v /tmp/mysql-get-url-param:/mysql-get-url-param -e MYSQL_ALLOW_EMPTY_PASSWORD=true --name mysql-server-udf mysql:5.7.26 中运行的 mysql 服务器 5.7.26 中尝试了 v1.0.1-alpha 二进制文件,它工作得很好。我也尝试自己编译它,它在该服务器上也能正常工作。你能指定你使用的是哪个mysql版本吗?
  • 有趣,我使用的是 MySQL 的 Percona strand 8.0.16-7 版本
  • 它也适用于在 docker docker run --rm -d -v /tmp/mysql-get-url-param:/mysql-get-url-param -e MYSQL_ALLOW_EMPTY_PASSWORD=YES --name mysql-server-udf percona:8.0.16-7 中运行的 percona 发行版
  • 你确定服务器使用的插件目录是正确的吗?例如,如果从插件目录中删除了 get_url_param.so 文件,服务器是否会返回不同的错误(抱怨找不到共享对象)?
  • 听起来很奇怪。此时,我会停止并重新启动服务器,以确保 mysqld 进程不会以某种方式持有对旧(或不同)共享库的引用,从而妨碍。

标签: mysql go cgo shared-objects mysql-udf


【解决方案1】:

过去我遇到过同样的问题,并且(仅)重新启动服务器有帮助。如果我记得正确的话,有些东西被缓存了,甚至完全重新编译/替换的库文件也没有正确重新加载。

所以:

  1. 重新编译插件
  2. 在使用相同操作系统/MySQL 版本的不同机器上测试
  3. 复制到生产机器
  4. 重启生产机器
  5. 评估

【讨论】:

  • 就是这样,我很遗憾我自己没有尝试过,但希望这篇文章对将来的某人有所帮助,它在其他机器上也能正常工作。奇怪的是,它只对 Go 编译的 UDF 执行此操作。我尝试了 3 或 4 个,他们都这样做了,但是我用 C 编写的 UDF 可以正常工作
猜你喜欢
  • 2011-09-25
  • 1970-01-01
  • 2011-04-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-29
  • 2023-03-12
  • 1970-01-01
相关资源
最近更新 更多