MySQL-8.0.32 启动失败问题的分析

2023-04-20 19:08:41 浏览数 (1)


背景

朋友安装了一个 MySQL-8.0.32 版本的 MySQL;其中服务端可以正常运行但是客户端运行不了。

1.1 ps 检查发现 mysqld 确实运行起来了。

代码语言:javascript复制
ps -ef | grep mysql
mysql33   407393       1  0 16:00 ?        00:00:03 /usr/local/mysql-8.0.32-linux-glibc2.12-x86_64/bin/mysqld --defaults-file=/etc/my-3306.cnf
root      412577  407779  0 16:21 pts/13   00:00:00 grep --color=auto mysql

1.2 mysql 客户端命令无法运行。

代码语言:javascript复制
mysql -uroot -pxxxxxx -h127.0.0.1 -P3306
mysql: error while loading shared libraries: libtinfo.so.5: 
cannot open shared object file: No such file or directory

分析

从报错的信息来看就是在加载 libtinfo.so.5 这个共享库的时候失败了。作为一个 cpper 遇到这个问题我还是比较淡定的,因为问题通常只有两个 1. 系统上有这个库文件但是它没有找到,2. 系统上根本就没有这个库文件。

对于情况 1 我们只要想办法让 mysql 能找到对应的库就行了,对于情况 2 我们只要安装上对应的依赖就能解决。

那么剩下的就是分析一下是什么情况了。先补充一下理论,加载库文件本质上就是打开库文件,对应的是 read 这个系统调用,也就是说我们只要追踪一下系统调用就可以分析出来

2.1 strace 分析系统调用

代码语言:javascript复制
strace mysql -uroot -pxxxxxx -h127.0.0.1 -e "exit;"

2.2 通过输出可以看到进程去如下地方找了 libtinfo.so.5

代码语言:javascript复制
openat(AT_FDCWD, "/usr/local/mysql-8.0.32-linux-glibc2.12-x86_64/bin/../lib/private/libtinfo.so.5", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/lib64/glibc-hwcaps/x86-64-v3/libtinfo.so.5", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/lib64/glibc-hwcaps/x86-64-v2/libtinfo.so.5", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/lib64/tls/x86_64/x86_64/libtinfo.so.5", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/lib64/tls/x86_64/libtinfo.so.5", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/lib64/tls/x86_64/libtinfo.so.5", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/lib64/tls/libtinfo.so.5", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/lib64/x86_64/x86_64/libtinfo.so.5", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/lib64/x86_64/libtinfo.so.5", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/lib64/x86_64/libtinfo.so.5", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/lib64/libtinfo.so.5", O_RDONLY|O_CLOEXEC) = 3

进程去了两 “类” 地方找了 libtinfo.so.5 这个库;第一类是 MySQL 的安装目录,第二类是系统默认的库路径。

2.3 确认 libtinfo.so.5 是不是 MySQL 安装包里的库

代码语言:javascript复制
tree /usr/local/mysql-8.0.32-linux-glibc2.12-x86_64/lib | grep libtinfo

在 MySQL 的 lib 目录下找不到,说明这个不是 MySQL 自带的库。

2.4 确认是不是系统库

代码语言:javascript复制
tree /lib64/ | grep libtinfo
├── libtinfo.so -> libtinfo.so.6
├── libtinfo.so.6 -> libtinfo.so.6.2
├── libtinfo.so.6.2

可以看得出两个结论 1. libtinfo 是系统库;2. 系统上的 libtinfo 库的版本已经升级到了 libtinfo.so.6 。程序找 libtinfo.so.5 所以会找不到。

难道是他的操作系统太新了?我确认一下。

代码语言:javascript复制
cat /etc/system-release
CentOS Stream release 9

系统都到 CentOS-9 了确实新!



解决办法

通过前面的分析可以看到由于系统比较新,libtinfo.so 的版本已经升级到 6 了,然而 mysql 还依赖于 5 。/lib64 下面的是基础库,如果采用降级的方式来处理影响面就太大了;最终选择 “骗” 一下 MySQL ,告诉它有一个 libtinfo.so.5 但是实际上是 libtinfo.so.6 。

代码语言:javascript复制
# 创建 5 版本的连接文件
cd /lib64
ln -s libtinfo.so libtinfo.so.5
# 重启加载库
ldconfig

检查

代码语言:javascript复制
mysql -uroot -pxxxxxx -h127.0.0.1 -P3306
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or g.
Your MySQL connection id is 22
Server version: 8.0.32 MySQL Community Server - GPL

Copyright (c) 2000, 2023, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or 'h' for help. Type 'c' to clear the current input statement.

mysql> select @@version;
 ----------- 
| @@version |
 ----------- 
| 8.0.32    |
 ----------- 
1 row in set (0.00 sec)

0 人点赞