MacOS下MySQL 8.0.28自定义UDF更新后无法重载缓存版本的问题求助
解决MySQL在MacOS上无法重新加载更新版UDF库的问题
你遇到的这个情况是MacOS的**动态链接器缓存(dyld)**在作祟——哪怕你已经删除了物理的.so文件,dyld依然会保留旧库的缓存副本,导致MySQL加载的还是旧版本的UDF逻辑。下面是针对你的场景(MacOS 12.0 + MySQL 8.0.28)的分步解决方案:
1. 先尝试重启MySQL服务
MySQL进程可能还持有旧库文件的句柄,重启服务可以强制释放这些资源:
- 如果你是用Homebrew安装的MySQL,执行:
brew services restart mysql - 如果你是通过官方安装包部署的,用launchctl控制:
sudo launchctl stop com.oracle.oss.mysql.mysqld sudo launchctl start com.oracle.oss.mysql.mysqld
2. 强制重建dyld共享缓存
MacOS的dyld会缓存所有系统和用户安装的共享库,这是导致你删除文件后还能加载旧库的核心原因。执行以下命令强制清理并重建缓存:
sudo update_dyld_shared_cache -force
执行完这个命令后,再尝试创建不存在的UDF库(比如你之前测试的libudf_xyz.so),应该会正常报错,说明缓存已经清理干净了。
3. 遵循UDF库的正确更新流程
更新UDF时,一定要按顺序操作,避免缓存残留:
- 第一步:在MySQL中删除旧函数
DROP FUNCTION decrypt; - 第二步:停止MySQL服务(参考步骤1的命令)
- 第三步:将新编译好的
libudf_func.so复制到MySQL的plugin目录(你这里是/usr/local/opt/mysql/lib/plugin/) - 第四步:启动MySQL服务
- 第五步:重新创建UDF函数
CREATE FUNCTION decrypt RETURNS STRING SONAME "libudf_func.so";
4. 额外排查:检查MySQL进程的文件句柄
如果上面的方法还没解决,可以检查MySQL进程是否还在引用旧库的残留句柄:
- 先找到MySQL的进程ID:
ps aux | grep mysqld - 用
lsof查看该进程打开的文件:lsof -p <mysql_pid> | grep libudf
如果能看到旧库的路径,说明进程还没释放,重启服务就能解决。
补充说明
你提到删除所有.so文件后仍能创建函数,这完全是dyld缓存的锅——dyld会把常用的共享库缓存到系统目录,哪怕原文件被删除,缓存依然存在,直到你执行update_dyld_shared_cache -force重建缓存。
另外,创建UDF时可以尝试使用绝对路径指定库文件,这样能避免MySQL依赖搜索路径加载旧缓存:
CREATE FUNCTION decrypt RETURNS STRING SONAME "/usr/local/opt/mysql/lib/plugin/libudf_func.so";
内容的提问来源于stack exchange,提问作者Carlotta
相关产品推荐
相关产品推荐

