13.5.2. 表维护语句

13.5.2.1. ANALYZE TABLE语法

ANALYZE [LOCAL | NO_WRITE_TO_BINLOG] TABLE tbl_name [, tbl_name] ...

本语句用于分析和存储表的关键字分布。在分析期间,使用一个读取锁定对表进行锁定。这对于MyISAM, BDBInnoDB表有作用。对于MyISAM表,本语句与使用myisamchk -a相当。

MySQL使用已存储的关键字分布来决定,当您对除常数以外的对象执行联合时,表按什么顺序进行联合。

本语句会返回一个含有以下列的表:

Table

表名称

Op

进行分析

Msg_type

状态、错误、信息或警告之一

Msg_text

消息

您可以使用SHOW INDEX语句检查已存储的关键字分布。请参见13.5.4.11节,“SHOW INDEX语法”

如果从上一个ANALYZE TABLE语句开始,表没有变化,则不再分析该表。

ANALYZE TABLE语句被写入二进制日志中,除非使用了自选的NO_WRITE_TO_BINLOG关键词(或其别名LOCAL)。

13.5.2.2. BACKUP TABLE语法

BACKUP TABLE tbl_name [, tbl_name] ... TO '/path/to/backup/directory'

注释:本语句不理想。我们正在努力寻找一种更好的替代方式,该方式将提供在线备份能力。同时,也可以使用mysqlhotcopy原本替代。

BACKUP TABLE用于在刷新了所有对磁盘的缓冲变更后,把恢复表所需的最少数目的表文件拷贝到备份目录中。本语句只对MyISAM表起作用。它可以拷贝.frm定义文件和.MYD数据文件。.MYI索引文件可以从这两个文件中重建。本目录应被指定为一个完整的路径名。

在使用本语句前,请参见5.9.1节,“数据库备份”

在备份期间,为每个表保持一个读取锁定,每次一个,在正在备份时锁定。如果您想要把多个表作为一个快照来备份(防止它们在备份操作过程中被更改),您必须实现发布一个LOCK TABLES语句,以获得对一个组群中的每个表的读取锁定。

该语句会返回一个含有以下列的表:

Table

表名称

Op

进行备份

Msg_type

状态、错误、信息或警告之一

Msg_text

消息

13.5.2.3. CHECK TABLE语法

CHECK TABLE tbl_name [, tbl_name] ... [option] ...
 
option = {QUICK | FAST | MEDIUM | EXTENDED | CHANGED}

检查一个或多个表是否有错误。CHECK TABLEMyISAMInnoDB表有作用。对于MyISAM表,关键字统计数据被更新。

CHECK TABLE也可以检查视图是否有错误,比如在视图定义中被引用的表已不存在。

CHECK TABLE语句会返回一个含有以下列的表:

Table

表名称

Op

进行检查

Msg_type

状态、错误、信息或错误之一

Msg_text

消息

注意,该语句可能会为每个被检查的表产生多行信息。最后一行有一个Msg_type状态值。Msg_text通常应为OK。如果您没有得到OK,或表已经更新了,则您通常应该运行修复后的表。请参见5.9.4节,“表维护和崩溃恢复”。表已经更新了,这意味着表的存储引擎指示没有必要检查表。

可以给予的不同的检查选项列于下表中。这些选项只适用于检查MyISAM表。对于InnoDB表和视图,这些选项被忽略。

类型

意义

QUICK

不扫描行,不检查错误的链接。

FAST

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

CHANGED

只检查上次检查后被更改的表,和没有被正确关闭的表。

MEDIUM

扫描行,以验证被删除的链接是有效的。也可以计算各行的关键字校验和,并使用计算出的校验和验证这一点。

EXTENDED

对每行的所有关键字进行一个全面的关键字查找。这可以确保表是100%一致的,但是花的时间较长。

如果没有指定QUICK, MEDIUMEXTENDED选项,则对于动态格式MyISAM表,默认检查类型是MEDIUM。这与对表运行myisamchk --medium-check tbl_name的结果相同。对于静态格式MyISAM表,默认检查类型也是MEDIUM,除非CHANGEDFAST已被指定。在此情况下,默认值为QUICK。对于CHANGEDFAST,行扫描被跳过,因为行极少被破坏。

您可以组合检查选项,如下面的例子所示。该例子对表进行了一个快速检查,来查看该表是否被正确关闭:

CHECK TABLE test_table FAST QUICK;

注释:在有些情况下,CHECK TABLE会更改表。如果表被标记为“corrupted”或“not closed properly”,则出现这种情况。但是CHECK TABLE不会找出表中的问题。在这种情况下,CHECK TABLE会把表标记为良好。

如果一个表被破坏,很有可能问题在索引中,而不在数据部分中。所有前述的检查类型都可以彻底地检查索引,因此,可以找出多数的错误。

如果您只想要检查您假定的表是良好的,您应该不使用检查选项或QUICK选项。当您时间匆忙时,应使用QUICKQUICK无法找出数据文件中的错误的风险非常小。(在多数情况下,在正常使用中,MySQL应能在数据文件中找出错误。如果找出了错误,表被标记为“corrupted”,并不能被使用,直到修复为止。)

如果您想要时常检查表,FASTCHANGED多数情况下从原本中被使用(例如,从cron中被执行)。在多数情况下,FAST优先于CHANGED。(只有一种情况FAST不优先于CHANGED,那就是当您怀疑您在MyISAM代码中发现了错误。)

MySQL试图通过关键字更新一行或查找一行时,如果您已经运行了一个常规检查后但仍得到来自表的奇怪的错误,此时使用EXTENDED。(如果常规的检查运行成功,则基本用不着EXTENDED。)

CHECK TABLE报告的部分问题不会被自动修正:

·         发现行。此行中,auto_increment列有0值。

这意味着,您在表中有一行,该行的AUTO_INCREMENT索引列包含0值。(可以通过使用UPDATE语句,明确地把列设置为0,以创建一个AUTO_INCREMENT列为0的行。)

这本身不是一个错误,但是如果您决定转储表并恢复表,或对表进行ALTER TABLE,那么会导致出现麻烦。在此情况下,AUTO_INCREMENT列会根据AUTO_INCREMENT列的结果更改值,这会导致出现问题,如重复关键字错误等。

要消除警告,只需执行一个UPDATE语句,把列设置为除0以外的值。

13.5.2.4. CHECKSUM TABLE语法

CHECKSUM TABLE tbl_name [, tbl_name] ... [ QUICK | EXTENDED ]

报告一个表校验和。

如果指定了QUICK,则报告活性表校验和,否则报告NULL。这是非常快的。活性表通过指定CHECKSUM1表选项启用,目前只支持用于MyISAM表。请参见13.1.5节,“CREATE TABLE语法”

EXTENDED模式下,整个表被一行一行地读取,并计算校验和。对于大型表,这是非常慢的。

默认情况下,如果既没有指定QUICK,也没有指定EXTENDED,并且如果表存储引擎支持,则MySQL返回一个活性校验和,否则会对表进行扫描。

CHECKSUM TABLE对于不存在的表会返回NULL。对于这种情况,会生成一个警告。

13.5.2.5. OPTIMIZE TABLE语法

OPTIMIZE [LOCAL | NO_WRITE_TO_BINLOG] TABLE tbl_name [, tbl_name] ...

如果您已经删除了表的一大部分,或者如果您已经对含有可变长度行的表(含有VARCHAR, BLOBTEXT列的表)进行了很多更改,则应使用OPTIMIZE TABLE。被删除的记录被保持在链接清单中,后续的INSERT操作会重新使用旧的记录位置。您可以使用OPTIMIZE TABLE来重新利用未使用的空间,并整理数据文件的碎片。

在多数的设置中,您根本不需要运行OPTIMIZE TABLE。即使您对可变长度的行进行了大量的更新,您也不需要经常运行,每周一次或每月一次即可,只对特定的表运行。

OPTIMIZE TABLE只对MyISAM, BDBInnoDB表起作用。

对于MyISAM表,OPTIMIZE TABLE按如下方式操作:

1.    如果表已经删除或分解了行,则修复表。

2.    如果未对索引页进行分类,则进行分类。

3.       如果表的统计数据没有更新(并且通过对索引进行分类不能实现修复),则进行更新。

对于BDB表,OPTIMIZE TABLE目前被映射到ANALYZE TABLE上。对于InnoDB表,OPTIMIZE TABLE被映射到ALTER TABLE上,这会重建表。重建操作能更新索引统计数据并释放成簇索引中的未使用的空间。请参见13.5.2.1节,“ANALYZE TABLE语法”

使用—skip-new或—safe-mode选项可以启动mysqld。通过启动mysqld,您可以使OPTIMIZE TABLE对其它表类型起作用。

注意,在OPTIMIZE TABLE运行过程中,MySQL会锁定表。

OPTIMIZE TABLE语句被写入到二进制日志中,除非使用了自选的NO_WRITE_TO_BINLOG关键词(或其别名LOCAL)。已经这么做了,因此,用于MySQL服务器的OPTIMIZE TABLE命令的作用相当于一个复制主服务器,在默认情况下,这些命令将被复制到复制从属服务器中。

13.5.2.6. REPAIR TABLE语法

REPAIR [LOCAL | NO_WRITE_TO_BINLOG] TABLE
    tbl_name [, tbl_name] ... [QUICK] [EXTENDED] [USE_FRM]

REPAIR TABLE用于修复被破坏的表。默认情况下,REPAIR TABLEmyisamchk --recover tbl_name具有相同的效果。REPAIR TABLEMyISAMARCHIVE表起作用。请参见15.1节,“MyISAM存储引擎”, 15.8节,“ARCHIVE存储引擎”

通常,您基本上不必运行此语句。但是,如果灾难发生,REPAIR TABLE很有可能从MyISAM表中找回所有数据。如果您的表经常被破坏,您应该尽力找到原因,以避免使用REPAIR TALBE。请参见A.4.2节,“如果MySQL依然崩溃,应作些什么”。同时也见15.1.4节,“MyISAM表方面的问题”

本语句会返回一个含有以下列的表:

Table

表名称

Op

进行修复

Msg_type

状态、错误、信息或警告之一

Msg_text

消息

对于每个被修复的表,REPAIR TABLE语句会产生多行的信息。上一行含有一个Msg_type状态值。Msg_test通常应为OK。如果您没有得到OK,您应该尝试使用myisamchk --safe-recover修复表,因为REPAIR TABLE尚不会执行所有的myisamchk选项。我们计划在将来使它的灵活性更强。

如果给定了QUICK,则REPAIR TABLE会尝试只修复索引树。这种类型的修复与使用myisamchk --recover --quick相似。

如果您使用EXTENDED,则MySQL会一行一行地创建索引行,代替使用分类一次创建一个索引。这种类型的修复与使用myisamchk --safe-recover相似。

对于REPAIR TABLE,还有一种USE_FRM模式可以利用。如果.MYI索引文件缺失或标题被破坏,则使用此模式。在这种模式下,MySQL可以使用来自.frm文件重新创建.MYI文件。这种修复不能使用myisamchk来完成。 注释:只能在您不能使用常规REPAIR模式是,才能使用此模式。.MYI标题包含重要的表元数据(特别是,当前的AUTO_INCREMENT值和Delete链接)。这些元数据在REPAIR...USE_FRM中丢失。如果表被压缩,则不能使用USE_FRM。因为本信息也存储在.MYI文件中。

REPAIR TABLE语句被写入二进制日志中,除非使用了自选的NO_WRITE_TO_BINLOG关键词(或其别名LOCAL)。

警告:如果在REPAIR TABLE运行过程中,服务器停机,则在重新启动之后,在执行其它操作之前,您必须立刻对表再执行一个REPAIR TABLE语句。(通过制作一个备份来启动是一个好办法。)再最不利情况下,您可以有一个新的干净的索引文件,不含有关数据文件的信息。然后,您执行的下一个操作会覆盖数据文件。这很少发生,但是是有可能的。

13.5.2.7. RESTORE TABLE语法

RESTORE TABLE tbl_name [, tbl_name] ... FROM '/path/to/backup/directory'

用于恢复来自用BACKUP TABLE制作的备份的表。原有的表不会被覆盖;如果您试图覆盖一个原有的表,会发生错误。和BACKUP TABLE一样,RESTORE TABLE目前只对MyISAM表起作用。目录应被指定为一个完整路径名。

每个表的备份包括其.frm格式文件和.MYD数据文件。恢复操作会恢复这些文件,然后使用这些文件来重建.MYI索引文件。恢复操作比备份操作花的时间更长,这是因为需要重建索引。表含有的索引越多,花的时间就越长。

该语句会返回一个含有以下列的表:

Table

表名称

Op

进行恢复

Msg_type

状态、错误、信息或警告之一

Msg_text

消息

关注编程学问公众号