-
myisamchk命令使用总结
2025-09-10 21:56:25
myisamchk实用程序可以用来获得有关你的数据库表的统计信息或检查、修复、优化他们
1.常用于myisamchk的检查选项
--information, -i
打印所检查表的统计信息。
--fast,-F
只检查没有正确关闭的表。
--force, -f
如果myisamchk发现表内有任何错误,则自动进行修复。维护类型与-r选项指定的相同。
--medium-check, -m
比--extend-check更快速地进行检查。只能发现99.99%的错误,在大多数情况下就足够了。
长用命令如下:
快速的检查
[root@localhost ~]# myisamchk -im /var/lib/mysql/backup/t1
只检查没有正常关闭的表
[root@localhost ~]# myisamchk -iFm /var/lib/mysql/backup/*
仅显示表的最重要的信息
[root@localhost backup]# myisamchk -eis /var/lib/mysql/backup/t1
2.长用于myisamchk的修复选项
--backup, -B
将.MYD文件备份为file_name-time.BAK
--correct-checksum
纠正表的校验和信息。
--force, -f
覆盖旧的中间文件(文件名类似tbl_name.TMD),而不是中断。
--quick,-q
不修改数据文件,快速进行修复。出现复制键时,你可以两次指定该项以强制myisamchk修改原数据文件。
--recover, -r
可以修复几乎所有一切问题,除非唯一的键不唯一时(对于MyISAM表,这是非常不可能的情况)。如果你想要恢复表,这是首先要尝试的选项。如果myisamchk报告表不能用-r恢复,则只能尝试-o。如果你有大量内存,你应增加sort_buffer_size的值。
--safe-recover, -o
使用一个老的恢复方法读取,按顺序读取所有行,并根据找到的行更新所有索引树。这比-r慢些,但是能处理-r不能处理的情况。该恢复方法使用的硬盘空间比-r少。一般情况,你应首先用-r维修,如果-r失败则用-o。如果你有大量内存,你应增加sort_buffer_size的值。
--tmpdir=path, -t path
用于保存临时文件的目录的路径。如果未设置,myisamchk使用TMPDIR环境变量的值。tmpdir可以设置为一系列目录路径,用于成功地以round-robin模式创建临时文件。在Unix中,目录名之间的间隔字符为冒号(‘:’),在Windows、NetWare和OS/2中为分号 (‘;’)。
--unpack,-u
将用myisampack打包的表解包。
常用恢复命令:
首先尝试用这种恢复方式
[root@localhost ~]# myisamchk -iBfqr /var/lib/mysql/backup/t1
如果上面的恢复失败,再尝试用如下的方式,这个比较慢
[root@localhost ~]# myisamchk -iBfqo /var/lib/mysql/backup/t1
3.长用于myisamchk的分析选项
--analyze,-a
分析键值的分布。这通过让联结优化器更好地选择表应该以什么次序联结和应该使用哪个键来改进联结性能。要想获取分布相关信息,使用如下两个命令
mysql> show keys from t1;
或
[root@localhost ~]# myisamchk --description --verbose /var/lib/mysql/backup/t1
--description, -d
打印出关于表的描述性信息
--sort-index, -S
以从高到低的顺序排序索引树块。这将优化搜寻并且将使按键值的表扫描更快。
--sort-records=N, -R N
根据一个具体索引排序记录。这使你的数据更局部化并且可以加快在该键上的SELECT和ORDER BY的范围搜索。(第一次做排序可能很慢!)为了找出一张表的索引编号,使用SHOW INDEX,它以myisamchk看见他们的相同顺序,显示一张表的索引。索引从1开始编号。
如果键没有打包(PACK_KEYS=0),它们的长度相同,因此当myisamchk 排序并移动记录时,只覆盖索引中的记录偏移量。如果
键已经打包(PACK_KEYS=1),myisamchk必须先解开打包的键块,然后重新创建索引并再次将键块打包。(在这种情况下,重新创建索引比更新每个索引的偏移量要快)。
4.myisamchk内存使用
myisamchk默认只用3M的内存来修复,如果要修复大表的话,显然速度会巨慢,我们可以通过为myisamchk设置更多的内存,来使其运行的更快,
[root@localhost ~]# myisamchk --sort_buffer_size=16M --key_buffer_size=16M --read_buffer_size=1M --write_buffer_size=1M
一般sort_buffer_size的大小16m就足够用了。
myisamchk默认使用选项“--tmpdir”作为临时文件的,如果tmpdir指定内存的话,恢复的表比较大,很容易报内存的错误,所以我们可以用tmpdir指定一个比较大的文件系统
[root@localhost ~]# myisamchk --sort_buffer_size=16m --key_buffer_size=16m --read_buffer_size=2m --write_buffer_size=1m --tmpdir=/tmp -iBfqr /var/lib/mysql/backup/t1
5.myisamchk用于崩溃恢复
在使用myisamdchk修复会优化表时,必须保证mysqld服务器没有使用该表,最好关闭mysqld服务;如果不关闭mysqld,在运行myisamchk之前应执行mysqladmin flash-tables。如果服务器和myisamchk同时访问表,表可能会被破坏。
使用“--skip-external-locking”一般是系统的默认启用选项,mysql数据库一般也是应禁用该选项,因为使用系统的lock和mysql很容易产生死锁。
执行myisam表的恢复只要是修复表的三个文件,最常发生问题的文件是数据文件和索引文件
tbl_name.frm:定义(格式)文件
tbl_name.MYD:数据文件
tbl_name.MYI:索引文件
恢复步骤
A.检查myisam表的错误
# myisamchk -im --verbose /var/lib/mysql/backup/t1
如果有错误,用perror命令查看错误码
[root@localhost ~]# perror 126
OS error code 126: Required key not available
B.初级修复myisam表
试图不接触数据文件来修复索引文件,
# myisamchk -rq tablename
如果恢复失败,继续如下
#[root@localhost ~]# myisamchk -Br tablename
还不行就执行如下
#[root@localhost ~]# myisamchk -o tablename
C.中级修复myisam表
只有在索引文件的第一个16K块被破坏,或包含不正确的信息,或如果索引文件丢失,你才应该到这个阶段
1).把数据文件移到安全的地方。
2).使用表描述文件创建新的(空)数据文件和索引文件:
3).shell> mysql db_name
4).mysql> SET AUTOCOMMIT=1;
5).mysql> TRUNCATE TABLE tbl_name;
6).mysql> quit
如果没有TRUNCATE TABLE,则使用DELETE FROM tbl_name。
7).将老的数据文件拷贝到新创建的数据文件之中。 (记得保留一个副本以防某些东西出错)
8).在实行myisamchk -rq tablename应该就可以了
或
mysql> REPAIR TABLE tbl_name USE_FRM
D.高级恢复
1).从一个备份恢复描述文件然后执行“myisamchk -r tablename”
2).如果没有备份而知道表是怎样创建的,在另一个数据库中创建表的一个拷贝。删除新的数据文件,然后从其他数据库将描述文件和索引文件移到破坏的数据库中。这样在破坏的库里就有新的描述和索引文件,但是让.MYD数据文件独自留下来了。然后在执行“myisamchk -r tablename”
6.myisamchk对表优化
为了组合碎片记录并且消除由于删除或更新记录而浪费的空间
shell> myisamchk -r tbl_name
对所有的索引进行排序以便更快地查找键值
myisamch -S tablename
对指定的索引进行排序以便更快地查找键值
mysql> show index from tablename;
# myisamch -R 1 tablename
如果你用动态大小的行更改MyISAM表(含VARCHAR、BLOB或TEXT列的表)或有删除了许多行的表,你可能想要不时地(每月一次)整理/组合表的空间
可以对有问题的表执行OPTIMIZE TABLE来优化。或者是,如果可以停一会mysqld服务器,执行如下命令:
# myisamchk -r -s --sort-index -O sort_buffer_size=16M */*.MYI
建议按编号看,不要嫌烦
-------------------------------------
myisamchk 和isamchk 实用程序。使用它们可以执行索引键的分布分析和索引的释放与激活。还可以使用它们检查表和修复有问题的表。MySQL 的myisamchk 和isamchk 实用程序很类似,多数时候它们可以用同样的方式使用。它们之间的主要区别是它们所使用的表的类型。对于MyISAM 表,使用my i s a m c h k,而对于ISAM 表,则使用i s a m c h k。您可以通过表的索引文件的扩展名来告诉表使用哪种存储格式。扩展名“. M Y I”表明是一个MyISAM 表,而“. I S M”表明是ISAM 表。表的故障检测和修正的一般过程如下:1) 检查出错的表。如果该表检查通过,则完成任务,否则必须修复它。2) 在开始修复之前对表文件进行拷贝,以防万一。3) 试着修复表。4) 如果修复操作失败,从数据库备份和更新日志中恢复此表。当运行表检查或修复时,您应该被注册在运行mysql的账号下,因为您需要对表文件读写访问。myisamchk的调用语法shell> myisamchk [options] tbl_nametbl_name 参数可以是表名也可以是该表的索引文件名。shell>myisamchk reda.MYIshell> myisamchk /path/to/database_dir/*.MYIshell> myisamchk /path/to/datadir/*/*.MYI检查表要想执行标准的表检查,则不用带任何选项直接调用即可:% myisamchk tbl_name为了执行扩充检查,使用--extend-check 选项。该选项非常慢,但检查极为彻底。对于该表的数据文件中的每个记录,索引文件中的每个索引的相关键都被检查以确保它真正指向正确的记录。 myisamchk 还有一个中间选项—medium-check,它不如扩展检查彻底,但速度快。如果对于 --extend-check 检查不报告错误,则可以肯定表是好的。如果检查出有错误就需要修复它们。 修复表使用逐渐升级的方式修复表.1. 执行标准的表修复为了修复一个表,执行下列步骤:1) 试着用--recover 选项修正表,但也可以用--quick 选项试图只根据索引文件的内容进行恢复。这样将不触及数据文件:% myisamchk --recover --quick tbl_name2) 如果问题仍存在,再试一下上一步的命令,但忽略--quick 选项,以允许myisamchk前进并修改数据文件:% myisamchk --recover tbl_name3) 如果还不工作,试一试--safe-recover 修复方法。这种方法比普通的恢复方法要慢,但能够修正--recover 方法不能修正的几个问题:% myisamchk --safe-recover tbl_name如果myisamchk由于一个“C a n’t create new temp file: file_name” 的错误消息在任何一步中停止,应该重复这个命令并增加--force 选项以迫使清除临时文件。这个临时文件可能是从上一次失败的修复中留下的。这个临时文件是以.TMD结束的文件。在修复表之前拷贝它们,在执行表修复前应该遵循的一个常规的预防措施是做该表的新拷贝。这种情况未必出现,但如果发生,则可以从拷贝文件中做该表的新的拷贝并试试另一种恢复方法。2. 标准表修复方法失败时怎么办如果标准的修复过程未能修复表,则索引文件可能在修复时丢失或毁坏。尽管未必可能,但还是有可能使表的描述文件丢失。不论哪种情况,都需要替换受影响的文件,然后再试试标准修复过程。为了重新生成索引文件,可以使用下列过程:1) 定位到包含崩溃表的数据库目录中。2) 将该表的数据文件移到安全的地方。3) 调用mysql并通过执行下列语句重新创建新的空表,该语句使用表的描述文件tbl_name.frm 重新开始生成新的数据和索引文件:mysql> DELETE FROM tbl_name;4) 退出mysql,将原始的数据文件移回到数据库目录中,替换刚建立的新的空文件。5) 再试试标准表修复方法。为了恢复该表的描述文件,可先从备份文件中恢复,然后再试着用标准修复方法。如果由于某些原因没有备份,但知道建立表的CREATE TABLE 语句,则仍可以恢复该文件:1) 定位到包含崩溃表的数据库目录中。2) 将该表的数据文件移动到安全的地方。如果想要使用索引的话,还需将索引文件移走。3) 调用mysql并发布CREATE TABLE 语句建立该表。4) 退出mysql,将原始数据文件移回数据库目录中,替换刚才新建的数据文件。如果在步骤2移动了索引文件,则也要将其移回数据库目录中。5) 再试试标准表修复方法。避免与MySQL服务器交互作用当您正在运行表的检查/修复实用程序时,您或许不想让MySQL服务器和实用程序同时访问一个表。如果两个程序都向表中写数据显然是一件坏事,但是,当一个程序在写入时另一个程序在读取也不是件好事。如果表正由一个程序写入,同时进行读取的另一个程序会被搞乱。如果您关闭服务器,就可以保证在服务器和myisamchk之间没有交互作用。但是管理员极不愿意使服务器完全地脱机,因为这使得没有故障的数据库和表也不可用。本节中讨论的过程将帮助您避免服务器和 myisamchk之间的交互作用。服务器有两种类型的锁定方法。它使用内部锁定避免客户机的请求相互干扰──例如,避免客户机的SELECT 查询被另一个客户机的UPDATE查询所干扰。服务器还使用外部锁定(文件级锁)来防止其他程序在服务器使用表时修改该表的文件。通常,在表的检查操作中服务器将外部锁定与myisamchk组合使用。但是,外部锁定在某些系统中是禁用的,因为它不能可靠地进行工作。对运行myisamchk所选择的过程取决于服务器是否能使用外部锁定。如果不使用,则必须使用内部锁定协议。如果服务器用--skip-locking 选项运行,则外部锁定禁用。该选项在某些系统中是缺省的,如L i n ux。可以通过运行mysqladmin variables 命令确定服务器是否能够使用外部锁定。检查skip_external_locking 变量的值并按以下方法进行:如果skip_external_locking 为off,则外部锁定有效。您可以继续并运行任一个实用程序来检查表。服务器和实用程序将合作对表进行访问。但是,在运行任何一个实用程序之前,应该用 mysqladmin flush-tables 刷新表的高速缓存。为了修复表,应该使用表的修复锁定协议。如果 skip_external_locking 为on,则禁用外部锁定,但在myisamchk检查或修复一个表时服务器并不知道,最好关闭服务器。如果坚持使服务器保持开启状态,需要确保在您使用此表时没有客户机来访问它。必须使用恰当的锁定协议告诉服务器使该表独处,并阻塞客户机对其访问。这里所描述的锁定协议使用服务器的内部锁定机制,以防止服务器在您利用myisamchk工作时访问表。通常的办法是调用mysql并对要检查或修复的表发布LOCK TABLE 语句。然后,在mysql空闲时(即运行,但除了保持该表锁定外不用它做任何事情),运行myisamchk。在myisamchk 结束后,可以切换到mysql会话中并释放该锁以告诉服务器程序执行完毕此表可以再次使用了。检查和修复的锁定协议有点区别。对于检查,您只需要获得读锁。在这种情况下,只能读取表,但不能修改它,因此它也允许其他客户机读取它。读锁足以防止其他客户机修改表。对于修复,您必须获得写锁以防止任何客户机在您对表进行操作时修改它。锁定协议使用LOCK TABLE 和UNLOCK TABLE 语句获得并释放锁。协议还使用FLUSH TABLES 告诉服务器刷新磁盘中任何未决的改变,并在通过表修复实用程序修改表后重新打开该表。您必须从单个mysql会话中执行所有L O C K、FLUSH 和UNLOCK 语句。如果锁定一个表然后退出mysql,则该锁将释放,而这时再运行myisamchk将不再是安全的!如果保持打开两个窗口的状态,且一个运行mysql,而另一个运行myisamchk,则运行锁定过程将会变得很容易。这样允许您很容易地在程序之间进行切换。如果不是运行在视窗环境中,当运行myisamchk时,将需要使用外壳程序的作业控制工具暂停和恢复mysql。下面的指导显示出对myisamchk的命令,可用与您正在使用的表相对应的那个命令。1. 对检查操作锁定表此过程只针对表的检查,不针对表的修复。在窗口1中,调用mysql并发布下列语句:% mysql db_namemysql>LOCK TABLE tbl_name READ;mysql>FLUSH TABLES;该锁防止其他客户机在检查时写入该表和修改该表。FLUSH 语句导致服务器关闭表的文件,它将刷新仍然在高速缓存中的任何未写入的改变。当mysql空闲时,切换到窗口2 并检查该表:% myisamchk tbl_name当myisamchk结束时,切换回到窗口1的mysql会话并释放该表锁:mysql>UNLOCK TABLE;如果myisamchk指出发现该表的问题,将需要执行表的修复。2. 对修复操作锁定表修复表的锁定过程类似于检查表的过程,但有两个区别。第一,您必须得到写锁而非读锁。由于您将要修改表,因此根本不允许客户机对其进行访问。第二,必须在执行修复之后发布FLUSH TABLE 语句,因为myisamchk建立了新的索引文件,除非再次刷新该表的高速缓存否则服务器将不会注意到它:% mysql db_namemysql>LOCK TABLE tbl_name WRITE;
mysql>FLUSH TABLES;利用mysql的空闲切换到窗口2,做该表的数据库文件的拷贝,然后运行myisamchk:% cp tbl_name.* |some|other|directory% myisamchk --recover tbl_name--recover 选项只是针对安装而设置的。这些特殊选项的选择将取决于您执行修复的类型。myisamchk运行完成后,切换回到窗口1的mysql会话,再次刷新该表的高速缓存并释放表锁:mysql>FLUSH TABLES;mysql>UNLOCK TABLE;快速运行myisamchk myisamchk 和isamchk 的运行可能会花很长时间,尤其是您正在处理一个大表或使用一个更广泛的检查或修复方法时。通过告诉这些程序在运行时使用更多的内存,能够提高它们的速度。这两个实用程序都有几个可设置的操作参数。其中最重要的是控制程序使用的缓冲区大小的变量:变量 含义key _ buffer _ s i z e 用于存放索引块的缓冲区大小r e a d _ buffer _ s i z e 读操作用的缓冲区大小sort _ buffer _ s i z e 排序用的缓冲区大小w r i t e _ buffer _ s i z e 写操作用的缓冲区大小要想查看任一个程序使用的这些变量的缺省值,可用--help 选项运行该程序。要想指定其他的值,可在该命令上使用--set-variable variable=value 或-O variable=value。您可以将变量的名字简化成key、r e a d、sort 和w r i t e。例如,可告诉myisamchk 使用16MB 的排序缓冲区和1MB 的读写缓冲区,其调用如下:% myisamchk -0 sort=16M –0 read=1M –O write=1M ...sort _ buffer_size 只能利用--recover 选项来使用(而不是利用- - s a f e _ r e c o ver),在这种情况下,key _ buffer 不能使用。减少服务器的停机时间防止服务器访问(您正在处理的)表的另一种方法是在数据目录的外面使用该表文件的拷贝。这样并不能消除交互作用的问题,因为仍然必须防止服务器访问(并可能修改)正在进行拷贝的表。但是,如果您不愿意使服务器脱机的话,该路线可能是使服务器停机时间最小化的一种方法,这对您是有吸引力的。在将该表的文件拷贝到另一个目录时关闭服务器,然后恢复服务器。可以用ALTER TABLE 语句转换表的类型:ALTER TABLE tbl_name TYPE=MYISAM
myisamchk常用选项: -a, --analyze 分析键值的分布。这通过让联结优化器更好地选择表应该以什么次序联结和应该使用哪个键来改进联结性能。 -#, --debug=debug_options 输出调试记录文件。debug_options字符串经常是'd:t:o,filename'。 -d, --description 打印出关于表的一些信息。 -e, --extend-check 非常彻底地检查表,但速度很慢。这仅在极端情况下是必要的。通常,myisamchk应该找出所有错误,即使没有该选项。还有一个中间选项--medium-check.-f, --force 覆盖老的临时文件。如果你在检查表时使用-f (运行myisamchk没有-r),myisamchk在检查期间将自动为出现一个错误的表用-r重启。 --help 显示一条帮助消息并且退出。 -i, --information 打印有关被检查的表的信息统计。 -k #, --keys-used=# 与-r一起使用。告诉MYISAM表处理器仅更新头#个索引。较高编号的索引被撤销。这能用来使插入变得更快!撤销的索引能通过使用myisamchk -r被重新激活。 -l, --no-symlinks 在修复时,不跟随符号连接。通常myisamchk修复一个符号连接所指的表。 -q, --quick 与-r一起使用使得一个修复更快。通常,原来的数据文件没被接触;你能指定第二个-q强制使用原来的数据文件。 -r, --recover 恢复模式。可以修复几乎所有一切,除非唯一的键不是唯一。-o, --safe-recover 恢复模式。使用一个老的恢复方法;这比-r慢些,但是能处理-r不能处理的情况。 -O var=option, --set-variable var=option 设置一个变量的值。可能的变量列在下面。 -s, --silent 沉默模式。当错误发生时,仅写输出。你能使用-s两次(-ss)非常沉默地做myisamchk。 -S, --sort-index 以从高到低的顺序排序索引树块。这将优化搜寻并且将使按键值的表扫描更快。 -R index_num, --sort-records=index_num 根据一个索引排序记录。这使你的数据更局部化并且可以加快在该键上的SELECT和ORDER BY的范围搜索。(第一次做排序可能很慢!) 为了找出一张表的索引编号,使用SHOW INDEX,它以myisamchk看见他们的相同顺序显示一张表的索引。索引从1开始编号。 -u, --unpack 解开一个用myisampack压缩的表。 -v, --verbose 冗长模式。打印更多的信息。这能与-d和-e一起使用。为了更冗长,使用-v多次(-vv, -vvv)! -V, --version 打印myisamchk版本并退出。 -w, --wait 如果表被锁定,等待。 对--set-variable(-O)选项,可能的变量是:key_buffer_size 当前值: 16776192read_buffer_size 当前值: 262136write_buffer_size 当前值: 262136sort_buffer_size 当前值: 2097144sort_key_blocks 当前值: 16decode_bits 当前值: 9
OPTIMIZE TABLE:
在大多数情况下,你也可使用命令OPTIMIZE TABLES优化并修复表,但是这不如myisamchk快或可靠(在真正的致命错误的情况下)。在另一方面,OPTIMIZE TABLE较易使用并且你不必须关心清空表。
OPTIMIZE TABLE 语法:
OPTIMIZE TABLE tbl_name
如果你删除了一个表的大部分或如果你用变长的行对一个表(有VARCHAR、BLOB或TEXT列的表)做了改变,应该使用OPTIMZE TABLE。删除的记录以一个链接表维持并且随后的INSERT操作再次使用老记录的位置。你可以使用OPTIMIZE TABLE回收闲置的空间。
OPTIMIZE TABLE通过制作原来的表的一个临时副本来工作。老的表被拷贝到新表中(没有闲置的行),然后原来的表被删除并且重命名一个新的。这样做使得所有更新自动转向新的表,没有任何失败的更新。当OPTIMIZE TABLE正在执行时,原来的表可被另外的客户读取。对表的更新和写入延迟到新表准备好为止。