使用myisamchk对MyISAM数据表维护和崩溃恢复
本节讨论如何使用myisamchk的检查或修复MyISAM
表(有表.MYD
和.MYI
用于存储数据和索引文件)。有关myisamchk的一般背景,请参见“myisamchk-MyISAM表维护实用程序”。其他表修复信息可以在“重建或修复表或索引”中找到。
您可以使用myisamchk检查,修复或优化数据库表。以下各节描述如何执行这些操作以及如何设置表维护时间表。有关使用myisamchk获取有关表的信息,
尽管使用myisamchk进行表修复非常安全,但是在进行修复或任何可能对表进行大量更改的维护操作之前进行备份始终是一个好主意。
影响索引的 myisamchk操作可能导致MyISAM
FULLTEXT
使用全文参数重建索引,这些全文参数与MySQL服务器使用的值不兼容。为避免此问题,请遵循“ myisamchk常规选项”中的准则。
MyISAM
表维护还可以使用SQL语句完成,该语句执行与myisamchk可以执行的操作类似的操作:
- 要检查
MyISAM
表,请使用CHECK TABLE
。 - 要修复
MyISAM
表,请使用REPAIR TABLE
。 - 要优化
MyISAM
表,请使用OPTIMIZE TABLE
。 - 要分析
MyISAM
表,请使用ANALYZE TABLE
。
有关这些语句的更多信息,请参见“MySQL命令行工具”。
这些语句可以直接使用,也可以通过mysqlcheck客户程序使用。与myisamchk相比,这些语句的优势之一是服务器可以完成所有工作。使用myisamchk时,必须确保服务器不会同时使用这些表,以便myisamchk与服务器之间不会发生不必要的交互。
使用myisamchk进行崩溃恢复
本节介绍如何检查和处理MySQL数据库中的数据损坏。如果表经常损坏,则应尝试查找原因。请参见第B.4.3.3节“如果MySQL继续崩溃,该怎么办”。
有关如何MyISAM
损坏表的说明,请参见“ MyISAM表问题”。
如果在禁用外部锁定的情况下运行mysqld(这是默认设置),则当mysqld使用同一表时,不能可靠地使用myisamchk检查表。如果可以确定在运行myisamchk时没有人可以通过mysqld访问表,则只需在开始检查表之前执行mysqladmin flush- tables。如果不能保证这一点,则在检查表时必须停止mysqld。如果运行myisamchk来检查mysqld表在同一时间更新时,即使表没有损坏,您也可能会收到警告,指出该表已损坏。
如果服务器在启用了外部锁定的情况下运行,则可以随时使用myisamchk检查表。在这种情况下,如果服务器尝试更新myisamchk正在使用的表,则服务器将等待myisamchk完成后才能继续。
如果使用myisamchk来修复或优化表,则必须始终确保mysqld服务器未使用该表(如果禁用了外部锁定,这也适用)。如果不停止mysqld,则至少应在运行myisamchk之前执行mysqladmin flush-tables。如果服务器和myisamchk同时访问表,则表可能已损坏。
执行崩溃恢复时,重要的是要了解数据库中的每个MyISAM
表都tbl_name
与下表中显示的数据库目录中的三个文件相对应。
文件 | 目的 |
---|---|
tbl_name.MYD | 资料档案 |
tbl_name.MYI | 索引文件 |
这三种文件类型中的每一种都以各种方式受到破坏,但是问题最常发生在数据文件和索引文件中。
myisamchk.MYD
通过逐行创建数据文件的副本来工作。它通过删除旧.MYD
文件并将新文件重命名为原始文件名来结束修复阶段。如果使用--quick
,myisamchk不会创建临时.MYD
文件,而是假定该.MYD
文件正确,并且仅生成新的索引文件而不触动该.MYD
文件。这是安全的,因为 myisamchk会自动检测.MYD
文件是否损坏,如果文件损坏,则中止修复。您也可以--quick
为 myisamchk指定两次该选项。在这种情况下,myisamchk不会因某些错误(例如重复键错误)而中止,而是尝试通过修改.MYD
文件来解决它们。通常,--quick
只有在可用磁盘空间不足以进行正常修复时,才使用两个选项。在这种情况下,至少应在运行 myisamchk之前对表进行备份。
如何检查MyISAM表中的错误
要检查MyISAM
表,请使用以下命令:
myisamchk
tbl_name
发现所有错误的99.99%。它找不到的是仅涉及数据文件的损坏(非常不寻常)。如果要检查表,通常应运行不带选项或带有(静默)选项的myisamchk
-s
。myisamchk -m
tbl_name
发现所有错误的99.999%。它首先检查所有索引条目是否有错误,然后读取所有行。它计算行中所有键值的校验和,并验证校验和与索引树中键的校验和是否匹配。
myisamchk -e
tbl_name
这将对所有数据进行完整而彻底的检查(
-e
即“扩展检查”)。它对每一行的每个键进行检查读取,以验证它们确实指向正确的行。对于具有许多索引的大型表,这可能需要很长时间。通常,myisamchk在找到第一个错误后停止。如果要获取更多信息,可以添加-v
(详细)选项。这将导致myisamchk继续运行,最多出现20个错误。myisamchk -e -i
tbl_name
这类似于上一个命令,但是该
-i
选项告诉myisamchk打印其他统计信息。
在大多数情况下,一个简单的myisamchk命令,除了表名外,不带其他参数就足以检查一个表。
如何修复MyISAM表
本节中的讨论描述了如何在表(扩展名和)上使用myisamchk。MyISAM
.MYI
.MYD
您也可以使用CHECK TABLE
and REPAIR TABLE
语句检查和修复MyISAM
表。请参见“ CHECK TABLE语句”和“ REPAIR TABLE语句”。
损坏的表的症状包括查询意外中止和可观察到的错误,例如:
- 找不到文件
tbl_name.MYI
(ERRCODE:nnn
) - 文件意外结束
- 记录文件已崩溃
nnn
表处理程序出现错误
要获取有关错误的更多信息,请运行perrornnn
,其中nnn
错误号为。下面的示例演示如何使用perror查找最常见的错误编号的含义,这些错误编号指示表存在问题:
shell>perror 126 127 132 134 135 136 141 144 145 MySQL error code 126 = Index file is crashed MySQL error code 127 = Record-file is crashed MySQL error code 132 = Old database file MySQL error code 134 = Record was already deleted (or record file crashed) MySQL error code 135 = No more room in record file MySQL error code 136 = No more room in index file MySQL error code 141 = Duplicate unique key or constraint on write or update MySQL error code 144 = Table is crashed and last repair failed MySQL error code 145 = Table was marked as crashed and should be repaired
请注意,错误135(记录文件中没有更多空间)和错误136(索引文件中没有更多空间)不是可以通过简单修复即可修复的错误。在这种情况下,必须使用ALTER TABLE
增加MAX_ROWS
和AVG_ROW_LENGTH
表选项的值:
ALTER TABLE tbl_nameMAX_ROWS =xxxAVG_ROW_LENGTH =yyy;
如果您不知道当前表选项的值,请使用SHOW CREATE TABLE
。
对于其他错误,您必须修复表。myisamchk通常可以检测并修复大多数发生的问题。
维修过程包括以下三个阶段。在开始之前,您应该将位置更改为数据库目录并检查表文件的权限。在Unix上,请确保mysqld的运行用户(以及您自己,因为您需要访问要检查的文件)可以读取它们。如果事实证明您需要修改文件,那么它们也必须是可写的。
本节适用于表检查失败的情况(例如“如何检查MyISAM表中的错误”中所述),或者您要使用myisamchk提供的扩展功能。
“myisamchk-MyISAM表维护实用程序”中介绍了用于表维护的myisamchk选项。myisamchk还具有一些变量,您可以设置这些变量来控制内存分配,以提高性能。请参见“ myisamchk内存使用情况”。
如果要从命令行修复表,则必须首先停止mysqld服务器。请注意,当您在远程服务器上执行mysqladmin shutdown时,在mysqladmin返回之后,mysqld服务器仍然可以使用一段时间,直到所有语句处理停止并且所有索引更改都已刷新到磁盘上为止。
阶段1:检查表格
如果有更多时间,请运行myisamchk *.MYI或myisamchk -e *.MYI。使用-s
(静默)选项可消除不必要的信息。
如果mysqld服务器已停止,则应使用该--update-state
选项告诉myisamchk将表标记为“已选中”。”
您只需要修复myisamchk宣布错误的表。对于此类表,请转到阶段2。
如果在检查时遇到意外错误(例如out of memory
错误),或者myisamchk崩溃,请转到阶段3。
第二阶段:轻松安全维修
首先,尝试myisamchk -r -q tbl_name
(-r -q
表示“快速恢复模式”)。这将尝试修复索引文件而不接触数据文件。如果数据文件包含应有的所有内容,并且删除链接指向数据文件内的正确位置,则此操作应该起作用,并且表已修复。开始修复下表。否则,请使用以下过程:
- 在继续之前,请备份数据文件。
- 使用myisamchk -r
tbl_name
(-r
表示“恢复模式”)。这将从数据文件中删除不正确的行和已删除的行,并重建索引文件。 - 如果前面的步骤失败,请使用myisamchk --safe-recover
tbl_name
。安全恢复模式使用一种旧的恢复方法,该方法可以处理一些常规恢复模式无法解决的问题(但速度较慢)。
注意如果希望修复操作快得多,则在运行myisamchk时,应将
sort_buffer_size
和key_buffer_size
变量的值分别设置为可用内存的25%左右。
如果在修复时遇到意外错误(例如out of memory
错误),或者myisamchk崩溃,请转到阶段3。
阶段3:难以维修
仅当索引文件中的第一个16KB块被破坏或包含不正确的信息,或者缺少索引文件时,才应进入此阶段。在这种情况下,有必要创建一个新的索引文件。这样做如下:
- 将数据文件移到安全的地方。
使用表描述文件来创建新的(空)数据和索引文件:
shell>
mysql db_namemysql>
SET autocommit=1; mysql>TRUNCATE TABLE tbl_name; mysql> quit- 将旧数据文件复制回新创建的数据文件。(不要只是将旧文件移回新文件。您要保留副本,以防出现问题。)
重要如果使用的是复制,则应在执行上述过程之前将其停止,因为它涉及文件系统操作,并且这些操作不会由MySQL记录。
返回到阶段2。myisamchk -r -q应该可以工作。(这不应是一个无限循环。)
您还可以使用SQL语句,该语句自动执行整个过程。实用程序和服务器之间也不会发生不必要的交互,因为使用时服务器会完成所有工作。请参见“ REPAIR TABLE语句”。REPAIR TABLE tbl_name USE_FRM
REPAIR TABLE
MyISAM表优化
要合并碎片行并消除由于删除或更新行而导致的空间浪费,请在恢复模式下运行myisamchk:
shell>myisamchk -r tbl_name
您可以使用OPTIMIZE TABLE
SQL语句以相同的方式优化表。OPTIMIZE TABLE
进行表修复和键分析,并对索引树进行排序,以使键查找更快。实用程序和服务器之间也不会发生不必要的交互,因为使用时服务器会完成所有工作OPTIMIZE TABLE
。请参见“ OPTIMIZE TABLE语句”。
myisamchk还有许多其他选项可用于改善表的性能:
--analyze
或-
:执行密钥分布分析。通过使联接优化器更好地选择联接表的顺序和应使用的索引,可以提高联接性能。--sort-index
或-S
:对索引块进行排序。这样可以优化查找,并使使用索引的表扫描更快。--sort-records=index_num
或:根据给定的索引对数据行进行排序。这使您的数据更加本地化,并可能加快基于范围的索引和使用该索引的操作。-R index_num
SELECT
ORDER BY
有关所有可用选项的完整说明,请参见“myisamchk-MyISAM表维护实用程序”。
设置MyISAM表维护计划
定期执行表检查而不是等待问题发生是一个好主意。检查和修复MyISAM
表的一种方法是使用CHECK TABLE
nd REPAIR TABLE
语句。请参见“MySQL命令行工具”。
检查表的另一种方法是使用myisamchk。为了维护目的,可以使用myisamchk -s。该-s
选项(的缩写--silent
)使myisamchk以静默方式运行,仅在发生错误时才打印消息。
启用自动MyISAM
表检查也是一个好主意。例如,每当计算机在更新过程中完成重新启动时,通常都需要先检查每个可能受到影响的表,然后再使用它。(这些是“预期崩溃的表。”)要使服务器MyISAM
自动检查表,请使用myisam_recover_options
系统变量集启动它。请参见“服务器系统变量”。
您还应该在正常系统运行期间定期检查表。例如,您可以运行cron作业来每周检查一次重要的表,在crontab
文件中使用以下行:
35 0 * * 0 /path/to/myisamchk --fast --silent /path/to/datadir/*/*.MYI
这将打印出有关崩溃表的信息,以便您可以根据需要检查和修复它们。
首先,每晚在过去24小时内已更新的所有表上执行myisamchk -s。如您所见,问题很少发生,您可以将检查频率推迟到每周一次左右。
通常,MySQL表几乎不需要维护。如果您要对MyISAM
具有动态大小的行的表(带有VARCHAR
,BLOB
或TEXT
列的表)执行许多更新,或者具有删除了许多行的表,则可能需要不时对表进行碎片整理/回收。您可以通过OPTIMIZE TABLE
在有关表上使用来执行此操作。或者,如果可以暂时停止mysqld服务器,则在服务器停止时将位置更改为数据目录并使用以下命令:
shell>myisamchk -r -s --sort-index --myisam_sort_buffer_size=16M */*.MYI