0x001 问题背景
mysql上执行相关mysql命令(我们执行的是,show procedure status)时提示 mysql.proc表crashed,无法修复(marked as crashed and last (automatic?) repair failed )
报错信息:mysql table is marked as crashed and last (automatic?) repair failed
0x002 分析处理
mysql提供了检查和修复表的命令:
mysql命令:
CHECK TABLE `table name` 检查表,发现表已经损坏。
REPAIR TABLE `table_name` 执行后,提示无法修复,只能放弃。
正在困惑之时,只能退出mysql交互终端,尝试下mysqlcheck。
使用mysqlcheck 命令对表进行修复:
检查:
mysqlcheck -uuser -ppassword database table -c #检查单个表是否损坏
mysqlcheck -uuser -ppassword database -c #检查整个库那些表损坏
修复:
mysqlcheck -uuser -ppassword database table -r # 修复数据表
mysqlcheck -uuser -ppassword database -r # 修复整个数据库
mysqlcheck --help
This program can be used to CHECK (-c,-m,-C), REPAIR (-r), ANALYZE (-a)
or OPTIMIZE (-o) tables. Some of the options (like -e or -q) can be
used at the same time. Not all options are supported by all storage engines.
Please consult the MySQL manual for latest information about the
above. The options -c,-r,-a and -o are exclusive to each other, which
means that the last option will be used, if several was specified.
The option -c will be used by default, if none was specified. You
can change the default behavior by making a symbolic link, or
copying this file somewhere with another name, the alternatives are:
mysqlrepair: The default option will be -r
mysqlanalyze: The default option will be -a
mysqloptimize: The default option will be -o
Usage: mysqlcheck [OPTIONS] database [tables]
OR mysqlcheck [OPTIONS] --databases DB1 [DB2 DB3...]
OR mysqlcheck [OPTIONS] --all-databases
--print-defaults Print the program argument list and exit
--no-defaults Don't read default options from any options file
--defaults-file=# Only read default options from the given file #
--defaults-extra-file=# Read this file after the global files are read
-A, --all-databases Check all the databases. This will be same as
--databases with all databases selected.
-a, --analyze Analyze given tables.
-1, --all-in-1 Instead of issuing one query for each table, use one
query per database, naming all tables in the database in
a comma-separated list.
--auto-repair If a checked table is corrupted, automatically fix it.
Repairing will be done after all tables have been
checked, if corrupted ones were found.
--character-sets-dir=name
Directory where character sets are.
-c, --check Check table for errors.
-C, --check-only-changed
Check only tables that have changed since last check or
haven't been closed properly.
-g, --check-upgrade Check tables for version-dependent changes. May be used
with --auto-repair to correct tables requiring
version-dependent updates.
--compress Use compression in server/client protocol.
-B, --databases To check several databases. Note the difference in usage;
In this case no tables are given. All name arguments are
regarded as databasenames.
-#, --debug[=#] This is a non-debug version. Catch this and exit.
--default-character-set=name
Set the default character set.
-F, --fast Check only tables that haven't been closed properly.
-f, --force Continue even if we get an sql-error.
-e, --extended If you are using this option with CHECK TABLE, it will
ensure that the table is 100 percent consistent, but will
take a long time. If you are using this option with
REPAIR TABLE, it will force using old slow repair with
keycache method, instead of much faster repair by
sorting.
-?, --help Display this help message and exit.
-h, --host=name Connect to host.
-m, --medium-check Faster than extended-check, but only finds 99.99 percent
of all errors. Should be good enough for most cases.
-o, --optimize Optimize table.
-p, --password[=name]
Password to use when connecting to server. If password is
not given it's solicited on the tty.
-P, --port=# Port number to use for connection.
--protocol=name The protocol of connection (tcp,socket,pipe,memory).
-q, --quick If you are using this option with CHECK TABLE, it
prevents the check from scanning the rows to check for
wrong links. This is the fastest check. If you are using
this option with REPAIR TABLE, it will try to repair only
the index tree. This is the fastest repair method for a
table.
-r, --repair Can fix almost anything except unique keys that aren't
unique.
-s, --silent Print only error messages.
-S, --socket=name Socket file to use for connection.
--tables Overrides option --databases (-B).
--use-frm When used with REPAIR, get table structure from .frm
file, so the table can be repaired even if .MYI header is
corrupted.
-u, --user=name User for login if not current user.
-v, --verbose Print info about the various stages.
-V, --version Output version information and exit.
myisamchk 修复mysql表
Myisamchk是MyISAM表维护的一个非常实用的工具。可以使用myisamchk实用程序来获得有关数据库表的信息或检查、修复、优化他们。myisamchk适用MyISAM表(对应.MYI和.MYD文件的表)。
Myisamchk 选项解释
�Cdebug=debug_options, -# debug_options
输出调试记录文件。debug_options字符串经常是’d:t:o,filename’。
�Csilent,-s
沉默模式。仅当发生错误时写输出。
�Cwait, -w
如果表被锁定,不是提示错误终止,而是在继续前等待到表被解锁。
如果不使用�Cskip-external-locking,可以随时使用myisamchk来检查表。当检查表时,所有尝试更新表的客户端将等待,直到myisamchk准备好可以继续。
请注意如果用�Cskip-external-locking选项运行mysqld,只能用另一个myisamchk命令锁定表。
�Cvar_name=value
可以通过�Cvar_name=value选项设置下面的变量:
�Ccheck, -c
检查表的错误。如果你不明确指定操作类型选项,这就是默认操作。
�Ccheck-only-changed, -C
只检查上次检查后有变更的表。
�Cextend-check, -e
非常仔细地检查表。如果表有许多索引将会相当慢。
�Cfast,-F
只检查没有正确关闭的表。
�Cforce, -f
如果myisamchk发现表内有任何错误,则自动进行修复。
�Cinformation, -i
打印所检查表的统计信息。
�Cmedium-check, -m
比�Cextend-check更快速地进行检查。只能发现99.99%的错误
�Cupdate-state, -U
将信息保存在.MYI文件中,来表示表检查的时间以及是否表崩溃了。该选项用来充分利用�Ccheck-only-changed选项,
但如果mysqld服务器正使用表并且正用�Cskip-external-locking选项运行时不应使用该选项。
�Cread-only, -T
不要将表标记为已经检查。如果你使用myisamchk来检查正被其它应用程序使用而没有锁定的表很有用
�Cbackup, -B
将.MYD文件备份为file_name-time.BAK
�Ccharacter-sets-dir=path
字符集安装目录。
�Ccorrect-checksum
纠正表的校验和信息。
�Cdata-file-length=len, -D len
数据文件的最大长度
�Cextend-check,-e
进行修复,试图从数据文件恢复每一行。一般情况会发现大量的垃圾行。不要使用该选项,除非你不顾后果。
�Cforce, -f
覆盖旧的中间文件(文件名类似tbl_name.TMD),而不是中断
�Ckeys-used=val, -k val
对于myisamchk,该选项值为位值,说明要更新的索引。选项值的每一个二进制位对应表的一个索引,其中第一个索引对应位0。
选项值0禁用对所有索引的更新,可以保证快速插入。通过myisamchk -r可以重新激活被禁用的索引。
�Cparallel-recover, -p
与-r和-n的用法相同,但使用不同的线程并行创建所有键。
�Cquick,-q
不修改数据文件,快速进行修复。
�Crecover, -r
可以修复几乎所有一切问题,除非唯一的键不唯一时(对于MyISAM表,这是非常不可能的情况)。如果你想要恢复表,
这是首先要尝试的选项。如果myisamchk报告表不能用-r恢复,则只能尝试-o。
在不太可能的情况下-r失败,数据文件保持完好)。
�Csafe-recover, -o
使用一个老的恢复方法读取,按顺序读取所有行,并根据找到的行更新所有索引树。这比-r慢些,
但是能处理-r不能处理的情况。该恢复方法使用的硬盘空间比-r少。一般情况,你应首先用-r维修,如果-r失败则用-o。
�Csort-recover, -n
强制myisamchk通过排序来解析键值,即使临时文件将可能很大。
�Canalyze,-a
分析键值的分布。这通过让联结优化器更好地选择表应该以什么次序联结和应该使用哪个键来改进联结性能。
要想获取分布相关信息,使用myisamchk �Cdescription �Cverbose tbl_name命令或SHOW KEYS FROM tbl_name语句。
�Csort-index, -S
以从高到低的顺序排序索引树块。这将优化搜寻并且将使按键值的表扫描更快。
�Cset-auto-increment[=value], -A[value]
强制从给定值开始的新记录使用AUTO_INCREMENT编号(或如果已经有AUTO_INCREMENT值大小的记录,应使用更高值)。
如果未指定value,新记录的AUTO_INCREMENT编号应使用当前表的最大值加上1。
�Cdescription, -d
打印出关于表的描述性信息。
在使用myisamchk 修复过程中,发现提示出错,后来搜索了下,发现需要停止mysql服务进行修复。
到mysql的db目录,通过myisamchk -r -f 表名来完成数据表的修复。
Go to your data folder and try running myisamchk -r <table_name>. You should stop MySQL process first. If that doesn't work, you can try with myisamchk -r -v -f <table_name>.
0x003 总结
mysql在使用过程中不经意间会发生库表损坏的情况,通过repair table 表名,mysqlcheck,myisamchk 来检查库表是否损坏,以及进行修复。