首页 > 数据库 > > 7.6 MyISAM 表维护和崩溃恢复
参考官方文档:
https://dev.mysql.com/doc/refman/5.7/en/myisam-table-maintenance.html
本节讨论如何使用myisamchk检查或修复MyISAM表(具有.MYD和.MYI文件的表格用于存储数据和索引)。
您可以使用myisamchk来检查,修复或优化数据库表。 以下各节介绍如何执行这些操作以及如何设置表维护计划。
尽管使用myisamchk进行表修复是非常安全的,但在进行修复或任何可能会对表格进行大量修改的维护操作之前进行备份始终是个好主意。
影响索引的myisamchk操作可能会导致使用与MySQL服务器使用的值不兼容的全文参数重建MyISAM FULLTEXT索引。 为避免此问题,请按照第4.6.3.1节“myisamchk常规选项”中的指导进行操作。
MyISAM表维护也可以使用执行类似于myisamchk可以执行的操作的SQL语句完成:
这些语句可以直接使用或通过mysqlcheck客户端程序使用。 这些对myisamchk的语句的一个优点是服务器完成所有工作。 使用myisamchk时,您必须确保服务器不会同时使用这些表,这样myisamchk和服务器之间就不会发生不必要的交互。
7.6.1 为崩溃恢复使用myisamchk
本节介绍如何检查和处理MySQL数据库中的数据损坏。 如果你的表经常被破坏,你应该试着找出原因。
如果在禁用外部锁定的情况下运行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对应下表所示的数据库目录中的三个文件是很重要的。
File
Purpose
tbl_name.frm
定义(格式)文件
tbl_name.MYD
数据文件
tbl_name.MYI
索引文件
这三种文件类型中的每一种都受到各种方式的破坏,但是在数据文件和索引文件中经常出现问题。
myisamchk通过逐行创建.MYD数据文件的副本来工作。 它通过删除旧的.MYD文件并将新文件重命名为原始文件名来结束修复阶段。 如果使用--quick,则myisamchk不会创建临时.MYD文件,而是会假定.MYD文件是正确的,并且只生成新的索引文件而不触及.MYD文件。 这是安全的,因为myisamchk会自动检测.MYD文件是否损坏,如果是,则中止修复。 您还可以将两次--quick选项指定给myisamchk。 在这种情况下,myisamchk不会中止某些错误(如重复键错误),而是尝试通过修改.MYD文件来解决它们。 通常情况下,只有在可用磁盘空间太少才能执行正常修复时,使用两个--quick选项才有用。 在这种情况下,您至少应该在运行myisamchk之前备份表。
7.6.2 如何检查Myisam 表的错误
要检查MyISAM表,请使用以下命令:
其能找到99.99%的所有错误。 它无法找到的是仅涉及数据文件的损坏(这非常不寻常)。 如果你想检查一个表,你通常应该运行myisamchk而不使用任何选项或使用-s(silent)选项。
其找到99.999%的所有错误。 它首先检查所有索引条目的错误,然后读取所有行。 它计算行中所有键值的checksum,并验证checksum 和与索引树中键的checksum是否匹配。
这会对所有数据进行全面彻底的检查(-e表示“扩展检查”)。 它会对每一行的每个键进行检查读取,以确认它们确实指向了正确的行。 对于有很多索引的大表来说,这可能需要很长时间。 通常,myisamchk在找到第一个错误后停止。 如果您想获得更多信息,可以添加-v(详细)选项。 这导致myisamchk继续前进,最多发生20次错误。
这与前面的命令类似,但-i选项告诉myisamchk打印其他统计信息。
在大多数情况下,一个简单的myisamchk命令不需要表名以外的参数就足以检查一个表。
7.6.3 如何修复 Myisam 表
本节中的讨论描述了如何在MyISAM表(扩展名.MYI和.MYD)上使用myisamchk。
损坏的表的症状包括异常中止以及可观察到的错误的查询,例如:
要获得有关错误的更多信息,请运行perror nnn,其中nnn是错误编号。 以下示例显示如何使用perror来查找指示表存在问题的最常见错误编号的含义:
shell> perro 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_name MAX_ROWS=xxx AVG_ROW_LENGTH=yyy;
如果您不知道当前表选项值,请使用SHOW CREATE TABLE。
对于其他错误,您必须修复您的表格。 myisamchk通常可以检测并修复大多数发生的问题。
修复过程涉及多达四个阶段,如下所述。 在开始之前,您应该将位置更改为数据库目录并检查表文件的权限。 在Unix上,确保它们可以被mysqld运行的用户读取(并且由于您需要访问正在检查的文件)。 如果事实证明您需要修改文件,则它们也必须由您写入。
本节适用于表检查失败的情况(例如第7.6.2节“如何检查MyISAM表中是否有错误”中所述),或者您想使用myisamchk提供的扩展功能。
第4.6.3节“myisamchk - MyISAM表维护实用程序”中介绍了用于维护表的myisamchk选项。 myisamchk也有变量,您可以设置控制内存分配,可以提高性能。
如果您要从命令行修复表,您必须先停止mysqld服务器。 请注意,当您在远程服务器上执行mysqladmin shutdown时,在mysqladmin返回后mysqld服务器仍可用一段时间,直到所有语句处理已停止并且所有索引更改已刷新到磁盘。
阶段1:检查你的表
如果您有更多时间,请运行myisamchk * .MYI或myisamchk -e * .MYI。 使用-s(静默)选项来抑制不必要的信息。
如果mysql服务器已停止,则应使用--update-state选项告诉myisamchk将该表标记为“已检查”。
您只能修复myisamchk发布错误的表。 对于这样的表,进入第2阶段。
如果在检查时出现意外错误(例如内存不足错误),或者myisamchk崩溃,请转到第3阶段。
阶段2:简单安全修复
首先,尝试myisamchk -r -q tbl_name(-r -q表示“快速恢复模式”)。 这会尝试修复索引文件而不触及数据文件。 如果数据文件包含它应该包含的所有内容,并且删除链接指向数据文件中的正确位置,则应该可以工作,并且表格已修复。 开始修复下一张表。 否则,请使用以下步骤:
注意:
如果您希望修复操作变得更快,则应在运行myisamchk时将sort_buffer_size和key_buffer_size变量的值分别设置为可用内存的25%。
如果修复时出现意外错误(例如内存不足错误),或者myisamchk崩溃,请转到阶段3。
阶段3:困难修复
只有当索引文件中的第一个16KB块被销毁或包含不正确的信息时,或者索引文件丢失时,才应该到达此阶段。 在这种情况下,有必要创建一个新的索引文件。 这样做如下:
shell> mysql db_name
mysql> SET autocommit=1;
mysql> TRUNCATE TABLE tbl_name;
mysql> quit
重要:
如果您正在使用复制,则应在执行上述过程之前停止它,因为它涉及文件系统操作,并且这些操作不会被MySQL记录。
回到阶段2。myisamchk -r -q应该可以工作。 (这不应该是一个无限循环。)
您也可以使用REPAIR TABLE tbl_name USE_FRM SQL语句,该语句自动执行整个过程。 工具和服务器之间也不可能发生不必要的交互,因为服务器在使用REPAIR TABLE时会执行所有工作。
阶段4:非常困难的恢复
只有当.frm描述文件也崩溃时,才应该到达此阶段。 这绝不应该发生,因为描述文件在创建表之后没有更改:
7.6.4 Myisam 表优化
要合并碎片行并消除删除或更新行所导致的浪费空间,请在恢复模式下运行myisamchk:
shell> myisamchk -r tbl_name
您可以使用OPTIMIZE TABLE SQL语句以相同的方式优化一个表。 OPTIMIZE TABLE执行表修复和键分析,并对索引树进行排序,以便键查找速度更快。 工具和服务器之间也不可能发生不必要的交互,因为服务器在使用OPTIMIZE TABLE时会执行所有的工作。
myisamchk有许多其他选项可用于提高表的性能:
有关所有可用选项的完整说明,请参见第4.6.3节“myisamchk - MyISAM表维护程序”。
7.6.5 设置 Myisam 表维护调度任务
定期执行表格检查是一个好主意,而不是等待问题发生。 检查和修复MyISAM表的一种方法是使用CHECK TABLE和REPAIR TABLE语句。 请参见第13.7.2节“表维护语句”。
检查表的另一种方法是使用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表需要很少的维护。 如果您正在使用动态大小的行(包含VARCHAR,BLOB或TEXT列的表)执行多个MyISAM表更新,或者您的表具有多个已删除行,您可能需要不时从表中整理/回收空间。 您可以通过在上述表上使用OPTIMIZE TABLE来做到这一点。 或者,如果您可以暂停mysqld服务器一段时间,请将位置更改为数据目录,并在服务器停止时使用此命令:
shell> myisamchk -r -s --sort-index --myisam_sort_buffer_size=16M */*.MYI
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/69946831/viewspace-3151370/ ,如需转载,请注明出处,否则将追究法律责任。