技术分享 | MySQL 启动失败的常见原因

技术分享 | MySQL 启动失败的常见原因,第1张

MySQL 启动失败的最常见的原因有两类,分别是无法访问系统资源和参数设置错误造成的,下面分别分析如下。

MySQL 不能访问启动需要的资源是造成而 MySQL 无法启动的一个常见原因,如:文件,端口等。由于 linux 中用于启动 mysqld 进程的 mysql 用户通常是不能登陆的,可以使用类似下面的命令检查文件的访问权限。

找出问题后,修改对应文件或目录的权限或属主后通常可以解决问题。但有时 mysql 用户有访问文件和目录的权限,但仍然会被拒绝访问,例如下面这个例子:

测试说明 mysql 用户有这个目录的访问权限,但创建文件还是失败,这种情况让很多人困惑,这个时候通常是 mysqld 进程的访问被 linux 的 selinux 或 apparmor 给阻止了,大家可以看到创建的表不是在 mysql 的默认目录下面,因此 selinux 或 apparmor 的 policy 里面没有包含这个目录的访问权限,此时只要对应的修改 policy 就行了,当然把 selinux 或 apparmor 停了也行。

有时虽然对系统资源有访问的权限,但系统资源已经被占用:

这个故障产生的原因是另外一个 mysqld 进程已经启动并占用了对应的文件。

参数设置错误造成 MySQL 无法启动的原因也非常常见,此时先要检查 MySQL 启动时会调用的参数,下面的命令可以查询 MySQL 启动时调用参数文件的顺序:

知道了 MySQL 参数文件的调用顺序,我们就可以检查对应的参数文件,找出其中的错误,如果觉得参数文件的可读性不强,可以使用下面的命令显示 mysqld 程序将要调用的参数:

注意这个命令显示完参数后就退出,不会真正运行 mysqld。这个命令和 my_print_defaults mysqld 完全是等价的,只不过后者的显示方式是一行一个参数。

然后开始对可疑的参数进行调试,我个人喜欢加的参数和顺序如下:

看这个例子:

看这个例子,我们很容易知道是需要我们同时设置参数 GTID_MODE 和 ENFORCE_GTID_CONSISTENCY 同时为 on 才行。

一、确认MYSQL已经配置且正确

重新配置

如果是重新安装的MYSQL,请确认安装后的MYSQL经过第一次配置,否则会缺少my.ini文件,配置方法,可以在安装到最后一步时选择,现在开始配置MYSQL,或在程序组中运行MYSQL配置向导。配置完成后,要确保my.ini文件中[mysqld]字段下至少有basedir安装目录路径和datadir数据库路径。

配置之前,如果原来已经有过MySQL配置,可以先在MYSQL向导中进行执行一次REMOVE INSTANCE,然后再重新配置。

覆盖数据表

默认的MYSQL数据库会安装到My Document下,所以如果您的数据库目录在其它路径下,可以先把MYSQL停止掉,然后把数据库剪切到其它路径,然后拷贝相关数据表进入同一目录即可。

如果MYSQL数据表使用不同的账户,还需要在MYSQL创建账户,或直接使用原来的MYSQL数据表覆盖(需确认之前的MSYQL数据表是未损坏的)。

解决无法启动

遇到无法启动MYSQL时常见解决方法:

A、先使用命令C:\Program files\mysql\bin\mysqladmin-u root -p shutdown来关闭MYSQL

B、再在cmd命令行下,执行net start mysql启动mysql。

二、1067错误常见解决方法

故障现象

如果在停止MYSQL(net stop mysql)或启动MYSQL时,出现1067错误,错误信息“MySql 服务正在停止...系统出错(A system error has occurred.)...系统发生 1067 错误(System error 1067 has occurred.),进程意外终止(The process terminated unexpectedly.)”等。

常见解决方法

如果以前一直运行OK的,请先按照上面的“无法启动”解决方法执行一次看看。

如果进行过Remove Instance *** 作,再次重建时后,一定要检查my.ini文件中的datadir是否已被还原了,如果该地址下数据库不存在,也将报告1067错误,只需要修改成真实的数据库目录地址,然后手动启动即可。

检查MYSQL目录权限

检查my.ini文件中[mysqld]字段下是否有basedir安装目录路径和datadir数据库路径,my.ini可能需要出现在两个地方,MYSQL的安装目录和Windows目录(假设是windows环境)下,都要检查一下。

有时候删除%windir%/my.ini文件然后再重新配置也可以解决,再次配置后检查一下Windir目录下是否有my.ini文件,有时把安装目录下最新的my.ini拷贝过去覆盖一下也能解决问题。

如果是Linux环境,试一下把mysql.server拷贝至/etc/rc.d/init.d/下,然后再运行chkconfig mysql.server,之后就可以在命令行中设置PATH、使用命令执行mysql启动。

三、非法关机造成的MYSQL无法启动问题

如果是因为非法关机等原因导致MYSQL无法启动或启动有问题的,最好使用重新安装的或确认是OK的MYSQL数据表及ibdata1、mysql.pid、ib_logfile0等文件进行覆盖,天缘试过遇到过多次这种情况,就是原来的MYSQL表有问题了,总是无法启动,但是更换成新表就可以。

四、重装MYSQL

发现MYSQL有问题时,最便捷的方法,是先把mysql卸载掉,然后重装重新配置,具体方法如下:

1、卸载MYSQL,清理掉安装目录和Windows目录下的my.ini文件。

2、检查任务管理器中是否还有mysql进程,如果有,可以把mysqld.exe杀掉,或者先杀掉再卸载也可以。

3、在cmd命令窗口,执行:sc delete mysql,该命令是清理注册服务命令。

3. 重装 mysql

如果是安全设置以后出现这个问题,可能是因为mysql以低权限运行的时候因为密码策略等问题导致,大家看恶意将mysql的启动用户更下下密码,然后在服务项里设置下即可。

最近接了一个锅,进入新公司接手了一个进入交付阶段的项目.在code review的时候发现很多问题,然后开始修复bug.

在测试阶段突然发现几乎所有涉及到更新的 *** 作都失败,下面贴出异常信息.

第一次 出现的时候百度了一下,猜想可能是多服务部署资源冲突,重启服务故障消失.所以没有特别重视

第二次 出现的时候只有测试环境部署,不存在多机资源冲突的问题,猜想是多线程资源交叉导致的,于是给可能导致资源竞争的地方加上了分布式锁.

由于无法重现故障,所以并没有确认问题得到解决.

第三次 故障依旧,当发现问题依然存在的时候,开始认真反思,发现自己解决问题的思路明显有问题,过于片面,一直都只在应用层面寻求解决问题的办法,而且解决问题的方式也只是在尝试百度出来的方法.并没有去思考更深层的问题.

在Mysql5.5中,information_schema 库中增加了三个关于锁的表(MEMORY引擎);

INNODB_TRX ## 当前运行的所有事务

INNODB _LOCKS ## 当前出现的锁

INNODB_LOCK_WAITS ## 锁等待的对应关系

通过查询 INNODB_TRX 发现

当前事务中又两个RUNNING状态开始时间在一个小时之前

开始一直以为是锁表了

查看了 INNODB _LOCKS  事务信息之后发现有4行数据被锁住了一直没有释放

从这里开始发现问题了,应用已经抛了异常,事务理所当然的应该回滚才对,为什么资源依然没有释放,导致持续的阻塞呢?

其实最开始的异常信息就已经给出了答案,回到开始的地方,再看异常信息就很清楚了,应用里面的异常类是 MySQLTransactionRollBackException

是一个回滚异常, 这就说明在事务回滚的时候出了问题资源没有得到释放

然后开始查询 MySQLTransactionRollBackException  相关的信息

这个时候 innodb_rollback_on_timeout =0(默认配置)这个MySQL的配置开始进入我的视线,

举个栗子

事务在锁等待超时后是回滚事务内所有的statement还是最后一条语句;

 0表示rollback最后一条语句,默认值; 有点坑爹啊( 细思极恐 )

 1表示回滚事务内所有的statements;(此参数是只读参数,需在my.cnf中配置,并且重启生效;)

吃过一次亏,这次并没有盲目的相信百度到的信息

于是开始测试

一、验证innodb_rollback_on_timeout=off的情况

1.session A

    开启事务,事务未提交,锁住id=1的数据

2.session B 

开启事务,执行更新id=2的数据成功(事务未提交,锁住id=2),然后请求id=1等待锁超时,id=2的数据更改为222.

3.session C

请求id=2的数据50秒后显示等待锁超时

执行 SELECT * FROM information_schema.INNODB_TRX

可发现有资源一直未释放,具体到测试数据中就是id=2的资源一直被锁定,线程一直被挂起.

总结:通过实验基本可以确定是业务资源交叉导致死锁之后资源没释放造成的持续阻塞,

二.验证innodb_rollback_on_timeout=on

修改配置后将验证innodb_rollback_on_timeout=off的步骤再走一遍

发现锁等待只能在业务层面尽量避免

on/off的区别在于session C进入时不会持续阻塞,session B异常后全部回滚


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/8711715.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-20
下一篇 2023-04-20

发表评论

登录后才能评论

评论列表(0条)

保存