APP下载

处理MySQL 访问异常故障

2019-12-16河南刘建臣

网络安全和信息化 2019年12期
关键词:数据表磁盘命令

河南 刘建臣

某单位使用Java 开发的数据分析系统,后台使用的是MySQL 数据库,最近出现了无法查询和写入数据的情况,MySQL 服务器使用的是CentOS 6.X 系统,使用了八核的CPU,内存为64GB,按照这样的配置,运行MySQL 是没有任何问题的。笔者进入MySQL 安装路径,发现似乎缺少了某些文件,果然其中的“ibdata1”“ib_logfile0”“ib_logfile1”等文件“不翼而飞”了。

故障分析

MySQL 默认采用InnoDB引擎,上述文件是MySQL 的表空间文件和日志文件,Innodb 存储类型的表的数据都放在该共享表空间中。看来是有人误删除了这些文件,是不是这些文件丢失的原因呢?因为MySQL服务并没有重启,是可以从内存文件系统中找回这些文件的。执行“netstat-nltp|grep mysqld”命令,可以查到MySQL 的进程号,这里为“6831”。执行“ll/proc/6831/fd|grep -e ibdata -e ib_”命令,果然在内存文件系统中找到了这些文件,状态为“deleted”,说明实际文件已被删除。因为数据库处于运行状态,在InnoDB 引擎缓存池中有很多数据已发生变动,但没有写入到磁盘文件中,如果直接恢复肯定会造成数据丢失。

在MySQL 中执行“flush tables with read lock;”命令,禁止针对数据库的修改操作。执行“show engine innodb statusG;”命令,在返回信息中的“Pages flushed up to”行显示当前最旧的脏页数据对应的位置,在“Log sequence number”行中显示当前最新数据产生的日志序列号信息。这里两者数据一致,说明内存中的Dirty Page 数据已写入磁盘。在“Modified db pages”栏中显示脏数据库页数,该值应为0,说明Dirty Page 已刷新到磁盘。

否则,执行“set global innodb_max_dirty_pages_pct=0;”命令,设置Dirty Page 刷新比例。当确定Dirty Page 已全部写入磁盘后,执行:

执行文件复制操作,之后执行“chown mysql:mysql/data1/mysql/ib*”命令,为上述文件指定用户权限,因为运行MySQL 的用户名为“mysql”。执行“/etc/init.d/mysqld restart”命令,重启MySQL 服务。

进入MySQL 运行路径,发现上述文件已找回,原本以为问题解决了,但在对某个数据表进行查询和写入操作时,依然出现失败。

在MySQL 中执行“show processlist;”命令,发现有线程正对“tb_anlydat”的表进行检测操作,而其他线程在进行插入等操作时,出现“Waiting for table level lock”提示,说明MySQL 正在对该表进行检查,因此其他的写入操作处于阻塞状态。

执行“show create table tb_anlydat;”命令,发现该表使用的是MyISAM引擎,因为同InnoDB 引擎相比,MyISAM 引擎具有较快的查询速度,在实际中经常会出现混合使用上述引擎的现象,即大部分表使用InnoDB引擎,少量对查询性能要求较高的表使用MyISAM 引擎。MyISAM 引擎只支持表级锁,如果当数据库出现执行时间较长的查询或检测时,对目标数据表进行更新操作,就很容易出现“Waiting for table level lock”之类的错误提示,造成无法插入数据的问题。

前端程序就会因连接失效造成访问请求失败,连续执 行“show processlist;”命令,可以发现相关线程正在对该表进行修复,说明MySQL 已发现该表存在问题,在进行修复操作。

根据以上分析,可以发现上述问题的原因,就在于某些数据表存储问题。既然数据表无法插入数据,那么就需要进行修复。在修复之前需要将内容导出来。例如执行“select * into outfile '/tmp/export.txt' from tb_anlydat;”命令,将该表中数据导出,在备用MySQL服务器上执行“LOAD DATA local INFILE '/tmp/export.txt' IGNORE INTO TABLE tb_anlydat;”之类的命令,将数据导入进来,便于对该数据表进行修复。

MyISAM 引擎提供了Check Table、Repair Table和Myisanchk 等工具,可以对数据表进行检测和修复操作。例如在MySQL 中执行“check table tb_anlydat;”和“repair table tb_anlydat;”命令,对该表进行修复操作,但很花时间却没有什么效果。打开MySQL 配置文件“my.cnf”,发现其中存在“myisamrecover=BACKUP,FORCE”行,这表明如果重启MySQL,就会自动针对使用MyISAM 的表进行备份和检测修复操作。因为该表体积达到几百兆,读写比较频繁,往往会因为各种原因(例如断电、硬件故障等),造成使用MyISAM 引擎的数据表出现故障。

故障排查

笔者注意到该MySQL 数据库使用了独立的磁盘来存储数据,执行“df -lh”命令,显示还有约30%的可用空间,不存在磁盘空间不足问题。执行“dmesg”命令,在返回信息中发现和MySQL 对应的磁盘出现“Medium Error”、“uncovered read erroe”、“critical medium error”等错误信息,表明该硬盘分区出现了坏道等才引发了以上问题。

表面看来,可以在硬盘上进行读写操作,似乎硬盘没有问题,其实该盘的某些扇区已经损坏,且该数据表恰恰使用了这些问题扇区。问题找到了,只能更换新的硬盘,当然,需要将所有MySQL数据导出保存到备用机。因为MyISAM 引擎容易出问题,最好还是使用InnoDB 引擎操作数据表。

猜你喜欢

数据表磁盘命令
管理Windows10的PowerShell命令行使用记录
它的好 它的坏 详解动态磁盘
湖北省新冠肺炎疫情数据表(2.26-3.25)
湖北省新冠肺炎疫情数据表
湖北省新冠肺炎疫情数据表
安装和启动Docker
创建虚拟机磁盘方式的选择
解决Windows磁盘签名冲突
移防命令下达后
Windows系统下动态磁盘卷的分析与研究