一、问题描述
某次一线报某业务网站门户登录验证码获取失败;因该验证码是代码里通过验证码函数实现存入数据库,登录时再读取数据库里的验证码来实现包包里破解登录的;因此本次故障极大可能出现在数据库服务器故障。类似报错信息如下:
polkitd[551]: Registered Authentication Agent for unix-process:3986:1469369
……
Starting MySQL. ERROR! The server quit without updating PID file (/var/run/mysqld/mysqld.pid)
环境:Mysql 5.7.20
二、故障分析处理
1)登录数据库服务器master,发现mysqld进程确实挂掉了,但是重启mysqld时,报错:The server quit without updating PID file,mysql服务启动。
2)查看日志journalctl -xe里有类似报错:
上图中:该错误表示由于未注册unix进程的身份验证代理导致服务失败,并由polkitd服务报告。错误中的 polkitd 是一个系统守护进程,在系统消息总线上提供 D-Bus 服务。只要应用程序调用服务,dbus-daemon(1) 或 systemd(1) 就会自动启动它,用户或管理员是不需要启动这个守护进程的。只要将要启动的服务加入systemd管理,即自启动的程序加入到supervisor的启动配置中,启动时就会触发该守护进程,它的身份验证代理在程序启动之前验证用户的身份,比如本次案例中的,mysqld目录的属主身份;
3)检查/var/run/mysqld/mysqld.pid文件,发现/var/run/下竟然没有mysqld目录,正常不应该的,否则上次如何启动的呢?
先/var/run/下有mysqld目录,并赋予mysql属主/组权限,否则依然无法启动。完成后重新启动mysqld,这时启动成功。
4)关于/var/run/mysqld丢失的原因
相关经验表明这是mysql5.7的一个BUG,当你停止mysql服务时,/ var/run/mysqld会被删除,且/var/run/mysqld 目录每次重启后都需要手动去创建,是因为/var/run/目录下建立文件夹是在内存中,故每次重启后内存被清空导致/var/run/mysqld 也被清除,从而导致无法启动mysql。可尝试:
vim /etc/init.d/mysqld
将pid-file=/var/run/mysqld/mysqld.pid修改为 pid-file=/var/lib/mysqld/mysqld.pid
systemctl daemon-reload
chkconfig mysqld on
service mysqld start
三、附录
1)相关命令
mysqldump -u root -p --all-databases > /opt/mysql_db_bak/all_$(date +%F).sql
mysqladmin flush-hosts -h 172.31.71.11 -P 3306 -uroot -p
#添加mysql自启动
cp /usr/local/mysql/support-files/mysql.server /etc/init.d/mysqld
chmod +x /etc/init.d/mysqld
chkconfig --add mysqld
chkconfig --list mysqld
peeror 错误码
2) mysql.server,mysqld_safe和mysqld都是可以用来启动mysql服务,他们的区别:
1、 mysql.server是以脚本的方式来启动和关闭mysql服务;它主要会用到两个程序和一个函数,分别是my_print_defaults、myslqd_safe和parse_server_arguments;其中,my_print_defaults:读取my.cnf配置文件,输出参数传递给parse_server_arguments,该程序只读my.cnf中[mysqld]中的参数。parse_server_arguments函数处理my_print_defaults传递过来的参数赋值给–basedir、–datadir、–pid-file、–service-startup-timeout等;之后mysql.server接着调用mysqld_safe这个脚本,把parse_server_arguments解析到的参数值传递到mysqld_safe的参数列表中,启动MySQL服务器;这种方式只能使用默认的/etc/my.cnf配置文件来启动mysql;
2、mysqld_safe:它是调用mysqld程序来启动mysql服务的,my.cnf配置文件中的[mysqld_safe]部分中的参数会覆盖[mysqld]部分中的参数;mysqld进程挂掉的时候,mysqld_safe进程会监测到并重新将mysqld启动起来。即mysqld_safe可理解为是mysqld的守护进程,mysqld_safe脚本会在启动MySQL服务器后继续监控其运行情况,并在其死机时重新启动它。因此,我们启动mysql服务时,会看到启动两个进程,一个是mysqld_safe、另外一个是mysqld的服务进程,其中mysqld_safe是守护进程,如果我们要kill掉mysqld进程,需要先kill掉守护进程。
3、mysqld:即执行/usr/local/mysql/bin/mysqld即可启动mysql服务;相关参数:–basedir=/usr/local/mysql --datadir=/usr/local/mysql/data --plugin-dir=/usr/local/mysql/lib/plugin --user=mysql --log-error=/var/log/mysqld.log
4、mysqld_multi:当运行多个MySQL服务器进程。mysql_multi可执行文件可以对每一个服务器进程的启动或停止进行监控
3)mysql的配置文件调用顺序
从高到低:my.cnf, $MYSQL_TCP_PORT,/etc/my.cnf,/etc/mysql/my.cnf,/usr/local/mysql/etc/my.cnf ,~/.my.cnf
mysqld_safe指定的–defaults-file指定的新文件会覆盖默认my.cnf中的配置
mysqld_safe指定的参数会覆盖my.cnf中的配置
mysqld直接启动使用参数,也会覆盖my.cnf中的配置
4)架构图
1、Server层:主要包括连接器、查询缓存(MySQL8.0移除)、分析器、优化器、执行器等,所有的跨存储引擎的功能都在这一层实现,比如存储过程、触发器、视图、函数等,还有一个通用的日志模块binglog
2、存储引擎:主要负责数据的存储和读取,采用可以替换的插件式架构,支持InnoDB、MyISAM、Memory等多个存储引擎,最常用的存储引擎是InnoDB,MySQL5.5.5版本开始其被做为默认的存储引擎。
更多参看MySQL的执行原理;
5)MySQL启动检查
#!/bin/bash
is_start_status=`ps -ef|grep -Ew 'mysqld|mysqld_safe' | grep -vw 'grep' | wc -l`
if [[ "$is_start_status" -ne 2 ]]; then
sleep 10
/opt/mysql/bin/mysqld_safe --defaults-file=/opt/mysql/conf/my.cnf &
fi