作为Write for DOnations计划的一部分,作者选择了免费和开源基金来接受捐赠。
介绍
在本教程中,您将使用systemd
配置 MySQL 在重启或崩溃后自动重启。
这是由两部分组成的系列的后半部分。第一部分涵盖了一般的 Linux 服务管理概念,如init
守护进程和运行级别。它以 .NET 中的服务管理演示结束systemd
。在这里,您将检查targets
,wants
,requires
,和unit
文件。这部分(第二部分)提供了一个使用MySQL 数据库的实际示例。
注意:您也可以考虑阅读我们非常流行的使用systemctl
来控制 systemd 服务和单元的教程。
先决条件
要完成本教程,您需要:
-
运行 CentOS 8 的服务器,包括具有 sudo 权限的非 root 用户。要设置所有这些,包括防火墙,您可以创建一个运行 CentOS 8 的 DigitalOcean Droplet,然后按照我们的初始服务器设置指南进行操作。
-
已安装 MySQL。有关详细说明,请遵循我们的教程,如何在 CentOS 8 上安装 MySQL。
配置 MySQL 在启动后自动启动使用 systemd
安装 MySQL 后,检查服务的状态:
- sudo systemctl status mysqld.service
输出应显示服务正在运行,但守护进程已禁用:
Output mysqld.service - MySQL 8.0 database server
Loaded: loaded (/usr/lib/systemd/system/mysqld.service; disabled; vendor preset: disabled)
Active: active (running) since Thu 2020-12-24 23:48:56 UTC; 1h 6min ago
Process: 30423 ExecStartPost=/usr/libexec/mysql-check-upgrade (code=exited, status=0/SUCCESS)
Process: 30294 ExecStartPre=/usr/libexec/mysql-prepare-db-dir mysqld.service (code=exited, status=0/SUCCESS)
Process: 30270 ExecStartPre=/usr/libexec/mysql-check-socket (code=exited, status=0/SUCCESS)
Main PID: 30378 (mysqld)
Status: "Server is operational"
Tasks: 40 (limit: 4763)
...
如果该服务已启用,请将其禁用。在进行更改之前,我们首先要探索禁用的行为:
- sudo systemctl disable mysqld.service
接下来,运行此命令以检查 multi-user.target 是否需要 MySQL:
- sudo systemctl show --property "Wants" multi-user.target | fmt -10 | grep mysql
什么都不会回来。现在检查符号链接是否存在:
- sudo ls -l /etc/systemd/system/multi-user.target.wants/mysql*
出现一条消息,指出符号链接文件不存在:
Outputls: cannot access '/etc/systemd/system/multi-user.target.wants/mysql*': No such file or directory
现在,如果您愿意,可以重新启动服务器并检查 MySQL 服务。它不应该运行。
无论您是否重新启动,现在重新启用 MySQL 服务:
- sudo systemctl enable mysqld.service
这一次,系统会在 下创建一个符号链接/etc/systemd/system/multi-user.target.wants/
:
OutputCreated symlink /etc/systemd/system/multi-user.target.wants/mysqld.service → /usr/lib/systemd/system/mysqld.service.
再次运行 ls 命令以确认这一点:
- sudo ls -l /etc/systemd/system/multi-user.target.wants/mysql*
您将收到如下输出:
Outputlrwxrwxrwx 1 root root 38 Aug 1 04:43 /etc/systemd/system/multi-user.target.wants/mysqld.service -> /usr/lib/systemd/system/mysqld.service
启用或禁用 systemd 服务会从默认目标的 Wants 目录中创建或删除符号链接。
如果您愿意,请再次重新启动 Droplet,当它重新联机时,运行ps -ef
命令以检查服务状态。
- ps -ef | grep mysql
如果 MySQL 正在运行,此命令将提供有关 MySQL 的信息:
Output\mysql 851 1 2 04:26 ? 00:00:02 /usr/libexec/mysqld --basedir=/usr
您现在已将 MySQL 配置为在重新启动后重新启动。接下来,您将考虑崩溃。
配置 MySQL 在崩溃后自动启动使用 systemd
作为一个现代应用程序,MySQL 已经配置为在崩溃后自动启动。让我们看看如何禁用它。
在编辑器中打开 MySQL 服务单元文件:
- sudo vi /etc/systemd/system/multi-user.target.wants/mysqld.service
在头信息之后,文件的内容如下所示:
[Unit]
Description=MySQL 8.0 database server
After=syslog.target
After=network.target
[Service]
Type=notify
User=mysql
Group=mysql
ExecStartPre=/usr/libexec/mysql-check-socke
ExecStartPre=/usr/libexec/mysql-prepare-db-dir %n
`# Note: we set --basedir to prevent probes that might trigger SELinux alarms,`
`# per bug #547485`
ExecStart=/usr/libexec/mysqld --basedir=/usr
ExecStartPost=/usr/libexec/mysql-check-upgrade
ExecStopPost=/usr/libexec/mysql-wait-stop
`# Give a reasonable amount of time for the server to start up/shut down`
TimeoutSec=300
`# Place temp files in a secure directory, not /tmp`
PrivateTmp=true
Restart=on-failure
RestartPreventExitStatus=1
`# Sets open_files_limit`
LimitNOFILE = 10000
`# Set enviroment variable MYSQLD_PARENT_PID. This is required for SQL restart command.`
Environment=MYSQLD_PARENT_PID=1
[Install]
WantedBy=multi-user.target
如您所见,Restart 参数的值设置为 on-failure。这意味着 MySQL 服务将因不干净的退出代码或超时而重新启动。
systemd 服务的手册页显示了下表中的重启参数:
重启设置/退出原因 | 不 | 总是 | 成功 | 失败时 | 异常 | 中止 | 看门狗 |
---|---|---|---|---|---|---|---|
清除退出代码或信号 | X | X | |||||
不干净的退出代码 | X | X | |||||
不干净的信号 | X | X | X | X | |||
超时 | X | X | X | ||||
看门狗 | X | X | X | X |
在 systemd 服务单元文件中,两个参数 –Restart
和RestartSec
– 控制崩溃行为。第一个参数指定服务应该何时重新启动,第二个参数定义在重新启动之前应该等待多长时间。
要测试崩溃行为,请使用 kill -9 信号停止 MySQL 进程。在我们的例子中,主 PID 是 851;用您自己的 PID 替换 PID:
ps -ef | mysql
- sudo kill -9 851
等待几秒钟,然后检查状态:
- sudo systemctl status mysqld.service
输出将显示 MySQL 已使用新的 PID 重新启动(在我们的例子中,新的进程 ID 是 1513):
Output mysqld.service - MySQL 8.0 database server
Loaded: loaded (/usr/lib/systemd/system/mysqld.service; enabled; vendor preset: disabled)
Active: active (running) since Fri 2020-12-25 04:47:48 UTC; 55s ago
Process: 1420 ExecStopPost=/usr/libexec/mysql-wait-stop (code=exited, status=0/SUCCESS)
Process: 1559 ExecStartPost=/usr/libexec/mysql-check-upgrade (code=exited, status=0/SUCCESS)
Process: 1476 ExecStartPre=/usr/libexec/mysql-prepare-db-dir mysqld.service (code=exited, status=0/SUCCESS)Process: 1451 ExecStartPre=/usr/libexec/mysql-check-socket (code=exited, status=0/SUCCESS)
Main PID: 1513 (mysqld)
Status: "Server is operational"
...
接下来,重新打开单元文件:
- sudo vi /etc/systemd/system/multi-user.target.wants/mysqld.service
注释掉 MySQL 守护进程的单元文件中的 Restart 指令并保存它。这将禁用重启行为:
`# Restart=on-failure`
之后,重新加载 systemd 守护进程,然后重新启动 mysqld 服务:
- sudo systemctl daemon-reload
- sudo systemctl restart mysqld.service
您可以通过运行以下命令找到服务的主 PID:
- sudo systemctl status mysqld.service
Output. . .
Main PID: 1895 (mysqld)
使用该kill -9
命令,杀死您环境中 MySQL PID 的主 PID(我们在测试环境中使用 PID)。
sudo kill -9 1895
检查 MySQL 的状态:
- sudo systemctl status mysqld.service
它会显示服务失败:
Outputmysqld.service - MySQL 8.0 database server
Loaded: loaded (/usr/lib/systemd/system/mysqld.service; enabled; vendor preset: disabled)
Active: **failed** (Result: signal) since Fri 2020-12-25 05:07:22 UTC; 1min 14s ago
Process: 1976 ExecStopPost=/usr/libexec/mysql-wait-stop (code=exited, status=0/SUCCESS)
Process: 1940 ExecStartPost=/usr/libexec/mysql-check-upgrade (code=exited, status=0/SUCCESS)
Process: 1895 ExecStart=/usr/libexec/mysqld --basedir=/usr (code=killed, signal=KILL)
Process: 1858 ExecStartPre=/usr/libexec/mysql-prepare-db-dir mysqld.service (code=exited, status=0/SUCCESS
Process: 1833 ExecStartPre=/usr/libexec/mysql-check-socket (code=exited, status=0/SUCCESS)
Main PID: 1895 (code=**killed**, signal=KILL)
...
尝试多次查找服务状态。每次服务都会显示为failed
。
因此,我们模拟了服务停止且未恢复的崩溃。这是因为我们已经指示 systemd 在非正常停止后不要重新启动服务。如果编辑mysqld.service单元文件取消Restart参数的注释,保存,重新加载systemctl守护进程,最后重启服务,即可恢复正常功能。
这是您如何配置本机 systemd 服务以在崩溃后自动启动。您所要做的就是在服务单元文件的部分下为Restart
(和可选的RestartSec
)添加一个额外的指令[Service]
。
结论
在这个由两部分组成的系列中,您了解了 Linux 生态系统中使用的服务管理守护进程。然后,您探索了 systemd 的基础知识,并将这些基础知识应用于一个实际示例:配置数据库以在重启或崩溃后重新启动。如果您想了解有关 systemd 的更多信息,请考虑浏览我们关于使用systemctl
.