### 7.6.3 如何修复 MyISAM 表

[](<>)[](<>)

本节中的讨论描述了如何使用[**迈萨姆奇克**](myisamchk.html)在`MyISAM`表（扩展`。我的我`和`.MYD`）。

您还可以使用[`检查表`](check-table.html)和[`维修台`](repair-table.html)检查和维修的声明`MyISAM`表。看[第 13.7.3.2 节，“CHECK TABLE 语句”](check-table.html)， 和[第 13.7.3.5 节，“REPAIR TABLE 语句”](repair-table.html).

损坏表的症状包括意外中止的查询和可观察到的错误，例如：

-   找不到文件`*`tbl_name`*。我的我`（错误代码：*`nnn`*)

-   文件意外结束

-   记录文件崩溃

-   出现错误*`nnn`*从表处理程序

    要获取有关错误的更多信息，请运行[**错误**](perror.html) *`nnn`*， 在哪里*`nnn`*是错误号。下面的例子展示了如何使用[**错误**](perror.html)查找表示表格问题的最常见错误编号的含义：


```
$> 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.html)增加`MAX_ROWS`和`AVG_ROW_LENGTH`表选项值：

```
ALTER TABLE tbl_name MAX_ROWS=xxx AVG_ROW_LENGTH=yyy;
```

如果您不知道当前表选项值，请使用[`显示创建表`](show-create-table.html).

对于其他错误，您必须修复您的表。[**迈萨姆奇克**](myisamchk.html)通常可以检测并修复发生的大多数问题。

修复过程涉及多达三个阶段，如下所述。在开始之前，您应该将位置更改为数据库目录并检查表文件的权限。在 Unix 上，确保它们可以被用户读取[**mysqld**](mysqld.html)运行为（对你来说，因为你需要访问你正在检查的文件）。如果事实证明您需要修改文件，它们也必须是您可写的。

本节适用于表检查失败的情况（例如在[第 7.6.2 节，“如何检查 MyISAM 表的错误”](myisam-check.html))，或者您想使用扩展功能[**迈萨姆奇克**](myisamchk.html)提供。

这[**迈萨姆奇克**](myisamchk.html)用于表维护的选项在[第 4.6.4 节，“myisamchk - MyISAM 表维护实用程序”](myisamchk.html).[**迈萨姆奇克**](myisamchk.html)还可以设置一些变量来控制内存分配，从而提高性能。看[第 4.6.4.6 节，“myisamchk 内存使用”](myisamchk-memory.html).

如果要从命令行修复表，必须先停止[**mysqld**](mysqld.html)服务器。请注意，当你这样做[**mysqladmin 关闭**](mysqladmin.html)在远程服务器上，[**mysqld**](mysqld.html)服务器在一段时间后仍然可用[**mysql管理员**](mysqladmin.html)返回，直到所有语句处理停止并且所有索引更改都已刷新到磁盘。

**第 1 阶段：检查您的表格**

跑步[**迈萨姆奇克\*。我的我**](myisamchk.html)要么[**myisamchk -e\*。我的我**](myisamchk.html)如果你有更多的时间。使用`-s`（静默）选项以抑制不必要的信息。

如果[**mysqld**](mysqld.html)服务器已停止，您应该使用[`--更新状态`](myisamchk-check-options.html#option_myisamchk_update-state)告诉的选项[**迈萨姆奇克**](myisamchk.html)将表格标记为“已检查”。

你只需要修复那些表[**迈萨姆奇克**](myisamchk.html)宣布错误。对于此类表格，请进入第 2 阶段。

如果您在检查时遇到意外错误（例如`记不清`错误），或者如果[**迈萨姆奇克**](myisamchk.html)崩溃，进入第 3 阶段。

**第 2 阶段：轻松安全维修**

第一次尝试[**myisamchk -r -q*`tbl_name`***](myisamchk.html)(`-r -q`表示“快速恢复模式”）。这会尝试在不接触数据文件的情况下修复索引文件。如果数据文件包含它应该包含的所有内容并且删除链接指向数据文件中的正确位置，那么这应该可以工作，并且表是固定的。开始修理下一张桌子。否则，请使用以下过程：

1.  在继续之前备份数据文件。

2.  采用[**myisamchk -r*`tbl_name`***](myisamchk.html)(`-r`表示“恢复模式”）。这会从数据文件中删除不正确的行和已删除的行并重建索引文件。

3.  如果上一步失败，请使用[**myisamchk --安全恢复*`tbl_name`***](myisamchk.html).安全恢复模式使用一种旧的恢复方法，可以处理一些常规恢复模式不能处理的情况（但速度较慢）。

笔记

如果您希望修复操作进行得更快，您应该设置[`排序缓冲区大小`](server-system-variables.html#sysvar_sort_buffer_size)和[`key_buffer_size`](server-system-variables.html#sysvar_key_buffer_size)运行时每个变量占可用内存的 25% 左右[**迈萨姆奇克**](myisamchk.html).

如果您在修复时遇到意外错误（例如`内存不足`错误），或者如果[**myisamchk**](myisamchk.html)坠机，进入第三阶段。

**第三阶段：修复困难**

只有当索引文件中的第一个16KB块被破坏或包含不正确的信息，或者索引文件丢失时，才应达到此阶段。在这种情况下，有必要创建一个新的索引文件。按以下步骤进行：

1.  将数据文件移到安全的地方。

2.  使用表格描述文件创建新（空）数据和索引文件：

    ```
    $> mysql db_name
    ```

    ```
    mysql> SET autocommit=1;
    mysql> TRUNCATE TABLE tbl_name;
    mysql> quit
    ```

3.  将旧数据文件复制回新创建的数据文件。（不要只是将旧文件移回新文件。你要保留一份副本，以防出现问题。）

重要的

如果您使用的是复制，您应该在执行上述过程之前停止它，因为它涉及文件系统操作，MySQL不会记录这些操作。

回到第二阶段。[**通过简单修复**](myisamchk.html)应该有用。（这不应该是一个无休止的循环。）

你也可以使用`修理台*`tbl\_名称`*使用`SQL语句，自动执行整个过程。在实用程序和服务器之间也不存在不必要的交互，因为当您使用时，服务器会完成所有工作[`修理台`](repair-table.html)看见[第13.7.3.5节，“维修表声明”](repair-table.html).
