5.9.4. 表维护和崩溃恢复
后面几节讨论如何使用myisamchk来检查或维护MyISAM表(对应.MYI和.MYD文件的表)。

你可以使用myisamchk实用程序来获得有关你的数据库表的信息或检查、修复、优化他们。下列小节描述如何调用myisamchk(包括它的选项的描述),如何建立表的维护计划,以及如何使用myisamchk执行各种功能。

尽管用myisamchk修复表很安全,在修复(或任何可以大量更改表的维护操作)之前先进行备份也是很好的习惯

影响索引的myisamchk操作会使ULLTEXT索引用full-text参数重建,不再与MySQL服务器使用的值兼容。要想避免,请阅读5.9.5.1节,“用于myisamchk的一般选项”的说明。

在许多情况下,你会发现使用SQL语句实现MyISAM表的维护比执行myisamchk操作要容易地多:

·         要想检查或维护MyISAM表,使用CHECK TABLE或REPAIR TABLE。

·         要想优化MyISAM表,使用OPTIMIZE TABLE。

·         要想分析MyISAM表,使用ANALYZE TABLE。

可以直接这些语句,或使用mysqlcheck客户端程序,可以提供命令行接口。

这些语句比myisamchk有利的地方是服务器可以做任何工作。使用myisamchk,你必须确保服务器在同一时间不使用表。否则,myisamchk和服务器之间会出现不期望的相互干涉。

 

 

5.9.5. myisamchk:MyISAM表维护实用工具
5.9.5.1. 用于myisamchk的一般选项
5.9.5.2. 用于myisamchk的检查选项
5.9.5.3. myisamchk的修复选项
5.9.5.4. 用于myisamchk的其它选项
5.9.5.5. myisamchk内存使用
5.9.5.6. 将myisamchk用于崩溃恢复
5.9.5.7. 如何检查MyISAM表的错误
5.9.5.8. 如何修复表
5.9.5.9. 表优化
可以使用myisamchk实用程序来获得有关数据库表的信息或检查、修复、优化他们。myisamchk适用MyISAM表(对应.MYI和.MYD文件的表)。

调用myisamchk的方法:

shell> myisamchk [options] tbl_name …
options指定你想让myisamchk做什么。在后面描述它们。还可以通过调用myisamchk –help得到选项列表。

tbl_name是你想要检查或修复的数据库表。如果你不在数据库目录的某处运行myisamchk,你必须指定数据库目录的路径,因为myisamchk不知道你的数据库位于哪儿。实际上,myisamchk不在乎你正在操作的文件是否位于一个数据库目录;你可以将对应于数据库表的文件拷贝到别处并且在那里执行恢复操作。

如果你愿意,可以用myisamchk命令行命名几个表。还可以通过命名索引文件(用“ .MYI”后缀)来指定一个表。它允许你通过使用模式“*.MYI”指定在一个目录所有的表。例如,如果你在数据库目录,可以这样在目录下检查所有的MyISAM表:

shell> myisamchk *.MYI
如果你不在数据库目录下,可通过指定到目录的路径检查所有在那里的表:

shell> myisamchk /path/to/database_dir/*.MYI
你甚至可以通过为MySQL数据目录的路径指定一个通配符来检查所有的数据库中的所有表:

shell> myisamchk /path/to/datadir/*/*.MYI
推荐的快速检查所有MyISAM表的方式是:

shell> myisamchk –silent –fast /path/to/datadir/*/*.MYI
如果你想要检查所有MyISAM表并修复任何破坏的表,可以使用下面的命令:

shell> myisamchk –silent –force –fast –update-state \
          -O key_buffer=64M -O sort_buffer=64M \
          -O read_buffer=1M -O write_buffer=1M \
          /path/to/datadir/*/*.MYI

{Eg:
myisamchk –silent –force –fast –update-state -O key_buffer=64M -O sort_buffer=64M -O read_buffer=1M -O  write_buffer=1M /usr/local/mysql/var/*/*.MYI
}
         
        
         
该命令假定你有大于64MB的自由内存。关于用myisamchk分配内存的详细信息,参见5.9.5.5节,“myisamchk内存使用”。

当你运行myisamchk时,必须确保其它程序不使用表。否则,当你运行myisamchk时,会显示下面的错误消息:

warning: clients are using or haven’t closed the table properly
这说明你正尝试检查正被另一个还没有关闭文件或已经终止而没有正确地关闭文件的程序(例如mysqld服务器)更新的表。

如果mysqld正在运行,你必须通过FLUSH TABLES强制清空仍然在内存中的任何表修改。当你运行myisamchk时,必须确保其它程序不使用表。避免该问题的最容易的方法是使用CHECK TABLE而不用myisamchk来检查表

 

可以用myisamchk –help检查myisamchk变量及其 默认值:

当用排序键值修复键值时使用sort_buffer_size,使用–recover时这是很普通的情况。

当用–extend-check检查表或通过一行一行地将键值插入表中(如同普通插入)来修改键值时使用Key_buffer_size。在以下情况通过键值缓冲区进行修复:

·         使用–safe-recover。

·         当直接创建键值文件时,需要对键值排序的临时文件有两倍大。通常是当CHAR、VARCHAR、或TEXT列的键值较大的情况,因为排序操作在处理过程中需要保存全部键值。如果你有大量临时空间,可以通过排序强制使用myisamchk来修复,可以使用–sort-recover选项。

通过键值缓冲区的修复占用的硬盘空间比使用排序么少,但是要慢。

如果想要快速修复,将key_buffer_size和sort_buffer_size变量设置到大约可用内存的25%。可以将两个变量设置为较大的值,因为一个时间只使用一个变量。

myisam_block_size是用于索引块的内存大小。

stats_method影响当给定–analyze选项时,如何为索引统计搜集处理NULL值。它如同myisam_stats_method系统变量。详细信息参见5.3.3节,“服务器系统变量”和7.4.7节,“MyISAM索引统计集合”的myisam_stats_method的描述。

ft_min_word_len和ft_max_word_len表示FULLTEXT索引的最小和最大字长。ft_stopword_file为停止字文件的文件名。需要在以下环境中对其进行设置。

如果你使用myisamchk来修改表索引(例如修复或分析),使用最小和最大字长和停止字文件的 默认全文参数值(除非你另外指定)重建FULLTEXT索引。这样会导致查询失败。

出现这些问题是因为只有服务器知道这些参数。它们没有保存在MyISAM索引文件中。如果你修改了服务器中的最小或最大字长或停止字文件,要避免该问题,为用于mysqld的myisamchk指定相同的ft_min_word_len,ft_max_word_len和ft_stopword_file值。例如,如果你将最小字长设置为3,可以这样使用myisamchk来修复表

 

 

5.9.5.2. 用于myisamchk的检查选项
myisamchk支持下面的表检查操作选项:

·         –check, -c

检查表的错误。如果你不明确指定操作类型选项,这就是默认操作。

·         –check-only-changed, -C

只检查上次检查后有变更的表。

·         –extend-check, -e

非常仔细地检查表。如果表有许多索引将会相当慢。该选项只能用于极端情况。一般情况下,可以使用myisamchk或myisamchk –medium-check来确定表内是否有错误。

如果你使用了–extend-check并且有充分的内存,将key_buffer_size变量设置为较大的值可以使修复操作运行得更快。

·         –fast,-F

只检查没有正确关闭的表。

·         –force, -f

如果myisamchk发现表内有任何错误,则自动进行修复。维护类型与–repair或-r选项指定的相同。

·         –information, -i

打印所检查表的统计信息。

·         –medium-check, -m

比–extend-check更快速地进行检查。只能发现99.99%的错误,在大多数情况下就足够了。

·         –read-only, -T

不要将表标记为已经检查。如果你使用myisamchk来检查正被其它应用程序使用而没有锁定的表很有用,例如当用–skip-external-locking选项运行时运行mysqld。

·         –update-state, -U

将信息保存在.MYI文件中,来表示表检查的时间以及是否表崩溃了。该选项用来充分利用–check-only-changed选项,但如果mysqld服务器正使用表并且正用–skip-external-locking选项运行时不应使用该选项。

 

 

5.9.5.2. 用于myisamchk的检查选项
myisamchk支持下面的表检查操作选项:

·         –check, -c

检查表的错误。如果你不明确指定操作类型选项,这就是默认操作。

·         –check-only-changed, -C

只检查上次检查后有变更的表。

·         –extend-check, -e

非常仔细地检查表。如果表有许多索引将会相当慢。该选项只能用于极端情况。一般情况下,可以使用myisamchk或myisamchk –medium-check来确定表内是否有错误。

如果你使用了–extend-check并且有充分的内存,将key_buffer_size变量设置为较大的值可以使修复操作运行得更快。

·         –fast,-F

只检查没有正确关闭的表。

·         –force, -f

如果myisamchk发现表内有任何错误,则自动进行修复。维护类型与–repair或-r选项指定的相同。

·         –information, -i

打印所检查表的统计信息。

·         –medium-check, -m

比–extend-check更快速地进行检查。只能发现99.99%的错误,在大多数情况下就足够了。

·         –read-only, -T

不要将表标记为已经检查。如果你使用myisamchk来检查正被其它应用程序使用而没有锁定的表很有用,例如当用–skip-external-locking选项运行时运行mysqld。

·         –update-state, -U

将信息保存在.MYI文件中,来表示表检查的时间以及是否表崩溃了。该选项用来充分利用–check-only-changed选项,但如果mysqld服务器正使用表并且正用–skip-external-locking选项运行时不应使用该选项。

 
一张损坏的表的症状通常是查询意外中断并且能看到下述错误:

“tbl_name.frm”被锁定不能更改。
不能找到文件“tbl_name.MYI”(Errcode:nnn)。
文件意外结束。
记录文件被毁坏。
从表处理器得到错误nnn。
要想得到错误相关的详细信息,你可以运行perror nnn,其中nnn为错误编号。下面的示例显示了如何使用perror来找到最常用错误编号(用表的方式指出问题)的含义:

shell> perror 126 127 132 134 135 136 141 144 145
126 = Index file is crashed / Wrong file format
127 = Record-file is crashed
132 = Old database file
134 = Record was already deleted (or record file crashed)
135 = No more room in record file
136 = No more room in index file
141 = Duplicate unique key or constraint on write or update
144 = Table is crashed and last repair failed
145 = Table was marked as crashed and should be repaired

请注意错误135(记录文件中没有更多的空间)和错误136(索引文件中没有更多的空间)不是可以通过简单修复可以修复的错误。在这种情况下,必须使用ALTER TABLE来增加MAX_ROWS和AVG_ROW_LENGTH表选项值:

ALTER TABLE tbl_name MAX_ROWS=xxx AVG_ROW_LENGTH=yyy;
如果你不知道当前的表的选项值,使用SHOW CREATE TABLE或DESCRIBE来查询。

对于其它的错误,你必须修复表。myisamchk通常可以检测和修复大多数问题。

修复过程包括四个阶段,此处将进行描述。开始修复前,应进入数据库目录并检查表文件的许可。在Unix中,确保它们对于运行mysqld的用户可读(你也应可读,因为你需要访问检查的文件)。如果你需要修改文件,你还必须拥有写访问权限。

用myisamchk修复表的选项的描述参见5.9.5节,“myisamchk:MyISAM表维护实用工具”的前几节。

下面几节列出了上述命令失败或你想要使用myisamchk提供的扩展特性等情况的例子。

如果你要通过命令行来修复表,必须首先停止mysqld服务器。请注意当你在远程服务器上运行mysqladmin shutdown时,mysqladmin返回后,mysqld服务器将仍然运行一会儿,直到停止所有查询并将所有键清空到硬盘上。

 
—————————

1:检查你的表

如果你有很多时间,运行myisamchk *.MYI或myisamchk -e *.MYI。使用-s(沉默)选项禁止不必要的信息。

如果mysqld服务器处于宕机状态,应使用–update-state选项来告诉myisamchk将表标记为’检查过的’。

你必须只修复那些myisamchk报告有错误的表。对这样的表,继续到阶段2。

如果在检查时,你得到奇怪的错误(例如out of memory错误),或如果myisamchk崩溃,到阶段3。
2:简单安全的修复

注释:如果想更快地进行修复,当运行myisamchk时,你应将sort_buffer_size和Key_buffer_size变量的值设置为可用内存的大约25%。

首先,试试myisamchk -r -q tbl_name(-r -q意味着“快速恢复模式”)。这将试图不接触数据文件来修复索引文件。如果数据文件包含它应有的一切内容和指向数据文件内正确地点的删除连接,这应该管用并且表可被修复。开始修复下一张表。否则,执行下列过程:

在继续前对数据文件进行备份。
使用myisamchk -r tbl_name(-r意味着“恢复模式”)。这将从数据文件中删除不正确的记录和已被删除的记录并重建索引文件。
如果前面的步骤失败,使用myisamchk –safe-recover tbl_name。安全恢复模式使用一个老的恢复方法,处理常规恢复模式不行的少数情况(但是更慢)。
如果在修复时,你得到奇怪的错误(例如out of memory错误),或如果myisamchk崩溃,到阶段3。
3:困难的修复

只有在索引文件的第一个16K块被破坏,或包含不正确的信息,或如果索引文件丢失,你才应该到这个阶段。在这种情况下,需要创建一个新的索引文件。按如下步骤操做:

把数据文件移到安全的地方。
使用表描述文件创建新的(空)数据文件和索引文件:
shell> mysql db_name
mysql> SET AUTOCOMMIT=1;
mysql> TRUNCATE TABLE tbl_name;
mysql> quit
如果你的MySQL版本没有TRUNCATE TABLE,则使用DELETE FROM tbl_name。

将老的数据文件拷贝到新创建的数据文件之中。(不要只是将老文件移回新文件之中;你要保留一个副本以防某些东西出错。)
回到阶段2。现在myisamchk -r -q应该工作了。(这不应该是一个无限循环)。

你还可以使用REPAIR TABLE tbl_name USE_FRM,将自动执行整个程序。

4阶段4:非常困难的修复

只有.frm描述文件也破坏了,你才应该到达这个阶段。这应该从未发生过,因为在表被创建以后,描述文件就不再改变了。

从一个备份恢复描述文件然后回到阶段3。你也可以恢复索引文件然后回到阶段2。对后者,你应该用myisamchk -r启动。
如果你没有进行备份但是确切地知道表是怎样创建的,在另一个数据库中创建表的一个拷贝。
删除新的数据文件,然后从其他数据库将描述文件和索引文件移到破坏的数据库中。这样提供了新的描述和索引文件,但是让.MYD数据文件独自留下来了。回到阶段2并且尝试重建索引文件。

 

—————————————————————————–

 

5.9.6. 建立表维护计划
定期对表进行检查而非等到问题出现后再检查数据库表是一个好主意。检查和修复MyISAM表的一个方式是使用CHECK TABLE和REPAIR TABLE语句。参见13.5.2.3节,“CHECK TABLE语法”和13.5.2.6节,“REPAIR TABLE语法”。

检查表的另一个方法是使用myisamchk。为维护目的,可以使用myisamchk -s检查表。-s选项(简称–silent)使myisamchk以沉默模式运行,只有当错误出现时才打印消息。

在服务器启动时检查表是一个好主意。例如,无论何时机器在更新当中重新启动了,你通常需要检查所有可能受影响的表。(即“预期的破坏了的表”)。要想自动检查MyISAM表,用–myisam-recover选项启动服务器。

一个更好的测试将是检查最后修改时间比“.pid”文件新的表。

你还应该在正常系统操作期间定期检查表。在MySQL AB,我们运行一个cron任务,每周一次检查所有重要的表,使用“crontab”文件中这样的行:
crontab -l

35 0 * * 0 /path/to/myisamchk –fast –silent /path/to/datadir/*/*.MYI
可以打印损坏的表的信息,以便我们在需要时能够检验并且修复它们。

多年了我们还没有发现(的确是真的)都没有任何意外损坏的表时(由于除硬件故障外的其它原因造成损坏的表),每周一次对我们是足够了。

我们建议现在开始,你对所有最后24小时内被更新了的表每晚都执行myisamchk -s,直到你变得象我们那样信任MySQL。

一般情况,MySQL表很少需要维护。如果你用动态大小的行更改MyISAM表(含VARCHAR、BLOB或TEXT列的表)或有删除了许多行的表,你可能想要不时地(每月一次)整理/组合表的空间。

可以对有问题的表执行OPTIMIZE TABLE来优化。或者是,如果可以停一会mysqld服务器,进入数据目录,当服务器停止时使用该命令:

shell> myisamchk -r -s –sort-index -O sort_buffer_size=16M */*.MYI

 

 

 

 

 

—————————————-
myisamchk的常规检查表
1.Mysql -d table_name               /*显示表的描述信息*/
{
[mysql@master web]$ myisamchk  -d website.MYI

MyISAM file:         website.MYI
Record format:       Fixed length
Character set:       latin1_swedish_ci (8)
Data records:                    4  Deleted blocks:                 0
Recordlength:                   25
table description:
Key Start Len Index   Type
}
1.1Mysql -dvv table_name    /*显示表的详细信息*/

{

MyISAM file:         shop.MYI
Record format:       Fixed length
Character set:       latin1_swedish_ci (8)
File-version:        1
Creation time:       2010-07-29  0:22:15
Status:              changed
Data records:                   11  Deleted blocks:                 0
Datafile parts:                 11  Deleted data:                   0
Datafile pointer (bytes):        2  Keyfile pointer (bytes):        2
Datafile length:               363  Keyfile length:              2048
Max datafile length:       2162686  Max keyfile length:      67107839
Recordlength:                   33

table description:
Key Start Len Index   Type                     Rec/key         Root  Blocksize
1   2     4   multip. unsigned long                  0         1024       1024

Field Start Length Nullpos Nullbit Type
1     1     1                                                        
2     2     4                                                        
3     6     20                                                       
4     26    8         
}

 

2.Mysql -eis table_name           /*仅显示表的最重要信息*/

{
[mysql@master web]$ myisamchk  -eis website.MYI
Checking MyISAM file: website.MYI
Records:                 4    M.recordlength:       25   Packed:             0%
Recordspace used:      100%   Empty space:           0%  Blocks/Record:   1.00
Record blocks:           4    Delete blocks:         0
Record data:           100    Deleted data:          0
Lost space:              0    Linkdata:              0

User time 0.00, System time 0.06
Maximum resident set size 0, Integral resident set size 0
Non-physical pagefaults 876, Physical pagefaults 0, Swaps 0
Blocks in 0 out 0, Messages in 0 out 0, Signals 0
Voluntary context switches 1, Involuntary context switches 6
}

3.Misamchk -eiv table_name    /*仅告诉目前正在做什么*/

{
[mysql@master web]$ myisamchk -eiv website.MYI
Checking MyISAM file: website.MYI
Data records:       4   Deleted blocks:       0
– check file-size
– check record delete-chain
No recordlinks
– check key delete-chain
– check index reference
– check records and index references
Records:                 4    M.recordlength:       25   Packed:             0%
Recordspace used:      100%   Empty space:           0%  Blocks/Record:   1.00
Record blocks:           4    Delete blocks:         0
Record data:           100    Deleted data:          0
Lost space:              0    Linkdata:              0

User time 0.00, System time 0.06
Maximum resident set size 0, Integral resident set size 0
Non-physical pagefaults 878, Physical pagefaults 0, Swaps 0
Blocks in 0 out 0, Messages in 0 out 0, Signals 0
Voluntary context switches 1, Involuntary context switches 0
}

 

 

 

 

 

 

 
下面解释myisamchk产生的信息的类型。“keyfile”是索引文件。“记录”和“行”是同义词。

·         MyISAM file

ISAM(索引)文件名。

·         File-version

ISAM格式的版本。当前总是2。

·         Creation time

数据文件创建的时间。

·         Recover time

索引/数据文件上次被重建的时间。

·         Data records

在表中有多少记录。

·         Deleted blocks

有多少删除的块仍然保留着空间。你可以优化表以使这个空间减到最小。参见第7章:优化。

·         Datafile parts

对动态记录格式,这指出有多少数据块。对于一个没有碎片的优化过的表,这与Data records相同。

·         Deleted data

不能回收的删除数据有多少字节。你可以优化表以使这个空间减到最小。参见第7章:优化。

·         Datafile pointer

数据文件指针的大小,以字节计。它通常是2、3、4或5个字节。大多数表用2个字节管理,但是目前这还不能从MySQL控制。对固定表,这是一个记录地址。对动态表,这是一个字节地址。

·         Keyfile pointer

索引文件指针的大小,以字节计。它通常是1、2或3个字节。大多数表用 2 个字节管理,但是它自动由MySQL计算。它总是一个块地址。

·         Max datafile length

表的数据文件(.MYD文件)能够有多长,以字节计。

·         Max keyfile length

表的键值文件(.MYI文件)能够有多长,以字节计。

·           Recordlength

每个记录占多少空间,以字节计。

·         Record format

用于存储表行的格式。上面的例子使用Fixed length。其他可能的值是Compressed和Packed。

·         table description

在表中所有键值的列表。对每个键,给出一些底层的信息:

o        Key

该键的编号。

o        Start

该索引部分从记录的哪里开始。

o        Len

该索引部分是多长。对于紧凑的数字,这应该总是列的全长。对字符串,它可以比索引的列的全长短些,因为你可能会索引到字符串列的前缀。

o        Index

unique或multip(multiple)。表明一个值是否能在该索引中存在多次。

o        Type

该索引部分有什么数据类型。这是一个packed、stripped或empty选项的ISAM数据类型。

o        Root

根索引块的地址。

o        Blocksize

每个索引块的大小。默认是1024,但是从源码构建MySQL时,该值可以在编译时改变。

o        Rec/key

这是由优化器使用的统计值。它告诉对该键的每个值有多少条记录。唯一键总是有一个1值。在一个表被装载后(或变更很大),可以用myisamchk -a更新。如果根本没被更新,给定一个30的默认值。

在上面例子的表中,第9个键有两个table description行。者说明它是有2个部分的多部键。

·         Keyblocks used

键块使用的百分比是什么。当在例子中使用的表刚刚用myisamchk重新组织时,该值非常高(很接近理论上的最大值)。

·         Packed

MySQL试图用一个通用后缀压缩键。这只能被用于CHAR/VARCHAR/DECIMAL列的键。对于左部分类似的长字符串,能显著地减少使用空间。在上面的第3个例子中,第4个键是10个字符长,可以减少60%的空间。

·         Max levels

对于该键的B树有多深。有长键的大表有较高的值。

·         Records

表中有多少行。

·         M.recordlength

平均记录长度。对于有定长记录的表,这是准确的记录长度,因为所有记录的长度相同。

·         Packed

MySQL从字符串的结尾去掉空格。Packed值表明这样做达到的节约的百分比。

·         Recordspace used

数据文件被使用的百分比。

·         Empty space

数据文件未被使用的百分比。

·         Blocks/Record

每个记录的平均块数(即,一个碎片记录由多少个连接组成)。对固定格式表,这总是1。该值应该尽可能保持接近1.0。如果它变得太大,你可以重新组织表。参见第7章:优化。

·         Recordblocks

多少块(链接)被使用。对固定格式,它与记录的个数相同。

·         Deleteblocks

多少块(链接)被删除。

·         Recorddata

在数据文件中使用了多少字节。

·         Deleted data

在数据文件中多少字节被删除(未使用)。

·         Lost space

如果一个记录被更新为更短的长度,就损失了一些空间。这是所有这样的损失之和,以字节计。

·         Linkdata

当使用动态表格式,记录碎片用指针连接(每个4 ~ 7字节)。 Linkdata指这样的指针使用的内存量之和。

如果一张表已经用myisampack压缩了,myisamchk -d打印每个表列的附加信息。对于它的一个例子及其含义的描述,参见8.2节,“myisampack:生成压缩、只读MyISAM表”。