有站长找到我,说数据库坏了,访问网站报错如下: Error establishing a database connection
看了下 MySQL 的错误日志,报错如下:
Error: Table './db_name/table_name' is marked as crashed and last (automatic?) repair failed
修复很简单,先停止 MySQL
: service mysqld stop
进入到 MySQL 数据库的文件存放目录,比如 cd /data/mysql/PiaoYun.CC_db
然后执行如下命令: D:\phpts\apps\mysql\x64\bin\myisamchk.exe --safe-recover -f -r *.MYI
执行完成后,为了保险起见,我们要将文件的权限改回 MySQL 的运行账号(自行查看),比如 mysql: chown -R mysql:mysql
启动 MySQL: service mysqld start
最后,执行再次自动修复优化命令即可解决: D:\phpts\apps\mysql\x64\bin\mysqlcheck.exe --auto-repair --optimize --all-databases -u帐号 -p密码
MyISAM表坏了怎么解决?myisamchk.exe使用说明
myisamchk工具简介
myisamchk是MySQL安装包内部自带的一个工具,它的作用是检查、修复或者优化MyISAM存储引擎的表。 myisamchk工具,一般放在bin目录下,跟mysqld_safe、mysqld文件放在一起
。通常情况下,是在myisam表出现问题的时候,会使用这个工具对出现问题的表进行修复。 一般来讲,一个myisam
表,存储上分为三个文件:.frm、.MYD、.MYI
其中frm是表结构,MYD是表数据文件,MYI是表索引文件 官方建议: 使用这个工具修复myisam表的时候,最好在进行表修复操作之前对表进行备份;在某些情况下,该操作可能会导致数据丢失。可能的原因包括但不限于文件系统错误 使用方法:
myisamchk option table_name
其中,option是相关操作,table_name是表名字,一般修复表的MYI文件就行 使用限制:
1、myisamchk工具不支持分区表。 2、修复表的时候,不能有其他的操作正在使用这张表。例如不能有备份、锁表等操作,因此最好在MySQL关闭的情况下修复表或者利用flush table将这个表内存数据落盘后,锁定表进行修复。否则,如果有其他操作在更新这个表,则会出现下面的报错:warning: clients are using or haven't closed the table properly
批量修复范例:
MySQL官方给出了一个快速修复所有表的范例:myisamchk --silent --force --fast --update-state
\ --key_buffer_size=64M
\ --myisam_sort_buffer_size=64M
\ --read_buffer_size=1M --write_buffer_size=1M
\ /path/to/datadir/*/*.MYI
如果有大量剩余内存,可以适当调大上面的内存值。 3、实际修复操作
这两天线上出现了一个这样的案例,由于MySQL进程意外挂掉导致的myisam表不可用。报错的信息如下:Slave_IO_Running: Yes
Slave_SQL_Running: No
Replicate_Do_DB:
Replicate_Ignore_DB:
...
Last_Errno: 144
Last_Error: Error 'Table './db/table_1' is marked as crashed and last (automatic?) repair failed' on query.
于是尝试使用这个工具进行修复。修复的时候,发现对应的参数比较多,可以使用myisamchk --help
进行查看,这里不一一介绍了。 我这里重点说两个修复方法,通常情况下,有下面两个修复参数:-r
,--recover
这个参数可以修复几乎MyISAM存储引擎几乎所有的问题,但是唯一索引值 不唯一
的问题无法处理。-o
, --safe-recover
使用旧的恢复方法进行修复,该方法按顺序读取所有行并根据找到的行更新所有索引树。它比--recover 参数慢一个数量级,但可以处理 --recover 不能处理的几个bad case。这种恢复方法使用的磁盘空间也比 --recover 少得多。 通常,我们应该首先使用--recover
进行修复,然后仅在--recover
失败时使用--safe-recover
最后,看一个线上的真实修表的输出吧: /usr/local/mysql-5.6.24/bin/myisamchk -r PiaoYun.CC_1.MYI
- recovering (with sort) MyISAM-table 'PiaoYun.CC_1.MYI'
Data records: 0
- Fixing index 1
- Fixing index 2
- Fixing index 3
- Fixing index 4
- Fixing index 5
- Fixing index 6
- Fixing index 7
- Fixing index 8
- Fixing index 9
- Fixing index 10
- Fixing index 11
- Fixing index 12
- Fixing index 13
- Fixing index 14
Data records: 14848225
这个表本身有14个索引,从输出结果看,确实每个索引都进行了修复,1000w数据的表,修复时间在15分钟左右。 修复完成之后,重新建立主从复制关系,复制关系无误。