15.7.3.2 检查表语句
CHECK TABLE tbl_name [, tbl_name] ... [option] ...
option: {
FOR UPGRADE
| QUICK
| FAST
| MEDIUM
| EXTENDED
| CHANGED
}
CHECK TABLE 检查一个或多个表是否存在错误。CHECK TABLE 也可以检查视图中的问题,例如在视图定义中引用的表已经不存在了。
要检查一个表,您必须对其拥有某种权限。
CHECK TABLE 可以用于 InnoDB、MyISAM、ARCHIVE 和 CSV 表。
在对InnoDB 表运行CHECK TABLE 前,见InnoDB表的CHECK TABLE使用说明。
CHECK TABLE 对分区表支持,您可以使用 ALTER TABLE ... CHECK PARTITION 检查一个或多个分区;更多信息,请见第15.1.9节,“ALTER TABLE 语句”,和第26.3.4节,“分区维护”.
CHECK TABLE 忽略未索引的虚拟生成列。
CHECK TABLE 返回一个结果集,列名如以下表所示。
| Column | Value |
|---|---|
Table |
表名称 |
Op |
总是 check |
Msg_type |
status, error, info, note, 或 warning |
Msg_text |
一个信息性消息 |
该语句可能为每个检查的表生成多行信息。最后一行的 Msg_type 值为 status,Msg_text 通常应该是 OK。Table is already up to date 表示该表的存储引擎指出没有必要检查该表。
使用 FOR UPGRADE 选项检查指定的表是否与当前 MySQL 版本兼容。使用 FOR UPGRADE,服务器将检查每个表,以确定自该表创建以来是否有任何不兼容的数据类型或索引变化。如果没有,检查成功。否则,如果存在可能的不兼容情况,服务器对该表进行全量检查(可能需要一些时间)。
不兼容可能是因为数据类型存储格式发生了改变或排序顺序发生了改变。我们的目标是避免这些变化,但有时它们是必要的,以解决与版本之间更糟糕的问题。
FOR UPGRADE 发现这些不兼容情况:
-
InnoDB 和 MyISAM 表中的
TEXT列的索引顺序在 MySQL 4.1 和 5.0 之间发生了变化。 -
MySQL 5.0.3 和 5.0.5 之间,
DECIMAL数据类型的存储方法发生了变化。 -
有时会对字符集或排序规则进行修改,要求重建表索引。关于这些变化的详细信息,请参阅第3.5节,“MySQL 8.4 的变化”。关于重建表的信息,请参阅第3.14节,“重建或修复表或索引”。
-
MySQL 8.4 不支持 MySQL 旧版本中的 2 位
YEAR(2)数据类型。包含YEAR(2)列的表,CHECK TABLE建议REPAIR TABLE,将 2 位YEAR(2)列转换为 4 位YEAR列。 -
触发器创建时间被维护。
-
如果表包含5.6.4之前的时间戳列 (
TIME,DATETIME,TIMESTAMP列没有小数秒精度支持),那么表将被报告需要重建。这有助于 MySQL 升级过程检测和升级包含老时间戳列的表。 -
对于使用非本地分区的表,会出现警告,因为在 MySQL 8.4 中移除了非本地分区。见第26章,分区。
以下表格显示了可以给出的其他检查选项。这些选项将被传递给存储引擎,可能使用或忽略它们。
| Type | Meaning |
|---|---|
QUICK |
不扫描行以检查错误链接。适用于 InnoDB 和 MyISAM 表和视图。 |
FAST |
只检查未关闭的表。忽略 InnoDB,仅适用于 MyISAM 表和视图。 |
CHANGED |
只检查自上次检查以来或未关闭的表。忽略 InnoDB,仅适用于 MyISAM 表和视图。 |
MEDIUM |
扫描行以验证删除的链接是否有效。这也计算了行的键校验和验证与键的计算校验。忽略 InnoDB,仅适用于 MyISAM 表和视图。 |
EXTENDED |
对每行进行全键查找。这确保了表的100%一致,但花费很长时间。忽略 InnoDB,仅适用于 MyISAM 表和视图。 |
您可以组合检查选项,如以下示例,快速检查表以确定是否关闭正确:
CHECK TABLE test_table FAST QUICK;
如果CHECK TABLE 对于标记为““损坏” 或 ““未关闭正确” 的表找到问题,CHECK TABLE 可能删除标记。
如果表损坏,问题通常在索引中,而不是数据部分。所有前面的检查类型都对索引进行了充分的检查,因此应该找到大多数错误。
要检查您认为是好的表,请不要使用检查选项或使用 QUICK 选项。后者在您匆忙时可以使用,但需要承担很小的风险,即 QUICK 可能不会找到数据文件中的错误。在大多数情况下,MySQL 应该找到数据文件中的错误。如果发生这种情况,表将被标记为““损坏”,直到修复后才能使用。
FAST 和 CHANGED 主要用于从脚本中执行(例如,使用 cron 定时检查表)。大多数情况下,FAST 都比 CHANGED 更好用。唯一的例外是你怀疑在 MyISAM 代码中发现了bug。
EXTENDED 只有在你已经运行正常检查,但仍然从表中获取错误时使用 MySQL 更新行或根据键查找行。这很少出现,如果正常检查成功。
使用 CHECK TABLE ... EXTENDED 可能会影响查询优化器生成的执行计划。
CHECK TABLE 报告的一些问题无法自动修复:
-
Found row where the auto_increment column has the value 0.这意味着你在表中有一个行,其中
AUTO_INCREMENT索引列包含值 0。可以通过使用UPDATE语句来创建一个行,其中AUTO_INCREMENT列是 0。这本身不是错误,但如果你决定dump表并恢复它或对表执行
ALTER TABLE,那么AUTO_INCREMENT列的值将根据AUTO_INCREMENT列的规则变化,这可能会导致问题,如重复键错误。要消除警告,可以执行
UPDATE语句将列设置为其他值非0。
InnoDB 表CHECK TABLE 使用注意
以下注意适用于InnoDB表:
-
如果
CHECK TABLE遇到损坏的页面,服务器将退出以防止错误传播(Bug #10132)。如果损坏发生在次要索引中,但表数据可读,执行CHECK TABLE仍然可能会导致服务器退出。 -
如果
CHECK TABLE遇到聚簇索引中的损坏DB_TRX_ID或DB_ROLL_PTR字段,CHECK TABLE可能会访问无效的回滚日志记录,从而导致MVCC-相关服务器退出。 -
如果
CHECK TABLE遇到InnoDB表或索引中的错误,它报告错误,通常将索引标记为损坏,有时也将表标记为损坏,从而防止对索引或表的进一步使用。这些错误包括次要索引中的条目数量不正确或链接不正确。 -
如果
CHECK TABLE发现次要索引中的条目数量不正确,它报告错误,但不会导致服务器退出或防止对文件的访问。 -
CHECK TABLE检查索引页结构,然后检查每个键条目。它不验证聚簇记录的键指针或跟随BLOB指针。 -
当
InnoDB表存储在自己的.ibd文件中,.ibd文件的前三个页包含头信息,而不是表或索引数据。CHECK TABLE语句不能检测只影响头数据的不一致。要验证整个InnoDB.ibd文件内容,使用innochecksum 命令。 -
在对大型
CHECK TABLE执行时,其他线程可能会被阻塞。为了避免超时,InnoDB将信号量等待阈值(600秒)延长为7200秒,以便CHECK TABLE操作。如果InnoDB检测到信号量等待240秒或更长,它将开始在错误日志中打印InnoDB监控输出。如果锁请求超出了信号量等待阈值,InnoDB将中止进程。为了避免信号量等待超时完全,运行CHECK TABLE QUICK而不是CHECK TABLE。 -
CHECK TABLE对InnoDB SPATIAL 索引支持R树有效性检查和确保R树行数与聚簇索引匹配。 -
CHECK TABLE支持虚拟生成列的次要索引,InnoDB也支持虚拟生成列。 -
InnoDB支持并行集群索引读取,可以提高CHECK TABLE性能。InnoDB在CHECK TABLE操作中读取集群索引两次。第二次读取可以并行进行。innodb_parallel_read_threads会话变量必须设置为大于 1 的值,以便并行集群索引读取发生。实际用于并行集群索引读取的线程数由innodb_parallel_read_threads设置或要扫描的索引子树数量,取小者确定。
MyISAM 表CHECK TABLE 使用注意
以下注意适用于MyISAM 表:
-
CHECK TABLE更新MyISAM表的键统计信息。 -
如果
CHECK TABLE输出不返回OK或Table is already up to date第9.6节,“MyISAM 表维护和崩溃恢复”。 -
如果未指定CHECK TABLE选项QUICK、MEDIUM或EXTENDED,动态格式的MyISAM表的默认检查类型为MEDIUM。这与在表上运行myisamchk --medium-checktbl_name相同。静态格式的MyISAM表的默认检查类型也为MEDIUM,除非指定CHANGED或FAST,否则默认为QUICK。由于行很少损坏,所以对CHANGED和FAST不进行行扫描。