ImportError: /usr/lib/x86_64-linux-gnu/libstdc++.so.6: version `GLIBCXX_3.4.20’ not found 问题处理
最近在搞数据仓库的项目,需要搞个etl工具,想在服务器上布个kettle,项目服务器上已经布了很多服务,包括应用,算法,调度平台,监控等。其中一个算法模型是“fasttext”。
在网上找了篇kettle的centos7布署教程,kettle本来是不需要做多余的安装配置,只需把压缩包上传到服务器,解压即可,重要的是需要安装一些前置依赖。
kettle布署的教 程链接如下,
https://wenku.baidu.com/view/4e3571f7250c844769eae009581b6bd97f19bc24.html
而我就是在安装前lib库时翻车了,如下图:
执行上面 yum安装时,可能是网络原因,下载特别慢,十来分钟后,估计装了一半了,被我直接ctrl+c中断,这个时候,应用服务监控直接报错,如下:
习惯性百度一下,网上一堆处理这问题的教程,基本都是教 你升级glibc库,于是就升级吧,
首先参考的教 程是这个(请勿参考,否则坑到你怀疑人生):
https://blog.csdn.net/poxiaonie/article/details/74059023
此文的解决方法是教 你升级glibc,因为是你的glibc版本太低,然后缺少GLIBCXX_3.4.20,升级以便使新版类库包含GLIBCXX_3.4.20,想法是没错,但编译安装后,直接覆盖原有的libc,就是给读者埋坑:
坑说明:
1.libc.so.6原硬是个链接,指向libc-2.17.so,如果直接把libc.so.6 cp覆盖过云,把链接替换成了实体文件,与原来完全不是同一回事。
2…libc.so.6,这个链接指向的libc-2.17.so,是系统底层核 心库文件,如果出错,将导致所有命失效,系统完全连不上。
看下面这个被坑的人怎么说的:
我用的是华为云centos7,执行上面cp命令,提示你是否覆盖原有文件,敲入“y”,moba的sh客户端直接显示
无论怎么都连不上,
等了几分钟,重新连居然连上去了,查看libc.so.6,发现该 文件被还原了,应该是华为云的保护机制。万幸!
该 文章有坑,于是继续查找其他教 程,
于是找到了这篇:https://blog.csdn.net/zhaojianting/article/details/81096707
这个文章还是比较中恳,至少告诉你操作很危险,也有个小坑,如下图:
坑点:
通过LD_PRELOAD rm libc.so.6,再把新库通过新库重建 libc.so.6链接,这里,如果直接把libc.so.6直接删了,会出现上文第一文中的相同危险因素,如果替换后,退出了客户端,这时候你可能再也连不上你的服务器了。
正确做法是:
LD_PRELOAD=/lib64/libc-2.2.5.so ln -s /lib64/libc-2.2.5.so libc.so.6-test,
先试试该 命令能不能行。千万记住LD_PRELOAD一定要用新库来做,像文中的新库是libc-2.2.5.so,如果用原来的那个老库,肯定能执行成功,替换后,就悲剧了,
libc.so.6这个先不直接替换,先命个别命做个测试。
我在执行“ LD_PRELOAD=/lib64/libc-2.2.5.so ln -s /lib64/libc-2.2.5.so libc.so.6-test,” 时,报“segment fault”
跟网上说的一样,不同的是有的人 是替换完成后报错。
我想是不是因为我的glibc版本太高了,我装了个最新版glibc2.33(为些还升级了make到4.3),
于是重新下载glibc2.18安装,这时,又出现了新的问题,老版本的glibc,得用老版本的make,如理先重装一个make3.8,
然后重编译glibc2.18,
后面执行上面的替换操作,同样还是报错 segment fault,
这条路行不通,于是换个思路,
能不能将其他系统上的该 文件弄过来替换一下呢。说做就做,
找个同版本的系统文件lib-2.17.so,
strings lib-2.17.so |grep GLIBCXX,
出来的结果与现在问题系统输出的结果一样,我估计也是行不通,于是我想,能不能从高一些的版本的centos复制该文件,于是找了个7.6的版本,最后还是报 segment fault 错误,怎么办呢,彻夜难眠了。。。
再换个思路,既然libc-2.17.so这个库文件没法更换(可能是与系统核 心文件一体的,换版本会导致不一致,用不了),那能不能把llibstdc++.so.6,这个文件降一下级呢。说做就做。
先查一下当前libstdc++.so.6该 文件的库:
strings libstdc++.so.6 | grep GLIBCXX
看到该 文件的GLIBCXX 到GLIBCXX_3.4.29了,
查一下系统中所有的libstdc++ .so.6文件:
find / -name ‘libstdc++.so.6*’
在这里插入图片描述
逐个做strings
终于找到一个与包含2.4.20,但又不太高的版本,
libstdc++.so.6这个文件是是指向libstdc++.so.6.0.19 的一个链接,我先把该 链接文件备份
mv libstdc++.so.6.0.19 libstdc++.so.6.0.19-bak。
再替换
cd /lib64
[root@ecs-60b3 lib64]# cp /usr/local/gcc/lib64/libstdc++.so.6 ./
替换成功,
然后测试fasttext,居然成功了
总结:
glibc千万不要随便更新。如果出现问题,优先用系统中原本存在的库文件,看能不能顶替。