【发布时间】: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 works 和new 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