SELinux 权限问题导致 GreatSQL 运行不了的坑
系统版本:Linux version 4.18.0-348.el8.x86_64
前言
SELinux 是什么
SELinux 工作原理
开启 SELinux 可以提升系统的安全性,但同时也会带来一些问题。在特定场景有的人会选择关闭 SELinux 以换取更好的兼容性。
在GreatSQL的安装手册里,就有关闭 SELinux 这一步。
#关闭selinux
$ setenforce 0
$ sed -i '/^SELINUX=/c'SELINUX=disabled /etc/selinux/config
不禁让人好奇,这个 SELinux 安全模块,如果不关闭会产生什么问题,在使用时有哪些需要注意的地方。于是我特意尝试了一下,开启 SELinux 安装 GreatSQL 数据库,看看会出现哪些问题。
问题产生
为了发现问题,我特意选择在用户目录(/root)下载解压 GreatSQL 二进制压缩包,然后再移动到指定目录使用。
cd /root
wegt https://***.***/greatsql.tar.gz
tar -xvf greatsql.tar.gz
mv /root/greatsql /usr/local/
安装过程一切顺利,数据库正常启动了,但是在配置 systemd
进程守护的时候出现了问题。
greatsql.service文件:
vim /usr/lib/systemd/system/greatsql.service
[Unit]
Description=GreatSQL Server
After=network.target
After=syslog.target
[Install]
WantedBy=multi-user.target
[Service]
User=greatsql
Group=greatsql
# Have mysqld write its state to the systemd notify socket
Type=notify
# Disable service start and stop timeout logic of systemd for mysqld service.
TimeoutSec=0
# Start main service
ExecStart=/usr/local/mysql/bin/mysqld --defaults-file=/etc/my.cnf $MYSQLD_OPTS
# Use this to switch malloc implementation
#EnvironmentFile=-/etc/sysconfig/mysql
# Sets open_files_limit
LimitNOFILE = 10000
Restart=on-failure
RestartPreventExitStatus=1
# Set environment variable MYSQLD_PARENT_PID. This is required for restart.
Environment=MYSQLD_PARENT_PID=1
PrivateTmp=false
用 systemctl start greatsql
启动数据库的时候报以下错误。
[root@Linux ~]# systemctl restart greatsql
Job for greatsql.service failed because the control process exited with error code.
See "systemctl status greatsql.service" and "journalctl -xe" for details.
直接运行mysqld
没问题但是使用systemctl
就启动不了。
根据上面的报错,查看一下 greatsql systemd的状态和相关日志
[root@gip Linux]# systemctl status greatsql.service
● greatsql.service
Loaded: loaded (/usr/lib/systemd/system/greatsql.service; bad; vendor preset: disabled)
Active: failed (Result: exit-code) since Tue 2023-01-10 16:00:06 CST; 17s ago
Process: 147226 ExecStart=/usr/local/greatsql/bin/mysqld --defaults-file=/etc/my.cnf $MYSQLD_OPTS (code=exited, status=203/EXEC)
Main PID: 147226 (code=exited, status=203/EXEC)
Jan 10 16:00:06 gip systemd[1]: greatsql.service: Service RestartSec=100ms expired, scheduling restart.
Jan 10 16:00:06 gip systemd[1]: greatsql.service: Scheduled restart job, restart counter is at 5.
Jan 10 16:00:06 gip systemd[1]: Stopped greatsql.service.
Jan 10 16:00:06 gip systemd[1]: greatsql.service: Start request repeated too quickly.
Jan 10 16:00:06 gip systemd[1]: greatsql.service: Failed with result 'exit-code'.
Jan 10 16:00:06 gip systemd[1]: Failed to start greatsql.service.
Jan 10 16:00:23 gip systemd[1]: /usr/lib/systemd/system/greatsql.service:1: Missing '='.
通过查看上述信息,可以得知 程序启动的时候抛出了报错。
Main PID: 147226 (code=exited, status=203/EXEC)
通过上网搜索可以得知,status=203/EXEC
报错可能和权限不足有关,记一下这里的PID。
我们继续查看一下相关日志证实一下。
[root@Linux ~]# journalctl _PID=13386
-- Logs begin at Tue 2023-01-10 16:54:11 CST, end at Tue 2023-01-10 17:09:15 CST. --
Jan 10 17:00:36 gip systemd[13386]: greatsqld.service: Failed to execute command: Permission denied
Jan 10 17:00:36 gip systemd[13386]: greatsqld.service: Failed at step EXEC spawning /usr/local/greatsql/bin/mysqld: Permission denied
可以看到确实是权限不足。
但是奇怪的事情来了,通过查看文件权限发现权限并没有问题。
[root@GreatSQL bin]# ls -lah |grep mysql
-rwxr-xr-x. 1 root root 6.9M 4月 29 2022 mysql
-rwxr-xr-x. 1 root root 6.8M 4月 29 2022 mysqladmin
-rwxr-xr-x. 1 root root 7.1M 4月 29 2022 mysqlbinlog
-rwxr-xr-x. 1 root root 6.8M 4月 29 2022 mysqlcheck
-rwxr-xr-x. 1 root root 6.3K 4月 29 2022 mysqld_pre_systemd
-rwxr-xr-x. 1 root root 34K 4月 29 2022 mysqld_safe
-rwxr-xr-x. 1 root root 6.9M 4月 29 2022 mysqldump
-rwxr-xr-x. 1 root root 1.7K 4月 29 2022 mysqldumpslow
***后省略***
即便把权限改成755,甚至777 也还是会报一样的错误。
chown -R mysql:mysql /usr/local/mysql
chmod 755 -R /usr/local/mysql
问题原因
后面我有检查了所有相关文件的权限,都没问题,但是程序还是会报权限不足。
在网上翻阅了资料,发现了问题产生原因。
是SELinux 的问题, 因为我的二进制文件是先下载到 /root
目录,然后才移到 /usr/local/greatsql
目录,从/root
目录移动到/usr/local/
目录时它们的 SELinux 上下文不会自动变更,依然是用户主目录。所以出现了权限问题。
解决方法:
#恢复文件的安全上下文
restorecon -rv /usr/local/greatsql
总结
可执行文件是先存放在用户目录,然后移动到别的目录,文件的 SELinux 上下文不会自动变更,依然是用户目录。
这就导致了,能直接运行,但是通过 systemd 启动时仍然报 Permission denied权限不足的问题。
解决方法就是用restorecon命令用来恢复SELinux文件属性
restorecon -rv 目标目录
相关链接:
解决文件权限正确,但 systemd 服务仍然提示没有权限,启动失败。(https://blog.csdn.net/kunyus/article/details/106592236)
一文带你看懂 SELinux 是什么? (redhat.com(https://www.redhat.com/zh/topics/linux/what-is-selinux)
Enjoy GreatSQL :)
《深入浅出MGR》视频课程
戳此小程序即可直达B站
https://www.bilibili.com/medialist/play/1363850082?business=space_collection&business_id=343928&desc=0
文章推荐:
MySQL 8.0不再担心被垃圾SQL搞爆内存 好用的数据校验&修复工具gt-checksum开源啦 NL连接一定是小表驱动大表效率高吗 从零开始学习MySQL调试跟踪(2) MySQL利用表空间透明传输快速恢复单表 MySQL8.0 show create view BUG解析 MySQL 8.0中InnoDB buffer pool size进度更透明 MySQL好玩新特性:离线模式 MySQL中WHERE后跟着N多个OR条件会怎样。。。 MySQL Hash Join前世今生 MySQL信号量等待日志阅读 深入聊聊MySQL直方图的应用
想看更多技术好文,点个“在看”吧!