首页 > Sysadmin > 正文

数据库开机自启:先分清服务名再 enable

huyuanwen 2026-10-26 Sysadmin

自启靠的是软链接:enable 只把 unit 挂进 target 的 wants 目录,不会顺手起服务,服务名还容易认错。

先分清服务名:mysql、mysqld、mariadb

systemctl list-unit-files | grep -iE "mysql|maria"
systemctl is-active mariadb
systemctl status mariadb --no-pager

MySQL 官方文档的说法是:如果服务名不是 mysqld 就用对应的名字,Debian 系(含 Ubuntu)和 SLES 上应该用 mysql 而不是 mysqld [1]。按包文件核实过(只解包看内容,没有安装):Ubuntu noble 的 mysql-server-8.0 包里是 usr/lib/systemd/system/mysql.service,没有 mysqld.service;mariadb-server 包里是 mariadb.service,另外把 mysql.service、mysqld.service 做成指向它的软链接——所以 MariaDB 机器上 systemctl status mysql 也能查到,真正跑的是 mariadb.service。

还有一个容易踩的点:apt 里的 default-mysql-server 只是 metapackage,装哪个引擎由发行版决定,Ubuntu noble 的依赖是 mysql-server-8.0 [2],这条在 WSL 里用 apt-cache 查过(Debian 上的指向未在本机核实)。

enable 只建软链接,起服务是另一回事

手册的措辞很明确:enable 按 unit 文件的 Install 段建一组软链接,并且不会因此启动任何被 enable 的 unit,要同时起服务得加 --now 或之后再 start [3] [4]。同一份手册还强调 enabling 和 starting 是正交的 [4]。

systemctl enable mariadb
systemctl is-active mariadb        # 实测:这步仍是 inactive
systemctl enable --now mariadb
ls -l /etc/systemd/system/multi-user.target.wants/

实测结果和手册一致:单跑 enable 后 is-active 仍是 inactive,加 --now 才 active;软链接确实落在 multi-user.target.wants 下。注意没有 Install 段的 unit 状态是 static,用 systemctl enable 没有意义(实测提示 The unit files have no installation config)[3]。

顺带解释一个常见误解:这台机器 get-default 是 graphical.target,而包里的 Install 段写的是 WantedBy=multi-user.target,链接仍建在 multi-user 下——因为 graphical.target 会拉取 multi-user.target [5],实测 systemctl show graphical.target -p Requires 就是 multi-user.target,所以桌面默认 target 不影响数据库自启。

脚本判断状态别只靠退出码

systemctl is-enabled mariadb
test -L /etc/systemd/system/multi-user.target.wants/mariadb.service && echo "开机时会起"
journalctl -u mariadb -b --no-pager | head -10

手册的 is-enabled 状态表写着 disabled 的退出码大于 0 [3],但这台 WSL Ubuntu 24.04(systemd 255)上三次实测(直接跑、重定向到 /dev/null、mask 后)返回的都是 0。所以脚本里靠 $? 判断状态不可靠,看输出字符串或者 wants 目录里的软链接更稳。

真机重启这步没法在 WSL 里做:WSL 要先在 wsl.conf 的 boot 段打开 systemd(本机就是 true),但 wsl --shutdown 后重新进入不等于一次完整开机,所以”重启后自启”只能靠 restart + journalctl 核对,真机重启留在发布前待办。

改过配置必须 daemon-reload

MySQL 官方文档给的 drop-in 做法是:在 /etc/systemd/system/mysqld.service.d 下建 override 文件(Debian 系对应 mysql.service.d),改完 daemon-reload,再 restart [1]。

systemctl edit mariadb              # 交互式编辑,保存后生成 override.conf
systemctl daemon-reload
systemctl restart mariadb
systemctl cat mariadb | tail -5

实测一个容易忽略的差别:手工往 service.d 写文件后,systemctl cat 立刻能从磁盘读到新内容,但 systemctl show 的加载态在 daemon-reload 之前仍是旧的 ExecStart;reload 之后才变新值,restart 才真正用上。另外 systemctl edit 在这台机的 systemd 255 上没有 --stdin 选项(报 unrecognized option),脚本里只能手写文件再 reload。

排错速查表

| 现象 | 原因 | 处理 | |—|—|—| | status 显示 active,重启后没起 | 只 start 没 enable,或 unit 是 static | systemctl is-enabled + 看 wants 目录软链接 | | start 报 Unit is masked | 之前被 mask 过(mask 把 unit 指向 /dev/null,比 disable 更强)[4] | systemctl unmask 再 start | | mask 报 File already exists | unit 文件本来就在 /etc/systemd/system 里,mask 只能对包装在 /usr/lib 下的 unit 用 | 手册也说明了这一点,实测复现 [4] | | 服务名报错、查不到 unit | 用了 mysqld 但实际是 mysql 或 mariadb | 见第 1 节;MariaDB 包里两个名字都是软链接 | | 改完配置没生效 | 忘记 daemon-reload 或没 restart | systemctl daemon-reload && systemctl restart |

回滚、局限与常见问题

回滚:systemctl disable --now mariadb(实测会删掉 wants 软链接并停止服务)、删掉 service.d 里的 override 文件后 daemon-reload、mask 过的用 unmask 恢复。

FAQ:

  • enable 和 start 的区别?enable 只管开机那次挂载,start 只管当前这一次,两者正交 [4]。
  • 用 service 还是 systemctl?官方文档把 service 列为 systemctl 的替代命令,新部署建议直接用 systemctl [1]。
  • 配置文件里能设自启吗?my.cnf 没有开机自启选项,自启是 unit 层的事,配置和自启分开放。
  • 多实例怎么办?官方文档用 mysqld@.service / mysql@.service 模板,enable 时要写具体实例名 [1]。
  • 局限:真机重启、RPM 平台、SELinux、容器内 systemd 均未实测;包文件结论来自 dpkg-deb 解包查看。测试环境是 WSL Ubuntu 24.04.4(systemd 255.4),日期 2026-10-26,测试用的临时 unit 和已下载的包文件已清理。草稿待审;文中命令除”真机重启”相关外均已在 WSL 执行,选题骨架来自源站列表页摘要(源站文章正文被站点 WAF 拦截,未抓取)。

  • 参考资料

    文中主要命令已在 WSL Ubuntu(24.04)实测,个别条目(未装工具/安装类命令)仅核对官方文档,未实际执行。