使用systemctl启动mysql,不使用mysqld_safe

【1】service 启动 mysql

我相信大多数专业的新手 DBA 都是用二进制部署法部署 MySQL 的,在部署 MySQL 时我们会给 MySQL 制作启动服务,按官方提供的方法,就是

cp support-files/mysql.server /etc/init.d/mysql

chmod +x /etc/init.d/mysql

chkconfig --add mysql

chkconfig --level 345 mysql on

这非常简单,相信也是大多数新手 DBA 使用的方法。

mysql.server 是 MySQL 的启动脚本,原理上是调用另外一个叫做 mysqld_safe 的 shell 脚本拉起 mysqld,mysqld_safe 是 mysqld 服务的守护进程,他保证了 mysqld 挂了后会自动被拉起来。mysqld_safe 是本文我们要讨论的主角,我为什么不用 mysqld_safe?

按照上述的配置后,用的是老的 CentOS/RHEL6 系列的玩法,采用 service mysql start 的方式来启动 mysqld 服务。

在 CentOS/RHEL7 系列也支持,如下

[root@fander ~]# cat /etc/redhat-release 
CentOS Linux release 7.5.1804 (Core)
[root@fander ~]# service mysql start
Starting MySQL(mysql).. SUCCESS!

【2】我为什么不用 mysqld_safe?

核心原因其实很简单,就是没有必要。

CentOS/RHEL6 服务的守护是需要你自己实现的,而 CentOS/RHEL7 支持 systemd,他能提供服务的守护能力。而我们用的就是 CentOS/RHEL7 服务器。

On platforms for which systemd support for MySQL is installed, scripts such as mysqld_safe and the System V initialization script are unnecessary and are not installed.

以上截取自 MySQL 官方文档,意思是支持 systemd 平台没有必要使用 mysqld_safe

mysqld_safe Because systemd has the capability of managing multiple MySQL instances on platforms for which systemd support for MySQL is installed, mysqld_multi and mysqld_multi.server are unnecessary and are not installed.

除此之外,因为 systemd 支持 MySQL 多实例的管理,mysqld_multi、mysqld_multi.server 也是没有必要使用了。

在 CentOS/RHEL7 系统上,systemd 和 mysqld_safe 都能支持对 mysqld 的守护,那谁更好呢?

先说答案,是 systemd,所以我建议大家不用 mysqld_safe。

【3】mysqld_safe 的缺点

  1. 无限重启 mysqld。

mysqld_safe 在发现 mysqld 挂了后会马上拉起他,挂了后又马上拉起,如果你遇到某个坏块导致 mysqld 在拉起过程中又挂了,或者遇到某个 bug 导致 mysql 运行几分钟后马上会挂,那么无限拉起 mysqld 是不合适的。因为可能:

  • 告警风暴。mysqld 挂->恢复->挂->恢复,如此循环

  • 无法告警。如果你的探活机制间隔太长,有可能永远不会告警

  • 高可用不切换。在某些高可用架构,我们称之为"重启优先于切换"的架构玩法中,因为其探活机制问题,无限拉起 mysqld,可能会导致不能触发高可用切换

  1. mysqld_safe 是 shell 脚本进程,他也会挂,你可能要单独监控他

【4】systemd 的优点

  1. 标准,可以和管理别的服务一样管理 mysqld 服务。

  2. 更强大的功能,systemd 的功能是很强大的 请看一下我的 mysql3306.service 服务配置,能实现不无限重启 mysqld

[root@fander ~]# cat /usr/lib/systemd/system/mysql3306.service
[Unit]
Description=MySQL 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]
User=mysql
Group=mysql
ExecStart=/database/mysql/base/5.7.38/bin/mysqld --defaults-file=/database/mysql/etc/3306/my.cnf
LimitNOFILE = 65536
Restart=on-failure # 重启条件
RestartPreventExitStatus=1 # 退出码为1不重启,即正常shutdown
ReStartSec=10 # 重启条件满足后等多久自动重启(秒)
StartLimitInterval=300 # 五分钟内只能重启两次,第三次不重启了
StartLimitBurst=2 # 五分钟内只能重启两次,第三次不重启了
TimeoutStartSec=30 # 服务启动的超时时间,单位秒
TimeoutStopSec=30 # 服务关闭的超时时间,单位秒

 

相信大家都看懂了,我这里的特殊玩法是,我把我的 mysql 做到了发生故障时会自动重启,但五分钟之内不能重启超过两次。

这样理论上还可以配合"重启优先于切换"的高可用架构玩法,在主库 mysqld 挂了后先尝试重启三次,第三次还是失败的话则主从切换。

当然了,仅仅一些抛砖引玉的玩法思路,你都自己写高可用逻辑了,你也可以让高可用软件的 agent去做重启动作,不是用原生的 systemd 实现。更多的 systemd 设置玩法请自行探索。

 

若是要配合 centos下使用jemalloc解决Mysql内泄漏的问题 ,则可以修改成如下(无法解决00M)

vi /usr/lib/systemd/system/mysql3306.service
在[Service]里加入一行:
Environment="LD_PRELOAD=/usr/lib64/libjemalloc.so.1"
systemctl daemon-reload

 

【参考文档】

转自:https://mp.weixin.qq.com/s/Tmqu7jn6d8nxw5K9N0I6Jg

posted @ 2022-11-17 15:17  郭大侠1  阅读(806)  评论(0编辑  收藏  举报