MySQL 通过 systemd 启动时 hang 住了……
mysqld:哥,我起不来了……
作者:贲绍华,爱可生研发中心工程师,负责项目的需求与维护工作。其他身份:柯基铲屎官。
爱可生开源社区出品,原创内容未经授权不得随意使用,转载请联系小编并注明来源。
本文约 2100 字,预计阅读需要 7 分钟。
引言
正如题目所述,在自动化测试场景下,通过 systemd 无法启动 MySQL。
连续 kill -9
结束实例进程,检测 mysqld 在退出后是否会被正确拉起。
具体信息如下:
- 主机信息:CentOS 8(Docker 容器)
- 使用 systemd 的方式管理 mysqld 进程
- systemd service 的运行模式为:forking
- 启动命令如下:
# systemd 启动命令
sudo -S systemctl start mysqld_11690.service# systemd service 内的 ExecStart 启动命令
/opt/mysql/base/8.0.34/bin/mysqld --defaults-file=/opt/mysql/etc/11690/my.cnf --daemonize --pid-file=/opt/mysql/data/11690/mysqld.pid --user=actiontech-mysql --socket=/opt/mysql/data/11690/mysqld.sock --port=11690
现象描述
启动命令持续 hang 住,既不成功,也无任何返回,尝试几次后均无法手动复现该场景。
下图为复现场景,service 端口号不一致请忽略。
MySQL 错误日志无任何信息。查看 systemd service 状态,发现启动脚本中由于缺少参数 MAIN PID
,执行失败。
systemd 最后输出的信息为:New main PID 31036 does not exist or is a zombie
原因总结
systemd 启动 mysqld 的过程中,会先根据 service 模板中的配置,执行:
- ExecStart(启动 mysqld)
- mysqld 启动创建
pid
文件 - ExecStartPost(自定义的一些后置脚本:调整权限、将
pid
写入 cgroup 等)
在 步骤 2-3 的中间态,也就是 pid
文件刚创建出来时,主机上接收到了自动化测试下发的命令:sudo -S kill -9 $(cat /opt/mysql/data/11690/mysqld.pid)
。
由于这个 pid
文件和 pid
进程确实存在(如果不存在 kill
命令或 cat
会报错),自动化的 CASE 认为 kill
操作已成功结束。但由于 mysqld.pid
这个文件是由 MySQL 自身维护的,在 systemd 的视角中,还需要继续等待 步骤 3 完成,才认为启动成功。
在 systemd 使用 forking 模式时,会根据子进程的 PID
值判断服务是否成功启动。
如果子进程成功启动,并且没有发生意外退出,则 systemd 会认为服务已启动,并将子进程的 PID
作为 MAIN PID
。
而如果子进程启动失败或意外退出,则 systemd 会认为服务未能成功启动。
结论
在执行 ExecStartPost 时,由于子进程 ID 31036 已经被 kill
掉,后置 shell
缺少了启动参数,但 ExecStart 步骤已完成,导致 MAIN PID 31036 成为了只存在于 systemd 里的 僵尸进程。
排查过程
当遇到这个问题时是有点懵的,简单检查了一下内存、磁盘基本信息。符合预期并没有出现资源不足的情况。
先从 MySQL 的 Error Log 看看有什么发现。查看结果如下:
...无关内容省略...
2024-02-05T05:08:42.538326+08:00 0 [Warning] [MY-010539] [Repl] Recovery from source pos 3943309 and file mysql-bin.000001 for channel ''. Previous relay log pos and relay log file had been set to 4, /opt/mysql/log/relaylog/11690/mysql-relay.000004 respectively.
2024-02-05T05:08:42.548513+08:00 0 [System] [MY-010931] [Server] /opt/mysql/base/8.0.34/bin/mysqld: ready for connections. Version: '8.0.34' socket: '/opt/mysql/data/11690/mysqld.sock' port: 11690 MySQL Community Server - GPL.
2024-02-05T05:08:42.548633+08:00 0 [System] [MY-013292] [Server] Admin interface ready for connections, address: '127.0.0.1' port: 6114
2024-02-05T05:08:42.548620+08:00 5 [Note] [MY-010051] [Server] Event Scheduler: scheduler thread started with id 5
通过观察 Error Log 发现并无任何有用信息,因为启动的时间点之后无任何日志信息输出。
查看 systemctl status 确认服务当前状态:
下图为正常情况下的 status 信息:
通过对比后,整理两条有用信息:
- 后置
shell
由于缺少-p
参数导致执行失败(-p
参数为MAIN PID
,也就是 fork 子进程启动后的PID
)。 - systemd 无法获取
PID 31036
,不存在或者为僵尸进程。
先来检查进程 ID
与 mysqld.pid
看看:
确认线索:
PID 31036
不存在mysqld.pid
文件存在,且文件内容为 31036top
命令查看不存在僵尸进程
还需要获取更多的线索来确认原因,检查 journalctl -u
内容,看看是否有帮助:
sh-4.4# journalctl -u mysqld_11690.service
-- Logs begin at Mon 2024-02-05 04:00:35 CST, end at Mon 2024-02-05 17:08:01 CST. --
Feb 05 05:07:54 udp-11 systemd[1]: Starting MySQL Server...
Feb 05 05:07:56 udp-11 systemd[1]: Started MySQL Server.
Feb 05 05:08:31 udp-11 systemd[1]: mysqld_11690.service: Main process exited, code=killed, status=9/KILL
Feb 05 05:08:31 udp-11 systemd[1]: mysqld_11690.service: Failed with result 'signal'.
Feb 05 05:08:32 udp-11 systemd[1]: Starting MySQL Server...
Feb 05 05:08:36 udp-11 systemd[1]: Started MySQL Server.
Feb 05 05:08:37 udp-11 systemd[1]: mysqld_11690.service: Main process exited, code=killed, status=9/KILL
Feb 05 05:08:37 udp-11 systemd[1]: mysqld_11690.service: Failed with result 'signal'.
Feb 05 05:08:39 udp-11 systemd[1]: Starting MySQL Server...
Feb 05 05:08:42 udp-11 u_set_iops.sh[31507]: /etc/systemd/system/mysqld_11690.service.d/u_set_iops.sh: option requires an argument -- p
Feb 05 05:08:42 udp-11 systemd[1]: mysqld_11690.service: New main PID 31036 does not exist or is a zombie.
这里的 journalctl -u
内容也只描述了现象,无法分析具体原因,与 systemctl status 的内容相差不多,帮助不大。
查看 /var/log/messages
系统日志内容:
发现循环报出了一些内存方面的错误信息,通过搜索后发现该错误可能为硬件问题。询问了自动化测试的同事后,得到结论:
- 场景为偶发问题,执行 4 次用例,2 次成功,2 次失败
- 每次执行均为同一台宿主机,同一份容器镜像
- 失败时 hang 住的容器为同一个
既然有成功执行的结果,这里就先忽略硬件问题导致的。
既然提到了容器,此时想到了 cgroup 会不会映射宿主机的时候出现了问题?在上边排查的 systemctl status 中,观察可知 cgroup 映射的宿主机目录为:CGroup: /docker/3a72b2cdc7bd9beb1c7b2abec24763046604602a38f0fcb7406d17f5d33353d2/system.slice/mysqld_11690.service
检查父级文件夹 system.slice
的读写权限并无异常。先暂时排除 cgroup 的映射问题(因为主机上还有其他 systemd 接管的 service 也在使用同一份 cgroup)。
打算试试 pstack 能不能看到 systemd 具体 hang 在了哪个地方,3048143
为 systemctl start 的 pid
:
sh-4.4# pstack 3048143
#0 0x00007fdfaef33ade in ppoll () from /lib64/libc.so.6
#1 0x00007fdfaf7768ee in bus_poll () from /usr/lib/systemd/libsystemd-shared-239.so
#2 0x00007fdfaf6a8f3d in bus_wait_for_jobs () from /usr/lib/systemd/libsystemd-shared-239.so
#3 0x000055b4c2d59b2e in start_unit ()
#4 0x00007fdfaf7457e3 in dispatch_verb () from /usr/lib/systemd/libsystemd-shared-239.so
#5 0x000055b4c2d4c2b4 in main ()
观察发现 start_unit 比较可疑,start_unit()
函数位于可执行文件中,它用于启动 systemd units,并没有什么帮助。
根据已有线索,推测后可知:
mysqld.pid
文件存在,则表示之前确实有一个 mysqld 且进程号为31036
的进程被启动了- 进程启动后被自动化用例
kill -9
结束掉 - systemd 获取到了一个已经被结束的
MAIN PID
,后置 shell 执行失败,fork 流程失败
通过梳理 systemd 启动流程的步骤,推测可能性。MySQL 实例只有在 mysqld 成功启动后才会生成 mysqld.pid
文件,所以可能是在后续步骤里被意外 kill -9
结束掉导致的。
复现方式
既然没什么其他头绪和线索了,打算根据推测结论尝试复现一下试试。
4.1 调整 systemd mysql serivce 模板
编辑模板文件 /etc/systemd/system/mysqld_11690.service
,在 mysqld 启动后,sleep10
秒,方便在这时间窗口内模拟kill掉实例进程的场景。
4.2 配置重载
执行 systemctl daemon-reload
令变更生效。
4.3 场景重现
- [ssh seesion A] 首先准备一个新的容器,做好相关配置后执行
sudo -S systemctl start mysqld_11690.service
启动一个 mysqld 进程,此时会因为sleep
的原因 hang 住会话。 - [ssh seesion B] 在另一个会话窗口,
start
命令 hang 住时,检查mysqld.pid
文件,一旦文件被创建后,立刻执行sudo -S kill -9 $(cat /opt/mysql/data/11690/mysqld.pid)
。 - 此时观察 systemctl status,表现与预期一致
解决方式
先 kill
掉 hang 住的 systemctl start 命令,执行 systemctl stop mysqld_11690.service
,这可以让 systemd 主动结束僵尸进程,虽然 stop
命令可能会报错但这并不影响。
等待 stop
执行完成后再次使用 start
命令启动,恢复正常。
更多技术文章,请访问:https://opensource.actionsky.com/
关于 SQLE
SQLE 是一款全方位的 SQL 质量管理平台,覆盖开发至生产环境的 SQL 审核和管理。支持主流的开源、商业、国产数据库,为开发和运维提供流程自动化能力,提升上线效率,提高数据质量。
SQLE 获取
类型 | 地址 |
---|---|
版本库 | https://github.com/actiontech/sqle |
文档 | https://actiontech.github.io/sqle-docs/ |
发布信息 | https://github.com/actiontech/sqle/releases |
数据审核插件开发文档 | https://actiontech.github.io/sqle-docs/docs/dev-manual/plugins/howtouse |
相关文章:

MySQL 通过 systemd 启动时 hang 住了……
mysqld:哥,我起不来了…… 作者:贲绍华,爱可生研发中心工程师,负责项目的需求与维护工作。其他身份:柯基铲屎官。 爱可生开源社区出品,原创内容未经授权不得随意使用,转载请联系小编…...

pat乙1033-旧键盘打字
1测试点2: 输入的字符串如果为空,要用getline(cin,s),而不是cin>>s,否则程序做不了 2题目说的如果上键坏了那大写字母打印不了,不是大写转小写打印啦,认真读题 3两个for循环长这样,break…...

Ubuntu安装VScode
Ubuntu安装VScode 前言: 1、Ubuntu安装VScode比较方便 2、我更喜欢source insight 1、获取到linux版本的VScode安装包 VSCode 下载地址是:https://code.visualstudio.com/ 2、得到安装包 3、复制到ubuntu中,使用命令安装 sudo dpkg -i cod…...

c# - - - winform程序四个角添加圆角效果
winform 给窗体四个角添加圆角效果。 在窗体 Load 事件中添加如下代码: // 创建了一个圆角矩形的路径,并将其设置为控件的形状 System.Drawing.Drawing2D.GraphicsPath path new System.Drawing.Drawing2D.GraphicsPath(); int radius 30; path.AddAr…...

Springboot 集成 Consul 实现服务注册中心-05
因为后续很多模块都要用到注册中心,所以此处先实现此模块。 Consul简介 Consul是一个开源的服务发现和配置管理工具,具有跨平台、运行高效等特点。它由HashiCorp公司开发,并使用Go语言编写。Consul主要用于实现分布式系统中的服务发现、健康…...

【软考高项】四十六、项目管理科学计算之运筹学
1、线性规划问题 解题思路: 先把文字转化成图表 最快方式应该是把第一题的4个答案直接代入计算,很快得知X2时利润最大。 A0时,利润5*630 A2时,利润2*25*634 A4时,利润4*23*523 A6时,利润4*2(因为甲的…...

使用 Python 和 OpenCV 进行实时目标检测的详解
使用到的模型文件我已经上传了,但是不知道能否通过审核,无法通过审核的话,就只能 靠大家自己发挥实力了,^_^ 目录 简介 代码介绍 代码拆解讲解 1.首先,让我们导入需要用到的库: 2.然后,设…...

Android build.prop生成过程源码分析
Android的build.prop文件是在Android编译时刻收集的各种property【LCD density/语言/编译时间, etc.】;编译完成之后,文件生成在out/target/product/<board【OK1000】>/system/目录下;在Android运行时刻可以通过property_get()[c/c域] …...

计算机网络教材——谢希仁教材与配套PPT课件和《计算机网络——自顶向下方法》
教材链接: https://pan.baidu.com/s/1MUkgTVNMvhFdkGxAd0U7Ew?pwdn3g4 提取码: n3g4 ppt资源:课程包列表 (51zhy.cn) 计算机网络——自顶向下方法(资源在下面的评论区里):计算机网络自顶向下方法第7版中文PDF习题参考 - 哔哩哔…...

mysql 离线安装
package download mysql https://dev.mysql.com/downloads/mysql/ libaio http://mirror.centos.org/centos/7/os/x86_64/Packages/libaio-0.3.109-13.el7.x86_64.rpm 根据自己服务器选择下载对应的安装包及依赖 删除本机自带mysql相关 # 首先排查服务器自身是否有安装对应m…...

【C++】 string类:应用与实践
💞💞 前言 hello hello~ ,这里是大耳朵土土垚~💖💖 ,欢迎大家点赞🥳🥳关注💥💥收藏🌹🌹🌹 💥个人主页&#x…...

巩固学习7
正则表达式 就是用来找到符合模式的字符串,这些模式包括:是什么字符,重复多少次,在什么位置,有哪些额外的约束 找某个字符串 import re text身高:178 体重:168 学号:123456 密码:9527 #在Python中,r前缀用…...

Android 右键 new AIDL 无法选择
提示 (AIDL File)Requires setting the buildFeatures.aidl to true in the build file) 解决方式: 在app的build.gradl中 adnroid{} 添加: buildFeatures{aidl true}...

使用Springboot整合Elasticsearch
全文搜索引擎 全文搜索引擎是目前广泛应用的主流搜索引擎,也称为全文检索。它的工作原理是计算机索引程序通过扫描文章中的每一个词,对每一个词建立一个索引,指明该词在文章中出现的次数和位置,当用户查询时,检索程序…...

Vue3+Element+TS动态菜单+按钮权限控制实现探索
1.动态获取权限并根据获取权限转换成相对应的router 根据请求获取菜单数据,对菜单数据进行转换,分别进行下面几步: /*** 组件地址前加斜杠处理*/ export function addSlashToRouteComponent(routeList: AppRouteRecordRaw[]) {routeList.fo…...

五款公司源代码加密软件推荐|代码防泄密解决方案
在当今数字化的世界中,源代码的泄露无疑是一场灾难。对于依赖加密软件保护关键信息的企业和个人来说,这种泄露不仅可能导致数据失窃,还可能损害企业的声誉和客户的信任。面对这种严峻的形势,我们迫切需要一种全面而有效的加密软件…...

【spring】Security 密码加密算法
Spring Security 提供了多种密码加密算法,用于在存储用户密码时进行加密,以增强安全性。 查看org.springframework.security.crypto.factory.PasswordEncoderFactories 以下是一些常用的密码加密算法: BCryptPasswordEncoder: 这…...

IO系列(一) -一文带你读懂 java 中的IO流!
一、摘要 说到 IO,相信大家都不陌生,英文全称:Input/Output,即输入/输出,通常指数据在内部存储器和外部存储器或其他周边设备之间的输入和输出。 比如我们常用的SD卡、U盘、移动硬盘等等存储文件的硬件设备ÿ…...

代码随想录算法训练营第六天| 242. 有效的字母异位词、349. 两个数组的交集、202. 快乐数、1. 两数之和
哈希表理论基础 [LeetCode] 242. 有效的字母异位词 [LeetCode] 242. 有效的字母异位词 文章解释 [LeetCode] 242. 有效的字母异位词 视频解释 题目: 给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。 注意:若 s 和 t 中每个字符出…...

【python】中的可迭代对象、迭代器、生成器
结论 凡是实现了__iter__() 方法的类都称之为可迭代对象,但 __iter__() 方法的返回值只能是迭代器和生成器for 循环的本质是先调用 __iter__() 方法,然后不断调用返回值的 __next__() 方法,直至报出异常 StopIteration,可迭代对象…...

短视频矩阵系统源码/saas--总后台端、商户端、代理端、源头开发
短视频矩阵系统源码/saas--总后台端、商户端、代理端、源头开发 搭建短视频矩阵系统源码的交付步骤可以概括为以下几个关键环节: 1. **系统需求分析**:明确系统需要支持的功能,如短视频的上传、存储、播放、分享、评论、点赞等。 2. **技术选…...

K8s:二进制安装k8s(单台master)
目录 一、安装k8s 1、拓扑图 2、系统初始化配置 2.1关闭防火墙selinx以及swap 2.2设置主机名 2.3在每台主机中添加hosts,做映射 2.4调整内核参数,将桥接的ipv4流量传递到iptables,关闭ipv6 2.4时间同步 3、部署docker引擎࿰…...

C++类和对象下——实现日期类
前言 在学习了类和对象的六大成员函数后,为了巩固我们学习的知识可以手写一个日期类来帮助我们理解类和对象,加深对于其的了解。 默认函数 构造函数 既然是写类和对象,我们首先就要定义一个类,然后根据实际需要来加入类的数据与函…...

252 基于MATLAB的自适应差分阈值法检测心电信号的QRS波
基于MATLAB的自适应差分阈值法检测心电信号的QRS波,QRS波群反映左、右心室除极电位和时间的变化,第一个向下的波为Q波,向上的波为R波,接着向下的波是S波。通过GUI进行数据处理,展示心率和QRS。程序已调通,可…...

SSIM(Structural Similarity),结构相似性及MATLAB实现
参考文献 Wang, Zhou; Bovik, A.C.; Sheikh, H.R.; Simoncelli, E.P. (2004-04-01). “Image quality assessment: from error visibility to structural similarity”. IEEE Transactions on Image Processing. 13 (4): 600–612. Bibcode:2004ITIP…13…600W. CiteSeerX 10.…...

第十六章-消费者-PUSH方式(一)
16.1 准备阶段 先从一段官方示例代码开始 public class Consumer {public static void main(String[] args) throws InterruptedException, MQClientException {// 初始化consumer,并设置consumer group nameDefaultMQPushConsumer consumer new DefaultMQPushCo…...

【C++要哮着学】初识C++,什么是C++?什么是命名空间?什么又是缺省函数?
文章目录 前言1、C简介1.1、什么是C1.2、C起源1.3、C发展 2、C关键字(C98)3、命名空间3.1、命名空间的定义及使用3.2、命名空间的嵌套3.3、命名空间的三种使用方式3.3.1、加命名空间名称及作用域限定符3.3.2、使用using将命名空间中某个成员引入3.3.3、使…...

Lua 数字格式化
在编程中,对数字进行格式化是一项常见的任务,特别是当我们需要在用户界面中显示数据或生成报告时。在 Lua 中,我们可以使用一些简单而有效的函数来实现数字的格式化。在本文中,我们将介绍一个由几个函数组成的小型 Lua 库…...

Java入门基础学习笔记13——数据类型
数据类型的分类: 基本数据类型 引用数据类型 基本数据类型:4大类8种类型: 定义整形用int,再大的数用long。 package cn.ensource.variable;public class VariableDemo2 {public static void main(String[] args) {//目标&#x…...

使用Docker+Jar方式部署微服务工程(前后端分离)看着一篇就够了
本篇教程的使用到的技术有springboot、springcloud、Nacos、Docker、Nginx部署前后端分离访问的微服务。 部署一下Nacos 首先我们需要在服务器中(或者本地部署启动一下Nacos),这里我采用服务器的方式进行部署,这里有一点不一样的…...