作者:杨涛涛

资深数据库专家,专研 MySQL 十余年。善于 MySQL、PostgreSQL、MongoDB 等开源数据库相干的备份复原、SQL 调优、监控运维、高可用架构设计等。目前任职于爱可生,为各大运营商及银行金融企业提供 MySQL 相干技术支持、MySQL 相干课程培训等工作。

本文起源:原创投稿

*爱可生开源社区出品,原创内容未经受权不得随便应用,转载请分割小编并注明起源。


引言

AppArmor (Debian 系平台)是一款内核级别的平安机制,通过 AppArmor 来让 Linux 零碎实现严格的资源访问控制,相似 SELinux(RedHat 系列平台)。

我本地环境为:OS 版本 Ubuntu 18,DB 版本 MySQL 8.0.27。

AppArmor 通过目录/etc/apparmor.d/ 下的一系列配置文件来别离限度每个过程对 OS 资源的拜访权限。

AppArmor 有两种工作模式:

  1. Enforced/Confined: 严格依照配置文件来限度对应的过程拜访OS资源的行为,回绝不在配置范畴内的过程运行。
  2. Complaining/Learning: 仅记录过程行为,不对其进行限度。

遇到的问题是:

我启动 MySQL ,未胜利:

root@ytt-ubuntu:~# systemctl start mysqlJob for mysql.service failed because the control process exited with error code.See "systemctl status mysql.service" and "journalctl -xe" for details.

我摘出来几条外围的错误信息:

root@ytt-ubuntu:~# journalctl -xe-- Defined-By: systemd-- user-122.slice 单元已完结进行操作。11月 16 16:14:00 ytt-ubuntu kernel: audit: type=1400 audit(1637050440.395:101): apparmor="DENIED" operation="mknod" profile="/usr/sbin/mysqld" name="/op11月 16 16:14:00 ytt-ubuntu audit[7237]: AVC apparmor="DENIED" operation="mknod" profile="/usr/sbin/mysqld" name="/opt/mysql/data/mysqld_tmp_file_case_i11月 16 16:14:01 ytt-ubuntu audit[7270]: AVC apparmor="DENIED" operation="mknod" profile="/usr/sbin/mysqld" name="/opt/mysql/log/error.log" pid=7270 com11月 16 16:14:01 ytt-ubuntu systemd[1]: mysql.service: Main process exited, code=exited, status=1/FAILURE11月 16 16:14:01 ytt-ubuntu systemd[1]: mysql.service: Failed with result 'exit-code'.11月 16 16:14:01 ytt-ubuntu systemd[1]: Failed to start MySQL Community Server.-- Subject: mysql.service 单元已失败

由错误信息能够看到,AppArmor 阻止了 MySQL 服务启动,可能的起因是启动 MySQL 服务须要拜访的目录在 AppArmor 里没有配置。

想起来我动过配置文件:

源配置内容:
[mysqld]pid-file       = /var/run/mysqld/mysqld.pidsocket         = /var/run/mysqld/mysqld.sock datadir        = /var/lib/mysqllog-error      = /var/log/mysql/error.log
我改后的配置内容:
[mysqld]           pid-file        = /opt/mysql/mysqld.pidsocket          = /opt/mysql/mysqld.sockdatadir         = /opt/mysql/datalog-error       = /opt/mysql/log/error.log

此时有两种办法来解决这个问题。

第一, 间接更改AppArmor 的配置文件:

给/etc/apparmor.d/user.sbin.mysqld里增加如下内容:(或者把原来MySQL相干的目录替换掉也行)

# pid,socket等文件目录  /opt/mysql/* rw,# 数据目录内容  /opt/mysql/data/ r, /opt/mysql/data/** rwk,#日志文件内容 /opt/mysql/log/ r, /opt/mysql/log** rw,

重载 AppArmor 服务

root@ytt-ubuntu:~# systemctl reload apparmor

再次重启 MySQL ,启动胜利。

root@ytt-ubuntu:/opt/mysql# systemctl start mysql

查看状态

root@ytt-ubuntu:/home/ytt# systemctl status mysql● mysql.service - MySQL Community Server   Loaded: loaded (/lib/systemd/system/mysql.service; disabled; vendor preset: enabled)   Active: activating (start) since Tue 2021-11-16 16:49:12 CST; 40s ago     Docs: man:mysqld(8)           http://dev.mysql.com/doc/refman/en/using-systemd.html  Process: 3137 ExecStartPre=/usr/share/mysql-8.0/mysql-systemd-start pre (code=exited, status=0/SUCCESS) Main PID: 3191 (mysqld)   Status: "Server startup in progress"    Tasks: 24 (limit: 4915)   CGroup: /system.slice/mysql.service           └─3191 /usr/sbin/mysqld11月 16 16:49:12 ytt-ubuntu systemd[1]: Starting MySQL Community Server...11月 16 16:49:54 ytt-ubuntu systemd[1]: Started MySQL Community Server.
第二, 扭转 AppArmor 的默认工作模式,由强制模式改为埋怨模式:

得先装置 apparmor-utils 包,外面蕴含了很多有用的程序来操作 AppArmor .

root@ytt-ubuntu:~# apt-get install apparmor-utils

独自配置 MySQL 服务进入埋怨模式:

root@ytt-ubuntu:~# aa-complain /etc/apparmor.d/usr.sbin.mysqld Setting /etc/apparmor.d/usr.sbin.mysqld to complain mode.

重载 AppArmor

root@ytt-ubuntu:~# systemctl reload apparmor

启动 MySQL 服务

root@ytt-ubuntu:~# systemctl restart mysql

查看状态

root@ytt-ubuntu:~# systemctl status mysql● mysql.service - MySQL Community Server   Loaded: loaded (/lib/systemd/system/mysql.service; disabled; vendor preset: enabled)   Active: active (running) since Tue 2021-11-16 17:11:12 CST; 12s ago     Docs: man:mysqld(8)           http://dev.mysql.com/doc/refman/en/using-systemd.html  Process: 3712 ExecStartPre=/usr/share/mysql-8.0/mysql-systemd-start pre (code=exited, status=0/SUCCESS) Main PID: 3767 (mysqld)   Status: "Server is operational"    Tasks: 41 (limit: 4915)   CGroup: /system.slice/mysql.service           └─3767 /usr/sbin/mysqld11月 16 17:10:45 ytt-ubuntu systemd[1]: Starting MySQL Community Server...11月 16 17:11:12 ytt-ubuntu systemd[1]: Started MySQL Community Server.
以上MySQL的行为基 zat于APT包装置产生,如果采纳MySQL二进制包装置,则能够躲避这个问题。