官网 greatsql.serviC++e
文件
[Unit]
Description=GreatSQL Server
Documentation=man:MySQLd(8)
Documentation=http://dev.mysql.com/doc/refman/en/using-systemd.HTML
After=network.target
After=syslog.target
[Install]
WantedBy=multi-user.target
[Service]
# 本文省略some limits
User=mysql
Group=mysql
Type=notify
TimeoutSec=10
PermissionsStartOnly=true
ExecStartPre=/usr/local/GreatSQL-8.0.32-27-Linux-glibc2.28-x86_64/bin/mysqld_pre_systemd
ExecStart=/usr/local/GreatSQL-8.0.32-27-Linux-glibc2.28-x86_64/bin/mysqld $MYSQLD_OPTS
EnvironmentFile=-/etc/sysconfig/mysql
Restart=on-failure
RestartPreventExitStatus=1
Environment=MYSQLD_PARENT_PID=1
PrivateTmp=false
上述服务文件中
MYSQLD_OPTS
、MYSQLD_PARENT_PID
的用途是什么?Type
和ExecStart
有什么关系?服务停止的逻辑是什么?TimeoutSec
超时会怎样?
[Service]
ExecStart=/data/svr/greatsql/bin/mysqld --defaults-file=/data/conf/greatsql4306.cnf $MYSQLD_OPTS
EnvironmentFile=-/data/conf/greatsql
MYSQLD_OPTS
是一个特殊的环境变量,用于在启动时向 MYSQLD 进程传递额外的命令行参数。适合需要动态调整参数的场景。
可以通过以下方式设置 MYSQLD_OPTS
# 设置
systemctl set-environment MYSQLD_OPTS="--general_log=1"
# 取消
systemctl unset-environment MYSQLD_OPTS
[Service]
Environment=MYSQLD_OPTS=--general_log=1
EnvironmentFile=-/data/conf/greatsql
[Service]
Environment=LD_PRELOAD=/usr/local/jemalloc-5.3.0/lib/libjemalloc.so
Environment=LD_PRELOAD=/data/svr/greatsql/lib/mysql/libjemalloc.so #覆盖之前同名的变量
Environment= #清空所有环境变量
如果同一变量被重复设置,后续的赋值会覆盖之前的值。如果将此选项赋值为空字符串,则会重置环境变量列表,之前的所有设置均失效。
[Service]
EnvironmentFile=-/etc/sysconfig/mysql #-表示忽略文件不存在错误
EnvironmentFile=-/data/conf/greatsql
EnvironmentFile= #清空所有待读取的文件
$ cat /data/conf/greatsql
LD_PRELOAD=/data/svr/greatsql/lib/mysql/libjemalloc.so
LD_LIBRARY_PATH=/data/svr/greatsql/lib
TZ=CST
MYSQLD_OPTS=--general_log=1 --port=4307
EnvironmentFile 可以设置多次,所有匹配的文件均会被读取。若将此选项赋值为空字符串,则会清空待读取的文件列表,之前所有设置均失效。
EnvironmentFile 按顺序依次读取,后加载的变量会覆盖之前的设定,且会覆盖 Environment 中的同名变量。
Environment、EnvironmentFile 在服务启动前解析,这些变量会被直接写入服务的环境变量列表,对所有后续命令(ExecStartPre、ExecStart、ExecStartPost)可见。
如果 EnvironmentFile 指定的文件在运行时动态生成,systemd 会尝试读取它,如果文件在读取时被修改,systemd 会使用最新的内容。
systemd 通过 fork-exec + cgroups 的机制创建并严格管理服务进程,确保所有进程均为其子进程。
- Uses fork() + execve() to spawn the new process:
- fork(): Creates a child process (a copy of the systemd parent).
- execve(): Overwrites the child process with the target binary.
- Assigns the process to a dedicated cgroup
- Ensures all child processes remain within the same cgroup.
- Enables resource limits and process tracking.
[Service]
Type=simple
ExecStart=/data/svr/greatsql/bin/mysqld --defaults-file=/data/conf/greatsql4306.cnf $MYSQLD_OPTS
如果 ExecStart 启动的命令以 daemon 模式运行,daemon 进程有一个瞬间退出的中间父进程,对应就是子进程。在子进程退出时,systemd 会将其从监控队列中踢掉,同时杀掉所有附属进程(杀进程的方式由 KillMode 控制)。
# KillMode=control-group
$ systemctl start db-4306
$ systemctl status db-4306
● db-4306.service - db-4306 Server
Loaded: loaded (/usr/lib/systemd/system/db-4306.service; enabled; vendor preset: disabled)
Active: inactive (dead) since Fri 2025-05-30 11:03:26 CST; 9s aGo
Process: 1914 ExecStart=/data/svr/greatsql/bin/mysqld --defaults-file=/data/conf/greatsql4306.cnf --daemonize $MYSQLD_OPTS (code=exited, status=0/SUCCESS)
Main PID: 1914 (code=exited, status=0/SUCCESS)
Jun 05 11:03:22 dbcluster-165 systemd[1]: Started db-4306 Server.
$ ps aux |grep 4306 |grep -v grep
Type=simple,执行 daemon 命令,默认启动后马上会停止。
[Service]
Type=forking
PIDFile=/data/dbdata/data4306/data/mysql.pid
ExecStart=/data/svr/greatsql/bin/mysqld --defaults-file=/data/conf/greatsql4306.cnf --daemonize $MYSQLD_OPTS
以下是 forking 模式下正常启动的服务
$ systemctl status db-4306
● db-4306.service - db-4306 Server
Loaded: loaded (/usr/lib/systemd/system/db-4306.service; enabled; vendor preset: disabled)
Active: active (running) since Thu 2025-05-29 22:28:03 CST; 11s ago
Process: 24262 ExecStart=/data/svr/greatsql/bin/mysqld --defaults-file=/data/conf/greatsql4306.cnf --daemonize $MYSQLD_OPTS (code=exited, status=0/SUCCESS)
Main PID: 24342 (mysqld)
Tasks: 54
CGroup: /system.slice/db-4306.service
└─24342 /data/svr/greatsql/bin/mysqld --defaults-file=/data/conf/greatsql4306.cnf --daemonize
May 29 22:28:01 dbcluster-165 systemd[1]: Starting db-4306 Server...
May 29 22:28:03 dbcluster-165 systemd[1]: Started db-4306 Server.
ExecStart 启动的进程 PID=24262,且该进程的状态是已退出,退出状态码为0,这个进程是 daemon 类进程创建过程中瞬间退出的中间父进程。Main PID: 24342 (MySQLd),这是 systemd 真正监控的服务主进程。
如果 ExecStart 是一个前台命令,systemd 会一直等待 ExecStart 启动的进程作为中间父进程退出,在等待过程中,systemctl start 会一直卡住,直到等待超时而失败。
[Service]
ExecStart=/data/svr/greatsql/bin/mysqld --defaults-file=/data/conf/greatsql4306.cnf $MYSQLD_OPTS
EnvironmentFile=-/data/conf/greatsql
0
Type=forking,执行前台命令,在Restart=on-failure场景,启动超时导致服务反复重启。
[Service]
ExecStart=/data/svr/greatsql/bin/mysqld --defaults-file=/data/conf/greatsql4306.cnf $MYSQLD_OPTS
EnvironmentFile=-/data/conf/greatsql
1
当使用 mysqld_safe 启动数据库时,ps 可以看到 mysqld 进程带有很多变量
[Service]
ExecStart=/data/svr/greatsql/bin/mysqld --defaults-file=/data/conf/greatsql4306.cnf $MYSQLD_OPTS
EnvironmentFile=-/data/conf/greatsql
2
mysqld_safe 处理逻辑如下
[Service]
ExecStart=/data/svr/greatsql/bin/mysqld --defaults-file=/data/conf/greatsql4306.cnf $MYSQLD_OPTS
EnvironmentFile=-/data/conf/greatsql
3
对于 systemd service,可以添加 ExecStartPre,从 --defaults-file
中获取需要显示的变量
[Service]
ExecStart=/data/svr/greatsql/bin/mysqld --defaults-file=/data/conf/greatsql4306.cnf $MYSQLD_OPTS
EnvironmentFile=-/data/conf/greatsql
4
对于开机自动启动,如果磁盘挂载服务启动较慢,数据库服务可能会报错,可以配置数据库服务延迟启动
[Service]
ExecStart=/data/svr/greatsql/bin/mysqld --defaults-file=/data/conf/greatsql4306.cnf $MYSQLD_OPTS
EnvironmentFile=-/data/conf/greatsql
5
服务日志如下
[Service]
ExecStart=/data/svr/greatsql/bin/mysqld --defaults-file=/data/conf/greatsql4306.cnf $MYSQLD_OPTS
EnvironmentFile=-/data/conf/greatsql
6
systemctl status
中 ERROR 的原因:执行 ExecStartPre 会加载服务的环境变量,此时由于磁盘挂载暂未完成,导致 so 文件无法加载(这一条 ERROR 可以忽略)。只要延迟足够,在磁盘挂载完成后再执行 ExecStart,就能正常加载配置的 so 文件。
对于版本升级等场景,通常会设置 innodb_fast_shutdown=0,此时关闭数据库会比较慢,如果 TimeoutStopSec 过小,可能导致 ExecStop、SIGTERM 超时,触发 SIGKILL。
[Service]
ExecStart=/data/svr/greatsql/bin/mysqld --defaults-file=/data/conf/greatsql4306.cnf $MYSQLD_OPTS
EnvironmentFile=-/data/conf/greatsql
7
[Service]
ExecStart=/data/svr/greatsql/bin/mysqld --defaults-file=/data/conf/greatsql4306.cnf $MYSQLD_OPTS
EnvironmentFile=-/data/conf/greatsql
8
systemctl stop 超时(ExecStop、SIGTERM),服务会被 SIGKILL。systemd 认为是一个预期的行为,不会触发重启。
[Service]
ExecStart=/data/svr/greatsql/bin/mysqld --defaults-file=/data/conf/greatsql4306.cnf $MYSQLD_OPTS
EnvironmentFile=-/data/conf/greatsql
9
systemd 对所有通过它管理的服务都实施完整的生命周期控制。当执行 shutdown 时,信号传递链:shutdown --> 数据库服务 --> systemd 服务管理器。systemd 会监控整个停止过程。
# 设置
systemctl set-environment MYSQLD_OPTS="--general_log=1"
# 取消
systemctl unset-environment MYSQLD_OPTS
0
SIGTERM 超时,发送 SIGKILL 强制终止,进程退出原因是 Unclean signal。在 Restart=on-failure 场景,等待 RestartSec(默认100ms)后重启。
命令行 shutdown 超时(SIGTERM),服务会被 SIGKILL,之后会触发重启。
如果要禁用 systemd 的默认停止行为,可以参考如下设置
# 设置
systemctl set-environment MYSQLD_OPTS="--general_log=1"
# 取消
systemctl unset-environment MYSQLD_OPTS
1
Configures whether the service shall be restarted when the service process exits, is killed, or a timeout is reached. The service process may be the main service process, but it may also be one of the processes specified with ExecStartPre=, ExecStartPost=, ExecStop=, ExecStopPost=, or ExecReload=. When the death of the process is a result of systemd operation (e.g. service stop or restart), the service will not be restarted. Timeouts include missing the watchdog "keep-alive ping" deadline and a service start, reload, and stop operation timeouts.
Restart settings/Exit causes | no | always | on-success | on-failure | on-abnormal | on-abort | on-watchdog |
---|---|---|---|---|---|---|---|
Clean exit code or signal | X | X | |||||
Unclean exit code | X | X | |||||
Unclean signal | X | X | X | X | |||
Timeout | X | X | X | ||||
Watchdog | X | X | X | X |
A clean exit means an exit code of 0, or one of the signals SIGHUP, SIGINT, SIGTERM or SIGPIPE, and additionally, exit statuses and signals specified in SuccessExitStatus=.
# 设置
systemctl set-environment MYSQLD_OPTS="--general_log=1"
# 取消
systemctl unset-environment MYSQLD_OPTS
2
原因:没有设置相关的监控进程(https://dev.mysql.com/doc/refman/8.0/en/restart.html)
# 设置
systemctl set-environment MYSQLD_OPTS="--general_log=1"
# 取消
systemctl unset-environment MYSQLD_OPTS
3
# 设置
systemctl set-environment MYSQLD_OPTS="--general_log=1"
# 取消
systemctl unset-environment MYSQLD_OPTS
4
# 设置
systemctl set-environment MYSQLD_OPTS="--general_log=1"
# 取消
systemctl unset-environment MYSQLD_OPTS
5
# 设置
systemctl set-environment MYSQLD_OPTS="--general_log=1"
# 取消
systemctl unset-environment MYSQLD_OPTS
6
如果要求不重启数据库就能执行 restart 命令,可通过 gdb 动态修改环境变量,gdb 会短时间阻塞数据库
# 设置 systemctl set-environment MYSQLD_OPTS="--general_log=1" # 取消 systemctl unset-environment MYSQLD_OPTS
7
clone 同样需要设置 MYSQLD_PARENT_PID,才能自动重启。
ReStartSec:重启条件满足后等多久自动重启
StartLimitInterval、StartLimitBurst:限制指定时间内(StartLimitInterval)重启的次数(StartLimitBurst)
RestartPreventExitStatus:指定某些退出状态码或信号不重启。GreatSQL服务建议设置为1,在遇到严重错误时不重启实例,需人工介入处理
RestartForceExitStatus:强制将某些退出状态码或信号重启。比如 Restart=no,RestartForceExitStatus=16,则不依赖自动重启,但命令行执行 restart 可正常重启实例
Enjoy GreatSQL
GreatSQL是适用于金融级应用的国内自主开源数据库,具备高性能、高可靠、高易用性、高安全等多个核心特性,可以作为MySQL或Percona Server的可选替换,用于线上生产环境,且完全免费并兼容MySQL或Percona Server。
相关链接: GreatSQL社区 Gitee GitHub Bilibili
社区博客有奖征稿详情:https://greatsql.cn/thread-100-1-1.html
微信:扫码添加
GreatSQL社区助手
微信好友,发送验证信息加群
。