当前位置: 首页 > 文档资料 > MySQL 中文手册 >

5.9. 备份与恢复

优质
小牛编辑
157浏览
2023-12-01
5.9.1. 数据库备份
5.9.2. 示例用备份与恢复策略
5.9.3. 自动恢复
5.9.4. 表维护和崩溃恢复
5.9.5. myisamchk:MyISAM表维护实用工具
5.9.6. 建立表维护计划
5.9.7. 获取关于表的信息

本节讨论如何进行数据库备份(完全备份和增量备份),以及如何执行表的维护。本节描述的SQL语句语法参见第5章:数据库管理。此处提供的大多数信息主要适合MyISAM表。InnoDB备份程序参见15.2.8节,“InnoDB数据库的备份和恢复”。

5.9.1. 数据库备份

因为MySQL表保存为文件方式,很容易备份。要想保持备份的一致性,对相关表执行LOCK TABLES操作,然后对表执行FLUSH TABLES。参见13.4.5节,“LOCK TABLES和UNLOCK TABLES语法”和13.5.5.2节,“FLUSH语法”。你只需要读锁定;这样当你复制数据库目录中的文件时,允许其它客户继续查询表。需要FLUSH TABLES语句来确保开始备份前将所有激活的索引页写入硬盘。

如果你想要进行SQL级别的表备份,你可以使用SELECT INTO ...OUTFILE或BACKUP TABLE。对于SELECT INTO ...OUTFILE, 输出的文件不能先存在。对于BACKUP TABLE也如此,因为覆盖完整的文件会有安全风险。参见13.2.7节,“SELECT语法”和13.5.2.2节,“BACKUP TABLE语法”。

备份数据库的另一个技术是使用mysqldump程序或mysqlhotcopy脚本。参见8.8节,“mysqldump:数据库备份程序”和8.9节,“mysqlhotcopy:数据库备份程序”。

1. 完全备份数据库:

2.    shell> mysqldump --tab=/path/to/some/dir --opt db_name

或:

shell> mysqlhotcopy db_name /path/to/some/dir

只要服务器不再进行更新,还可以只复制所有表文件(*.frm、*.MYD和*.MYI文件)。mysqlhotcopy脚本使用该方法。(但请注意如果数据库包含InnoDB表,这些方法不工作。InnoDB不将表的内容保存到数据库目录中,mysqlhotcopy只适合MyISAM表)。

3. 如果mysqld在运行则停止,然后用--log-bin[=file_name]选项来启动。参见5.11.3节,“二进制日志”。二进制日志文件中提供了 执行mysqldump之后对数据库的更改进行复制所需要的信息。

对于InnoDB表,可以进行在线备份,不需要对表进行锁定;参见8.8节,“mysqldump:数据库备份程序”。

MySQL支持增量备份:需要用--log-bin选项来启动服务器以便启用二进制日志;参见5.11.3节,“二进制日志”。当想要进行增量备份时(包含上一次完全备份或增量备份之后的所有更改),应使用FLUSH LOGS回滚二进制日志。然后,你需要将从最后的完全或增量备份的某个时刻到最后某个点的所有二进制日志复制到备份位置。这些二进制日志为增量备份;恢复时,按照下面的解释应用。下次进行完全备份时,还应使用FLUSH LOGS或mysqlhotcopy --flushlogs回滚二进制日志。参见8.8节,“mysqldump:数据库备份程序”和8.9节,“mysqlhotcopy:数据库备份程序”。

如果MySQL服务器为从复制服务器,则无论选择什么备份方法,当备份从机数据时,还应备份master.info和relay-log.info文件。恢复了从机数据后,需要这些文件来继续复制。如果从机执行复制LOAD DATA INFILE命令,你应还备份用--slave-load-tmpdir选项指定的目录中的SQL_LOAD-*文件。(如果未指定,该位置默认为tmpdir变量值)。从机需要这些文件来继续复制中断的LOAD DATA INFILE操作。

如果必须恢复MyISAM表,先使用REPAIR TABLE或myisamchk -r来恢复。99.9%的情况下该方法可以工作。如果myisamchk失败,试试下面的方法。请注意只有用--log-bin选项启动了MySQL从而启用二进制日志它才工作;参见5.11.3节,“二进制日志”。

1. 恢复原mysqldump备份,或二进制备份。

2. 执行下面的命令重新更新二进制日志:

3.    shell> mysqlbinlog hostname-bin.[0-9]* | mysql

在某些情况下,你可能只想要从某个位置重新运行某些二进制日志。(通常你想要从恢复备份的日期重新运行所有二进制日志,查询不正确时例外)。关于mysqlbinlog工具和如何使用它的详细信息参见8.6节,“mysqlbinlog:用于处理二进制日志文件的实用工具”。

还可以对具体文件进行选择备份:

·要想复制表,使用SELECT * INTO OUTFILE 'file_name' FROM tbl_name

·要想重载表,使用LOAD DATA INFILE 'file_name' REPLACE ...并恢复。要避免复制记录,表必须有PRIMARY KEY或一个UNIQUE索引。当新记录复制唯一键值的旧记录时,REPLACE关键字可以将旧记录替换为新记录。

如果备份时遇到服务器性能问题,可以有帮助的一个策略是在从服务器而不是主服务器上建立复制并执行备份。参见6.1节,“复制介绍”。

如果使用Veritas文件系统,可以这样备份:

1. 从客户端程序执行FLUSH TABLES WITH READ LOCK。

2. 从另一个shell执行mount vxfs snapshot。

3. 从第一个客户端执行UNLOCK TABLES。

4. 从快照复制文件。

5. 卸载快照。

5.9.2. 示例用备份与恢复策略

5.9.2.1. 备份策略
5.9.2.2. 为恢复进行备份
5.9.2.3. 备份策略摘要
本节讨论进行备份的程序,在出现崩溃后,可以恢复数据:

·操作系统崩溃

·电源故障

·文件系统崩溃

·硬件问题(硬盘、母板等等)

该命令不包括mysqldumpmysql程序的--user和—password等选项。应包括必要的选项让MySQL服务器允许你连接它。

我们假定数据保存在MySQL的InnoDB存储引擎中,支持事务和自动崩溃恢复。我们假定崩溃时MySQL服务器带负载。如果不带负载,则不需要恢复。

出现操作系统崩溃或电源故障时,我们可以假定重启后硬盘上的MySQLś数据仍可用。由于崩溃,InnoDB数据文件中的数据可能不再保持一致性,但InnoDB读取它的日志并会查到挂起的提交的和未提交的事务清单,它们没有清空到数据文件中。InnoDB自动卷回未提交的事务,并清空到它的数据文件中。通过MySQL错误日志将该恢复过程相关信息传达给用户。下面的例子为日志摘录:

InnoDB: Database was not shut down normally.
InnoDB: Starting recovery from log files...
InnoDB: Starting log scan based on checkpoint at
InnoDB: log sequence number 0 13674004
InnoDB: Doing recovery: scanned up to log sequence number 0 13739520
InnoDB: Doing recovery: scanned up to log sequence number 0 13805056
InnoDB: Doing recovery: scanned up to log sequence number 0 13870592
InnoDB: Doing recovery: scanned up to log sequence number 0 13936128
...
InnoDB: Doing recovery: scanned up to log sequence number 0 20555264
InnoDB: Doing recovery: scanned up to log sequence number 0 20620800
InnoDB: Doing recovery: scanned up to log sequence number 0 20664692
InnoDB: 1 uncommitted transaction(s) which must be rolled back
InnoDB: Starting rollback of uncommitted transactions
InnoDB: Rolling back trx no 16745
InnoDB: Rolling back of trx no 16745 completed
InnoDB: Rollback of uncommitted transactions completed
InnoDB: Starting an apply batch of log records to the database...
InnoDB: Apply batch completed
InnoDB: Started
mysqld: ready for connections

如果文件系统崩溃或出现硬件问题,我们可以假定重启后硬盘上的MySQLś数据不可用。这说明MySQL未能成功启动,因为一些硬盘数据块不再可读。在这种情况下,需要重新格式化硬盘,安装一个新的,或纠正问题。然后需要从备份中恢复MySQL数据,这说明我们必须先做好备份。要想确保,应及时返回并设计备份策略。

5.9.2.1. 备份策略

我们都知道必须按计划定期进行备份。可以用几个工具完全备份(在某个时间点的数据快照)MySQL。例如,InnoDB Hot Backup为InnoDB数据文件提供在线非数据块物理备份,mysqldump提供在线逻辑备份。这里使用mysqldump

假定我们在星期日下午1点进行了备份,此时负荷较低。下面的命令可以完全备份所有数据库中的所有InnoDB表:

shell> mysqldump --single-transaction --all-databases > backup_sunday_1_PM.sql

这是在线非块备份,不会干扰对表的读写。我们以前假定我们的表为InnoDB表,因此--single-transaction使用一致性地读,并且保证mysqldump所看见的数据不会更改。(其它客户端对InnoDB表进行的更改不会被mysqldump进程看见)。如果我们还有其它类型的表,我们必须假定在备份过程中它们不会更改。例如,对于mysql数据库中的MyISAM表,我们必须假定在备份过程中没有对MySQL账户进行管理更改。

mysqldump命令产生的.sql文件包含一系列SQLINSERT语句,可以用来重载转储的表。

需要进行完全备份,但有时不方便。会产生大的备份文件并需要花时间来生成。从某个角度,完全备份并不理想,因为每个成功的完全备份包括所有数据,甚至自从上一次完全备份以来没有更改的部分。完成了初使完全备份后,进行增量备份会更有效。这样备份文件要小得多,备份时间也较短。不利之处是,恢复时不能只重载完全备份来恢复数据。还必须要用增量备份来恢复增量更改。

要想进行增量备份,我们需要保存增量更改。应使用--log-bin选项启动MySQL服务器,以便更新数据时将这些更改保存到文件中。该选项启用二进制日志,因此服务器写将每个更新数据的SQL语句写入MySQL二进制日志。让我们看看用--log-bin选项启动的已经运行多日的MySQL服务器的数据目录。我们找到以下MySQL二进制日志文件:

-rw-rw---- 1 guilhem  guilhem   1277324 Nov 10 23:59 gbichot2-bin.000001
-rw-rw---- 1 guilhem  guilhem 4 Nov 10 23:59 gbichot2-bin.000002
-rw-rw---- 1 guilhem  guilhem79 Nov 11 11:06 gbichot2-bin.000003
-rw-rw---- 1 guilhem  guilhem       508 Nov 11 11:08 gbichot2-bin.000004
-rw-rw---- 1 guilhem  guilhem 220047446 Nov 12 16:47 gbichot2-bin.000005
-rw-rw---- 1 guilhem  guilhem    998412 Nov 14 10:08 gbichot2-bin.000006
-rw-rw---- 1 guilhem  guilhem       361 Nov 14 10:07 gbichot2-bin.index

每次重启,MySQL服务器用序列中的下一个编号创建一个新的二进制日志文件。当服务器运行时,你还可以通过执行FLUSH LOGS SQL语句或mysqladmin flush-logs命令,告诉服务器关闭当前的二进制日志文件并创建一个新文件。mysqldump也有一个选项来清空日志。数据目录中的.index文件包含该目录下所有MySQL二进制日志的清单。该文件用于复制。

恢复时MySQL二进制日志很重要,因为它们是增量备份。如果进行完全备份时确保清空了日志,则后面创建的二进制日志文件包含了备份后的所有数据更改。让我们稍稍修改前面的mysqldump命令,让它在完全备份时能够清空 MySQL二进制日志,以便转储文件包含包含新的当前的二进制日志:

shell> mysqldump --single-transaction --flush-logs --master-data=2
   --all-databases > backup_sunday_1_PM.sql

执行该命令后,数据目录则包含新的二进制日志文件,gbichot2-bin.000007。结果.sql文件包含下列行:

-- Position to start replication or point-in-time 恢复时y from
-- CHANGE MASTER TO MASTER_LOG_FILE='gbichot2-bin.000007',MASTER_LOG_POS=4;

因为mysqldump命令可以执行完全备份,这些行表示两件事情:

·.sql文件包含所有写入gbichot2-bin.000007二进制日志文件或最新的文件之前的更改。

·备份后所记录的所有数据更改不出现在.sql中,但出现在gbichot2-bin.000007二进制日志文件或最新的文件中。

在星期一下午1点,我们可以清空日志开始新的二进制日志文件来创建增量备份。例如,执行mysqladmin flush-logs命令创建gbichot2-bin.000008。星期日下午1点的完全备份和星期一下午1点之间的所有更改为文件gbichot2-bin.000007。该增量备份很重要,因此最好将它复制到安全的地方。(例如,备份到磁带或DVD上,或复制到另一台机器上)。在星期二下午1点,执行另一个mysqladmin flush-logs命令。星期一下午1点和星期二下午1点之间的所有所有更改为文件gbichot2-bin.000008(也应复制到某个安全的地方)。

MySQL二进制日志占据硬盘空间。要想释放空间,应随时清空。操作方法是删掉不再使用的二进制日志,例如进行完全备份时:

shell> mysqldump --single-transaction --flush-logs --master-data=2
   --all-databases --delete-master-logs > backup_sunday_1_PM.sql

释:如果你的服务器为复制主服务器,用mysqldump --delete-master-logs删掉MySQL二进制日志很危险,因为从服务器可能还没有完全处理该二进制日志的内容。

PURGE MASTER LOGS语句的描述中解释了为什么在删掉MySQL二进制日志之前应进行确认。参见13.6.1.1节,“PURGE MASTER LOGS语法”。

5.9.2.2. 为恢复进行备份

现在假设在星期三上午8点出现了灾难性崩溃,需要使用备份文件进行恢复。恢复时,我们首先恢复最后的完全备份(从星期日下午1点开始)。完全备份文件是一系列SQL语句,因此恢复它很容易:

shell> mysql < backup_sunday_1_PM.sql

在该点,数据恢复到星期日下午1点的状态。要想恢复从那时起的更改,我们必须使用增量备份,也就是,gbichot2-bin.000007和gbichot2-bin.000008二进制日志文件。根据需要从备份处取过这些文件,然后按下述方式处理:

shell> mysqlbinlog gbichot2-bin.000007 gbichot2-bin.000008 | mysql

我们现在将数据恢复到星期二下午1点的状态,但是从该时刻到崩溃之间的数据仍然有丢失。要想恢复,我们需要MySQL服务器将MySQL二进制日志保存到安全的位置(RAID disks, SAN, ...),应为与数据文件的保存位置不同的地方,保证这些日志不在毁坏的硬盘上。(也就是,我们可以用--log-bin选项启动服务器,指定一个其它物理设备上的与数据目录不同的位置。这样,即使包含该目录的设备丢失,日志也不会丢失)。如果我们执行了这些操作,我们手头上会有gbichot2-bin.000009文件,我们可以用它来恢复大部分最新的数据更改,而不会丢失到崩溃时的数据。

5.9.2.3. 备份策略摘要

出现操作系统崩溃或电源故障时,InnoDB自己可以完成所有数据恢复工作。但为了确保你可以睡好觉,应遵从下面的指导:

·一定用--log-bin或甚至--log-bin=log_name选项运行MySQL服务器,其中日志文件名位于某个安全媒介上,不同于数据目录所在驱动器。如果你有这样的安全媒介,最好进行硬盘负载均衡(这样能够提高性能)。

·定期进行完全备份,使用mysqldump命令进行在线非块备份。

·用FLUSH LOGS或mysqladmin flush-logs清空日志进行定期增量备份。

5.9.3. 自动恢复

5.9.3.1. 指定恢复时间
5.9.3.2. 指定恢复位置

如果MySQL服务器启用了二进制日志,你可以使用mysqlbinlog工具来恢复从指定的时间点开始 (例如,从你最后一次备份)直到现在或另一个指定的时间点的数据。关于启用二进制日志的信息,参见5.11.3节,“二进制日志”。对于mysqlbinlog的详细信息,参见8.6节,“mysqlbinlog:用于处理二进制日志文件的实用工具”。

要想从二进制日志恢复数据,你需要知道当前二进制日志文件的路径和文件名。一般可以从选项文件(即my.cnf or my.ini,取决于你的系统)中找到路径。如果未包含在选项文件中,当服务器启动时,可以在命令行中以选项的形式给出。启用二进制日志的选项为--log-bin。要想确定当前的二进制日志文件的文件名,输入下面的MySQL语句:

SHOW BINLOG EVENTS \G

你还可以从命令行输入下面的内容:

mysql --user=root -pmy_pwd -e 'SHOW BINLOG EVENTS \G'

将密码my_pwd替换为服务器的root密码。

5.9.3.1. 指定恢复时间

对于MySQL 4.1.4,可以在mysqlbinlog语句中通过--start-date和--stop-date选项指定DATETIME格式的起止时间。举例说明,假设在今天上午10:00(今天是2005年4月20日),执行SQL语句来删除一个大表。要想恢复表和数据,你可以恢复前晚上的备份,并输入:
mysqlbinlog --stop-date="2005-04-20 9:59:59" /var/log/mysql/bin.123456 \
     | mysql -u root -pmypwd

该命令将恢复截止到在--stop-date选项中以DATETIME格式给出的日期和时间的所有数据。如果你没有检测到几个小时后输入的错误的SQL语句,可能你想要恢复后面发生的活动。根据这些,你可以用起使日期和时间再次运行mysqlbinlog

mysqlbinlog --start-date="2005-04-20 10:01:00" /var/log/mysql/bin.123456 \
     | mysql -u root -pmypwd \

在该行中,从上午10:01登录的SQL语句将运行。组合执行前夜的转储文件和mysqlbinlog的两行可以将所有数据恢复到上午10:00前一秒钟。你应检查日志以确保时间确切。下一节介绍如何实现。

5.9.3.2. 指定恢复位置

也可以不指定日期和时间,而使用mysqlbinlog的选项--start-position和--stop-position来指定日志位置。它们的作用与起止日选项相同,不同的是给出了从日志起的位置号。使用日志位置是更准确的恢复方法,特别是当由于破坏性SQL语句同时发生许多事务的时候。要想确定位置号,可以运行mysqlbinlog寻找执行了不期望的事务的时间范围,但应将结果重新指向文本文件以便进行检查。操作方法为:
mysqlbinlog --start-date="2005-04-20 9:55:00" --stop-date="2005-04-20 10:05:00" \
      /var/log/mysql/bin.123456 > /tmp/mysql_restore.sql

该命令将在/tmp目录创建小的文本文件,将显示执行了错误的SQL语句时的SQL语句。你可以用文本编辑器打开该文件,寻找你不要想重复的语句。如果二进制日志中的位置号用于停止和继续恢复操作,应进行注释。用log_pos加一个数字来标记位置。使用位置号恢复了以前的备份文件后,你应从命令行输入下面内容:

mysqlbinlog --stop-position="368312" /var/log/mysql/bin.123456 \
    | mysql -u root -pmypwd 
 
mysqlbinlog --start-position="368315" /var/log/mysql/bin.123456 \
    | mysql -u root -pmypwd \ 

上面的第1行将恢复到停止位置为止的所有事务。下一行将恢复从给定的起始位置直到二进制日志结束的所有事务。因为mysqlbinlog的输出包括每个SQL语句记录之前的SET TIMESTAMP语句,恢复的数据和相关MySQL日志将反应事务执行的原时间。

5.9.4. 表维护和崩溃恢复

后面几节讨论如何使用myisamchk来检查或维护MyISAM表(对应.MYI和.MYD文件的表)。

你可以使用myisamchk实用程序来获得有关你的数据库表的信息或检查、修复、优化他们。下列小节描述如何调用myisamchk(包括它的选项的描述),如何建立表的维护计划,以及如何使用myisamchk执行各种功能。

尽管用myisamchk修复表很安全,在修复(或任何可以大量更改表的维护操作)之前先进行备份也是很好的习惯

影响索引的myisamchk操作会使ULLTEXT索引用full-text参数重建,不再与MySQL服务器使用的值兼容。要想避免,请阅读5.9.5.1节,“用于myisamchk的一般选”的说明。

在许多情况下,你会发现使用SQL语句实现MyISAM表的维护比执行myisamchk操作要容易地多:

·要想检查或维护MyISAM表,使用CHECK TABLE或REPAIR TABLE。

·要想优化MyISAM表,使用OPTIMIZE TABLE。

·要想分析MyISAM表,使用ANALYZE TABLE。

可以直接这些语句,或使用mysqlcheck客户端程序,可以提供命令行接口。

这些语句比myisamchk有利的地方是服务器可以做任何工作。使用myisamchk,你必须确保服务器在同一时间不使用表。否则,myisamchk和服务器之间会出现不期望的相互干涉。

5.9.5. myisamchk:MyISAM表维护实用工具

5.9.5.1. 用于myisamchk的一般选
5.9.5.2. 用于myisamchk的检查选项
5.9.5.3. myisamchk的修复选项
5.9.5.4. 用于myisamchk的其它选项
5.9.5.5. myisamchk内存使用
5.9.5.6. 将myisamchk用于崩溃恢
5.9.5.7. 如何检查MyISAM表的错误
5.9.5.8. 如何修复表
5.9.5.9. 表优化

可以使用myisamchk实用程序来获得有关数据库表的信息或检查、修复、优化他们。myisamchk适用MyISAM表(对应.MYI和.MYD文件的表)。

调用myisamchk的方法:

shell> myisamchk [options] tbl_name ...

options指定你想让myisamchk做什么。在后面描述它们。还可以通过调用myisamchk --help得到选项列表。

tbl_name是你想要检查或修复的数据库表。如果你不在数据库目录的某处运行myisamchk,你必须指定数据库目录的路径,因为myisamchk不知道你的数据库位于哪儿。实际上,myisamchk不在乎你正在操作的文件是否位于一个数据库目录;你可以将对应于数据库表的文件拷贝到别处并且在那里执行恢复操作。

如果你愿意,可以用myisamchk命令行命名几个表。还可以通过命名索引文件(用“ .MYI”后缀)来指定一个表。它允许你通过使用模式“*.MYI”指定在一个目录所有的表。例如,如果你在数据库目录,可以这样在目录下检查所有的MyISAM表:

shell> myisamchk *.MYI

如果你不在数据库目录下,可通过指定到目录的路径检查所有在那里的表:

shell> myisamchk /path/to/database_dir/*.MYI

你甚至可以通过为MySQL数据目录的路径指定一个通配符来检查所有的数据库中的所有表:

shell> myisamchk /path/to/datadir/*/*.MYI

推荐的快速检查所有MyISAM表的方式是:

shell> myisamchk --silent --fast /path/to/datadir/*/*.MYI

如果你想要检查所有MyISAM表并修复任何破坏的表,可以使用下面的命令:

shell> myisamchk --silent --force --fast --update-state \
  -O key_buffer=64M -O sort_buffer=64M \
  -O read_buffer=1M -O write_buffer=1M \
  /path/to/datadir/*/*.MYI

该命令假定你有大于64MB的自由内存。关于用myisamchk分配内存的详细信息,参见5.9.5.5节,“myisamchk内存使用”。

当你运行myisamchk时,必须确保其它程序不使用表。否则,当你运行myisamchk时,会显示下面的错误消息:

warning: clients are using or haven't closed the table properly

这说明你正尝试检查正被另一个还没有关闭文件或已经终止而没有正确地关闭文件的程序(例如mysqld服务器)更新的表。

如果mysqld正在运行,你必须通过FLUSH TABLES强制清空仍然在内存中的任何表修改。当你运行myisamchk时,必须确保其它程序不使用表。避免该问题的最容易的方法是使用CHECK TABLE而不用myisamchk来检查表。

5.9.5.1. 用于myisamchk的一般选

本节描述的选项可以用于用myisamchk执行的任何类型的表维护操作。本节后面的章节中描述的选项只适合具体操作,例如检查或修复表。

·--help,-?

显示帮助消息并退出。

·--debug=debug_options, -# debug_options

输出调试记录文件。debug_options字符串经常是'd:t:o,filename'。

·--silent,-s

沉默模式。仅当发生错误时写输出。你能使用-s两次(-ss)使myisamchk沉默。

·--verbose,-v

冗长模式。打印更多的信息。这能与-d和-e一起使用。为了更冗长,使用-v多次(-vv,-vvv)!

·--version, -V

显示版本信息并退出。

·--wait, -w

如果表被锁定,不是提示错误终止,而是在继续前等待到表被解锁。请注意如果用--skip-external-locking选项运行mysqld,只能用另一个myisamchk命令锁定表。

还可以通过--var_name=value选项设置下面的变量:

变量

默认值

decode_bits

9

ft_max_word_len

取决于版本

ft_min_word_len

4

ft_stopword_file

内建列表

key_buffer_size

523264

myisam_block_size

1024

read_buffer_size

262136

sort_buffer_size

2097144

sort_key_blocks

16

stats_method

nulls_unequal

write_buffer_size

262136

可以用myisamchk --help检查myisamchk变量及其默认值:

当用排序键值修复键值时使用sort_buffer_size,使用--recover时这是很普通的情况。

当用--extend-check检查表或通过一行一行地将键值插入表中(如同普通插入)来修改键值时使用Key_buffer_size。在以下情况通过键值缓冲区进行修复:

·使用--safe-recover。

·当直接创建键值文件时,需要对键值排序的临时文件有两倍大。通常是当CHAR、VARCHAR、或TEXT列的键值较大的情况,因为排序操作在处理过程中需要保存全部键值。如果你有大量临时空间,可以通过排序强制使用myisamchk来修复,可以使用--sort-recover选项。

通过键值缓冲区的修复占用的硬盘空间比使用排序么少,但是要慢。

如果想要快速修复,将key_buffer_size和sort_buffer_size变量设置到大约可用内存的25%。可以将两个变量设置为较大的值,因为一个时间只使用一个变量。

myisam_block_size是用于索引块的内存大小。

stats_method影响当给定--analyze选项时,如何为索引统计搜集处理NULL值。它如同myisam_stats_method系统变量。详细信息参见5.3.3节,“服务器系统变量”和7.4.7节,“MyISAM索引统计集合”的myisam_stats_method的描述。

ft_min_word_len和ft_max_word_len表示FULLTEXT索引的最小和最大字长。ft_stopword_file为停止字文件的文件名。需要在以下环境中对其进行设置。

如果你使用myisamchk来修改表索引(例如修复或分析),使用最小和最大字长和停止字文件的默认全文参数值(除非你另外指定)重建FULLTEXT索引。这样会导致查询失败。

出现这些问题是因为只有服务器知道这些参数。它们没有保存在MyISAM索引文件中。如果你修改了服务器中的最小或最大字长或停止字文件,要避免该问题,为用于mysqldmyisamchk指定相同的ft_min_word_len,ft_max_word_len和ft_stopword_file值。例如,如果你将最小字长设置为3,可以这样使用myisamchk来修复表:

shell> myisamchk --recover --ft_min_word_len=3 tbl_name.MYI

要想确保myisamchk和服务器使用相同的全文参数值,可以将它们放入选项文件的[mysqld]和[myisamchk]小节:

[mysqld]
ft_min_word_len=3
 
[myisamchk]
ft_min_word_len=3

除了myisamchk,还可以使用REPAIR TABLE、ANALYZE TABLE、OPTIMIZE TABLE或ALTER TABLE。这些语句由服务器执行,知道要使用的正确的全文参数值。

5.9.5.2. 用于myisamchk的检查选项

myisamchk支持下面的表检查操作选项:

·--check, -c

检查表的错误。如果你不明确指定操作类型选项,这就是默认操作。

·--check-only-changed, -C

只检查上次检查后有变更的表。

·--extend-check, -e

非常仔细地检查表。如果表有许多索引将会相当慢。该选项只能用于极端情况。一般情况下,可以使用myisamchkmyisamchk --medium-check来确定表内是否有错误。

如果你使用了--extend-check并且有充分的内存,将key_buffer_size变量设置为较大的值可以使修复操作运行得更快。

·--fast,-F

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

·--force, -f

如果myisamchk发现表内有任何错误,则自动进行修复。维护类型与--repair或-r选项指定的相同。

·--information, -i

打印所检查表的统计信息。

·--medium-check, -m

比--extend-check更快速地进行检查。只能发现99.99%的错误,在大多数情况下就足够了。

·--read-only, -T

不要将表标记为已经检查。如果你使用myisamchk来检查正被其它应用程序使用而没有锁定的表很有用,例如当用--skip-external-locking选项运行时运行mysqld

·--update-state, -U

将信息保存在.MYI文件中,来表示表检查的时间以及是否表崩溃了。该选项用来充分利用--check-only-changed选项,但如果mysqld服务器正使用表并且正用--skip-external-locking选项运行时不应使用该选项。

5.9.5.3. myisamchk的修复选项

myisamchk支持下面的表修复操作的选项:

·--backup,-B

将.MYD文件备份为file_name-time.BAK

·--character-sets-dir=path

字符集安装目录。参见5.10.1节,“数据和排序用字符集”。

·--correct-checksum

纠正表的校验和信息。

·--data-file-length=len, -D len

数据文件的最大长度(当重建数据文件且为“满”时)。

·--extend-check,-e

进行修复,试图从数据文件恢复每一行。一般情况会发现大量的垃圾行。不要使用该选项,除非你不顾后果。

·--force,-f

覆盖旧的中间文件(文件名类似tbl_name.TMD),而不是中断。

·--keys-used=val,-k val

对于myisamchk,该选项值为位值,说明要更新的索引。选项值的每一个二进制位对应表的一个索引,其中第一个索引对应位0。选项值0禁用对所有索引的更新,可以保证快速插入。通过myisamchk -r可以重新激活被禁用的索引。

·--no-symlinks,-l

不跟随符号连接。通常myisamchk修复一个符号连接所指的表。在MySQL 4.0中该选项不存在,因为从4.0开始的版本在修复过程中不移除符号链接。

·--parallel-recover,-p

与-r和-n的用法相同,但使用不同的线程并行创建所有键。这是alpha代码。自己承担风险!

·--quick,-q

不修改数据文件,快速进行修复。出现复制键时,你可以两次指定该项以强制myisamchk修改原数据文件。

·--recover,-r

可以修复几乎所有一切问题,除非唯一的键不唯一时(对于MyISAM表,这是非常不可能的情况)。如果你想要恢复表,这是首先要尝试的选项。如果myisamchk报告表不能用-r恢复,则只能尝试-o。在不太可能的情况下-r失败,数据文件保持完好)。

如果你有大量内存,你应增加sort_buffer_size的值。

·--safe-recover,-o

使用一个老的恢复方法读取,按顺序读取所有行,并根据找到的行更新所有索引树。这比-r慢些,但是能处理-r不能处理的情况。该恢复方法使用的硬盘空间比-r少。一般情况,你应首先用-r维修,如果-r失败则用-o。

如果你有大量内存,你应增加sort_buffer_size的值。

·(OBSOLETE)--set-character-set=name

在MySQL 5.1中不使用。参见--set-collation。

·--set-collation=name

更改用来排序表索引的校对规则。校对规则名的第一部分包含字符集名。

·--sort-recover, -n

强制myisamchk通过排序来解析键值,即使临时文件将可能很大。

·--tmpdir=path, -t path

用于保存临时文件的目录的路径。如果未设置,myisamchk使用TMPDIR环境变量的值。tmpdir可以设置为一系列目录路径,用于成功地以round-robin模式创建临时文件。在Unix中,目录名之间的间隔字符为冒号(‘:’),在Windows、NetWare和OS/2中为分号 (‘;’)。

·--unpack,-u

将用myisampack打包的表解包。

5.9.5.4. 用于myisamchk的其它选项

myisamchk支持以下表检查和修复之外的其它操作的选项:

·--analyze,-a

分析键值的分布。这通过让联结优化器更好地选择表应该以什么次序联结和应该使用哪个键来改进联结性能。要想获取分布相关信息,使用myisamchk --description --verbose tbl_name命令或SHOW KEYS FROM tbl_name语句。

·--description, -d

打印出关于表的描述性信息。

·--set-auto-increment[=value],-A[value]

强制从给定值开始的新记录使用AUTO_INCREMENT编号(或如果已经有AUTO_INCREMENT值大小的记录,应使用更高值)。如果未指定value,新记录的AUTO_INCREMENT编号应使用当前表的最大值加上1。

·--sort-index, -S

以从高到低的顺序排序索引树块。这将优化搜寻并且将使按键值的表扫描更快。

·--sort-records=N, -R N

根据一个具体索引排序记录。这使你的数据更局部化并且可以加快在该键上的SELECT和ORDER BY的范围搜索。(第一次做排序可能很慢!)为了找出一张表的索引编号,使用SHOW INDEX,它以myisamchk看见他们的相同顺序显示一张表的索引。索引从1开始编号。

如果键没有打包(PACK_KEYS=0),它们的长度相同,因此当myisamchk排序并移动记录时,只覆盖索引中的记录偏移量。如果键已经打包(PACK_KEYS=1),myisamchk必须先解开打包的键块,然后重新创建索引并再次将键块打包。(在这种情况下,重新创建索引比更新每个索引的偏移量要快)。

5.9.5.5. myisamchk内存使用

当你运行myisamchk时内存分配重要.MYIsamchk使用的内存大小不能超过用-O选项指定的。如果你想对每一个大表使用myisamchk,你必须首先确定你想使用多少内存。修复时可以使用的默认值只有3MB。使用更大的内存,可以让myisamchk工作得更快一些。例如,如果有大于32MB的RAM,可以使用如下所示选项(除了你可以指定的其它选项):

shell> myisamchk -O sort=16M -O key=16M -O read=1M -O write=1M ...

对于大多数情况,使用-O sort=16M应该足够了。

应记住myisamchk使用TMPDIR中的临时文件。如果TMPDIR指向内存文件系统,你可能很容易得到内存溢出的错误。如果发生,设定TMPDIR指向有更多空间的文件系统目录并且重启myisamchk

修复时myisamchk也需要大量硬盘空间:

·将数据文件大小扩大一倍(原文件和复制文件)。如果你用--quick修复则不需要该空间;在这种情况下,只重新创建了索引文件。在文件系统上需要的空间与原数据文件相同!(创建的复制文件位于原文件所在目录)。

·代替旧索引文件的新索引文件所占空间。修复工作一开始,就对旧索引文件进行了删减,因此你通常会忽略该空间。在文件系统上需要的该空间与原数据文件相同!

·当使用--recover或---sort-recover(但不使用--safe-recover)时,需要排序缓冲区空间。需要的空间为:

·(largest_key + row_pointer_length) * number_of_rows * 2

可以用myisamchk -dv tbl_name检查键值和row_pointer_length的长度。在临时目录分配该空间(用TMPDIR或--tmpdir=path指定)。

如果在修复过程中出现硬盘空间问题,可以试试用--safe-recover代替--recover。

5.9.5.6. 将myisamchk用于崩溃恢

如果用--skip-external-locking运行mysqld(在某些系统上为默认设置,例如Linux),当mysqld使用某个表时,你不能可靠地使用myisamchk来检查相同的表。当你运行myisamchk时如果可以确保没有人在通过mysqld访问表,在开始检查表前,你只需要运行mysqladmin flush-tables。如果你不能保证,则你检查表时你必须停止mysqld。如果mysqld更新表时运行myisamchk,你可能会获得表被破坏的警告,即使事实并非如此。

如果不使用--skip-external-locking,可以随时使用myisamchk来检查表。当检查表时,所有尝试更新表的客户端将等待,直到myisamchk准备好可以继续。

如果使用myisamchk来修复或优化表,必须确保mysqld服务器没有在使用该表(如果你正使用--skip-external-locking选项也适用)。如果不关闭mysqld,在运行myisamchk之前至少应执行mysqladmin flush-tables。如果服务器和myisamchk同时访问表,表可能会被破坏。

本节描述如何检查和处理MySQL数据库中的数据破坏。如果表经常被破坏,你应尽力找到原因。参见A.4.2节,“如果MySQL依然崩溃,应作些什么”。

关于MyISAM表怎样会被破坏的解释,参见15.1.4节,“MyISAM表方面的问题”。

在执行崩溃恢复时,理解在一个数据库中的每一个MyISAM表tbl_name对应的在数据库目录中的3个文件是很重要的:

文件

目的

tbl_name.frm

定义(格式)文件

tbl_name.MYD

数据文件

tbl_name.MYI

索引文件

这3类文件的每一类都可能遭受不同形式的损坏,但是问题最常发生在数据文件和索引文件。

myisamchk通过一行一行地创建一个“.MYD”数据文件的副本来工作,它通过删除旧的“.MYD文件并且重命名新文件到原来的文件名结束修复阶段。如果你使用--quick,myisamchk不创建一个临时“.MYD”文件,只是假定“.MYD”文件是正确的并且仅创建一个新的索引文件,不接触“.MYD”文件,这是安全的,因为myisamchk自动检测“.MYD”文件是否损坏并且在这种情况下,放弃修复。你也可以给myisamchk两个--quick选项。在这种情况下,myisamchk不会在一些错误上(象重复键)放弃,相反试图通过修改“.MYD”文件解决它们。通常,只有在太少的空闲磁盘空间上实施正常修复,使用两个--quick选项时才有用。在这种情况下,你至少应该在运行myisamchk前做进行备份。

5.9.5.7. 如何检查MyISAM表的错误

要想检查MyISAM表,应使用下面的命令:

·myisamchk tbl_name

这样能找出99.99%的错误。它不能找出的是仅仅涉及数据文件的损坏(这很不常见)。如果想要检查一张表,通常应该没有选项地运行myisamchk或用-s或--silent选项的任何一个。

·myisamchk -m tbl_name

这样能找出99.99%的错误。它首先检查所有索引条目的错误并通读所有行。它还计算行内所有键值的校验和,并确认校验和与索引树内键的校验和相匹配。

·myisamchk -e tbl_name

可以完全彻底地检查数据(-e意思是“扩展检查”)。它对每一行做每个键的读检查以证实它们确实指向正确的行。这在一个有很多键的大表上可能花很长时间。myisamchk通常将在它发现第一个错误以后停止。如果你想要获得更多的信息,可以增加--verbose(-v)选项。这使得myisamchk继续一直到最多20个错误。

·myisamchk -e -i tbl_name

象前面的命令一样,但是-i选项告诉myisamchk还打印出一些统计信息。

在一般使用中,一个简单的myisamchk(没有除表名以外的参数)就足够检查表了。

5.9.5.8. 如何修复表

本节描述如何对MyISAM表使用myisamchk(扩展名.MYI和.MYD)。

你还可以(并且应该,如果可能)使用CHECK TABLE和REPAIR TABLE语句来检查和修复MyISAM表。参见13.5.2.3节,“CHECK TABLE语法”和13.5.2.6节,“REPAIR TABLE语法”。

一张损坏的表的症状通常是查询意外中断并且能看到下述错误:

  • tbl_name.frm”被锁定不能更改。
  • 不能找到文件tbl_name.MYI”(Errcode:nnn)。
  • 文件意外结束。
  • 记录文件被毁坏。
  • 从表处理器得到错误nnn

要想得到错误相关的详细信息,你可以运行perrornnn,其中nnn为错误编号。下面的示例显示了如何使用perror来找到最常用错误编号(用表的方式指出问题)的含义:

shell> perror 126 127 132 134 135 136 141 144 145
126 = Index file is crashed / Wrong file format
127 = Record-file is crashed
132 = Old database file
134 = Record was already deleted (or record file crashed)
135 = No more room in record file
136 = No more room in index file
141 = Duplicate unique key or constraint on write or update
144 = Table is crashed and last repair failed

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或DESCRIBE来查询。

对于其它的错误,你必须修复表。myisamchk通常可以检测和修复大多数问题。

修复过程包括四个阶段,此处将进行描述。开始修复前,应进入数据库目录并检查表文件的许可。在Unix中,确保它们对于运行mysqld的用户可读(你也应可读,因为你需要访问检查的文件)。如果你需要修改文件,你还必须拥有写访问权限。

myisamchk修复表的选项的描述参见5.9.5节,“myisamchk:MyISAM表维护实用工具”的前几节。

下面几节列出了上述命令失败或你想要使用myisamchk提供的扩展特性等情况的例子。

如果你要通过命令行来修复表,必须首先停止mysqld服务器。请注意当你在远程服务器上运行mysqladmin shutdown时,mysqladmin返回后,mysqld服务器将仍然运行一会儿,直到停止所有查询并将所有键清空到硬盘上。

阶段1:检查你的表

如果你有很多时间,运行myisamchk *.MYImyisamchk -e *.MYI。使用-s(沉默)选项禁止不必要的信息。

如果mysqld服务器处于宕机状态,应使用--update-state选项来告诉myisamchk将表标记为'检查过的'。

你必须只修复那些myisamchk报告有错误的表。对这样的表,继续到阶段2。

如果在检查时,你得到奇怪的错误(例如out of memory错误),或如果myisamchk崩溃,到阶段3。

阶段2:简单安全的修复

注释:如果想更快地进行修复,当运行myisamchk时,你应将sort_buffer_size和Key_buffer_size变量的值设置为可用内存的大约25%。

首先,试试myisamchk -r -q tbl_name(-r -q意味着“快速恢复模式”)。这将试图不接触数据文件来修复索引文件。如果数据文件包含它应有的一切内容和指向数据文件内正确地点的删除连接,这应该管用并且表可被修复。开始修复下一张表。否则,执行下列过程:

  1. 在继续前对数据文件进行备份。
  2. 使用myisamchk -r tbl_name(-r意味着“恢复模式”)。这将从数据文件中删除不正确的记录和已被删除的记录并重建索引文件。
  3. 如果前面的步骤失败,使用myisamchk --safe-recover tbl_name。安全恢复模式使用一个老的恢复方法,处理常规恢复模式不行的少数情况(但是更慢)。

如果在修复时,你得到奇怪的错误(例如out of memory错误),或如果myisamchk崩溃,到阶段3。

阶段3:困难的修复

只有在索引文件的第一个16K块被破坏,或包含不正确的信息,或如果索引文件丢失,你才应该到这个阶段。在这种情况下,需要创建一个新的索引文件。按如下步骤操做:

  1. 把数据文件移到安全的地方。
  2. 使用表描述文件创建新的(空)数据文件和索引文件:
  3. shell> mysql db_name
  4. mysql> SET AUTOCOMMIT=1;
  5. mysql> TRUNCATE TABLE tbl_name;
  6. mysql> quit

如果你的MySQL版本没有TRUNCATE TABLE,则使用DELETE FROM tbl_name

  1. 将老的数据文件拷贝到新创建的数据文件之中。(不要只是将老文件移回新文件之中;你要保留一个副本以防某些东西出错。)

回到阶段2。现在myisamchk -r -q应该工作了。(这不应该是一个无限循环)。

你还可以使用REPAIR TABLE tbl_name USE_FRM,将自动执行整个程序。

阶段4:非常困难的修复

只有.frm描述文件也破坏了,你才应该到达这个阶段。这应该从未发生过,因为在表被创建以后,描述文件就不再改变了。

  1. 从一个备份恢复描述文件然后回到阶段3。你也可以恢复索引文件然后回到阶段2。对后者,你应该用myisamchk -r启动。
  2. 如果你没有进行备份但是确切地知道表是怎样创建的,在另一个数据库中创建表的一个拷贝。删除新的数据文件,然后从其他数据库将描述文件和索引文件移到破坏的数据库中。这样提供了新的描述和索引文件,但是让.MYD数据文件独自留下来了。回到阶段2并且尝试重建索引文件。

5.9.5.9. 表优化

为了组合碎片记录并且消除由于删除或更新记录而浪费的空间,以恢复模式运行myisamchk

shell> myisamchk -r tbl_name

你可以用SQL的OPTIMIZE TABLE语句使用的相同方式来优化表,OPTIMIZE TABLE可以修复表并对键值进行分析,并且可以对索引树进行排序以便更快地查找键值。实用程序和服务器之间不可能交互操作,因为当你使用OPTIMIZE TABLE时,服务器做所有的工作。参见13.5.2.5节,“OPTIMIZE TABLE语法”。

myisamchk还有很多其它可用来提高表的性能的选项:

·-S,--sort-index

·-Rindex_num, --sort-records=index_num

·-a,--analyze

关于这些选项的完整的描述,参见5.9.5节,“myisamchk:MyISAM表维护实用工具”。

5.9.6. 建立表维护计划

定期对表进行检查而非等到问题出现后再检查数据库表是一个好主意。检查和修复MyISAM表的一个方式是使用CHECK TABLE和REPAIR TABLE语句。参见13.5.2.3节,“CHECK TABLE语法”和13.5.2.6节,“REPAIR TABLE语法”。

检查表的另一个方法是使用myisamchk。为维护目的,可以使用myisamchk -s检查表。-s选项(简称--silent)使myisamchk以沉默模式运行,只有当错误出现时才打印消息。

在服务器启动时检查表是一个好主意。例如,无论何时机器在更新当中重新启动了,你通常需要检查所有可能受影响的表。(即“预期的破坏了的表”)。要想自动检查MyISAM表,用--myisam-recover选项启动服务器。

一个更好的测试将是检查最后修改时间比“.pid”文件新的表。

你还应该在正常系统操作期间定期检查表。在MySQL AB,我们运行一个cron任务,每周一次检查所有重要的表,使用crontab文件中这样的行:

35 0 * * 0 /path/to/myisamchk --fast --silent /path/to/datadir/*/*.MYI

可以打印损坏的表的信息,以便我们在需要时能够检验并且修复它们。

多年了我们还没有发现(的确是真的)都没有任何意外损坏的表时(由于除硬件故障外的其它原因造成损坏的表),每周一次对我们是足够了。

我们建议现在开始,你对所有最后24小时内被更新了的表每晚都执行myisamchk -s,直到你变得象我们那样信任MySQL

一般情况,MySQL表很少需要维护。如果你用动态大小的行更改MyISAM表(含VARCHAR、BLOB或TEXT列的表)或有删除了许多行的表,你可能想要不时地(每月一次)整理/组合表的空间。

可以对有问题的表执行OPTIMIZE TABLE来优化。或者是,如果可以停一会mysqld服务器,进入数据目录,当服务器停止时使用该命令:

shell> myisamchk -r -s --sort-index -O sort_buffer_size=16M */*.MYI

5.9.7. 获取关于表的信息

为了获得关于一个表的描述或统计,使用下面的命令:

·myisamchk -d tbl_name

以“描述模式”运行myisamchk,生成表的描述。如果用--skip-external-locking选项启动MySQL服务器,myisamchk可以报告运行的表被更新的错误。然而,既然在描述模式中myisamchk不更改表,没有任何破坏数据的风险。

·myisamchk -d -v tbl_name

为了生成更多关于myisamchk正在做什么的信息,加上-v告诉它以冗长模式运行。

·myisamchk -eis tbl_name

仅显示表的最重要的信息。因为必须读取整个表,该操作很慢。

·myisamchk -eiv tbl_name

这类似 -eis,只是告诉你正在做什么。

下面为这些命令的输出示例。它们基于含这些数据和索引文件大小的表:

-rw-rw-r--   1 monty    tcx     317235748 Jan 12 17:30 company.MYD
-rw-rw-r--   1 davida   tcx      96482304 Jan 12 18:35 company.MYM

myisamchk -d输出示例:

MyISAM file:     company.MYI
Record format:   Fixed length
Data records:    1403698  Deleted blocks: 0
Recordlength:    226
 
table description:
Key Start Len Index   Type
1   2     8   unique  double
2   15    10  multip. text packed stripped
3   219   8   multip. double
4   63    10  multip. text packed stripped
5   167   2   multip. unsigned short
6   177   4   multip. unsigned long
7   155   4   multip. text
8   138   4   multip. unsigned long
9   177   4   multip. unsigned long
    193   1   text

myisamchk -d -v输出示例:

MyISAM file: company
Record format:       Fixed length
File-version:1
Creation time:       1999-10-30 12:12:51
Recover time:1999-10-31 19:13:01
Status:      checked
Data records:    1403698  Deleted blocks:      0
Datafile parts:  1403698  Deleted data:0
Datafile pointer (bytes):      3  Keyfile pointer (bytes):     3
Max datafile length:  3791650815  Max keyfile length: 4294967294
Recordlength:226
 
table description:
Key Start Len Index   Type  Rec/key     Root Blocksize
1   2     8   unique  double      1 15845376      1024
2   15    10  multip. text packed stripped2 25062400      1024
3   219   8   multip. double     73 40907776      1024
4   63    10  multip. text packed stripped5 48097280      1024
5   167   2   multip. unsigned short   4840 55200768      1024
6   177   4   multip. unsigned long    1346 65145856      1024
7   155   4   multip. text     4995 75090944      1024
8   138   4   multip. unsigned long      87 85036032      1024
9   177   4   multip. unsigned long     178 96481280      1024
    193   1   text

myisamchk -eis输出示例:

Checking MyISAM file: company
Key:  1:  Keyblocks used:  97%  Packed:    0%  Max levels:  4
Key:  2:  Keyblocks used:  98%  Packed:   50%  Max levels:  4
Key:  3:  Keyblocks used:  97%  Packed:    0%  Max levels:  4
Key:  4:  Keyblocks used:  99%  Packed:   60%  Max levels:  3
Key:  5:  Keyblocks used:  99%  Packed:    0%  Max levels:  3
Key:  6:  Keyblocks used:  99%  Packed:    0%  Max levels:  3
Key:  7:  Keyblocks used:  99%  Packed:    0%  Max levels:  3
Key:  8:  Keyblocks used:  99%  Packed:    0%  Max levels:  3
Key:  9:  Keyblocks used:  98%  Packed:    0%  Max levels:  4
Total:    Keyblocks used:  98%  Packed:   17%
 
Records:  1403698    M.recordlength:     226
Packed:     0%
Recordspace used:     100%   Empty space:  0%
Blocks/Record:   1.00
Record blocks:    1403698    Delete blocks:0
Recorddata:     317235748    Deleted data: 0
Lost space:     0    Linkdata:     0
 
User time 1626.51, System time 232.36
Maximum resident set size 0, Integral resident set size 0
Non physical pagefaults 0, Physical pagefaults 627, Swaps 0
Blocks in 0 out 0, Messages in 0 out 0, Signals 0
Voluntary context switches 639, Involuntary context switches 28966

myisamchk -eiv输出示例:

Checking MyISAM file: company
Data records: 1403698   Deleted blocks:       0
- check file-size
- check delete-chain
block_size 1024:
index  1:
index  2:
index  3:
index  4:
index  5:
index  6:
index  7:
index  8:
index  9:
No recordlinks
- check index reference
- check data record references index: 1
Key:  1:  Keyblocks used:  97%  Packed:    0%  Max levels:  4
- check data record references index: 2
Key:  2:  Keyblocks used:  98%  Packed:   50%  Max levels:  4
- check data record references index: 3
Key:  3:  Keyblocks used:  97%  Packed:    0%  Max levels:  4
- check data record references index: 4
Key:  4:  Keyblocks used:  99%  Packed:   60%  Max levels:  3
- check data record references index: 5
Key:  5:  Keyblocks used:  99%  Packed:    0%  Max levels:  3
- check data record references index: 6
Key:  6:  Keyblocks used:  99%  Packed:    0%  Max levels:  3
- check data record references index: 7
Key:  7:  Keyblocks used:  99%  Packed:    0%  Max levels:  3
- check data record references index: 8
Key:  8:  Keyblocks used:  99%  Packed:    0%  Max levels:  3
- check data record references index: 9
Key:  9:  Keyblocks used:  98%  Packed:    0%  Max levels:  4
Total:    Keyblocks used:   9%  Packed:   17%
 
- check records and index references
[LOTS OF ROW NUMBERS DELETED]
 
Records: 1403698   M.recordlength:   226   Packed:   0%
Recordspace used:    100%  Empty space:0%  Blocks/Record: 1.00
Record blocks:   1403698   Delete blocks:      0
Recorddata:    317235748   Deleted data:       0
Lost space:    0   Linkdata:   0
 
User time 1639.63, System time 251.61
Maximum resident set size 0, Integral resident set size 0
Non physical pagefaults 0, Physical pagefaults 10580, Swaps 0
Blocks in 4 out 0, Messages in 0 out 0, Signals 0
Voluntary context switches 10604, Involuntary context switches 122798

下面解释myisamchk产生的信息的类型。“keyfile”是索引文件。“记录”和“行”是同义词。

·MyISAM file

ISAM(索引)文件名。

·File-version

ISAM格式的版本。当前总是2。

·Creation time

数据文件创建的时间。

·Recover time

索引/数据文件上次被重建的时间。

·Data records

在表中有多少记录。

·Deleted blocks

有多少删除的块仍然保留着空间。你可以优化表以使这个空间减到最小。参见第7章:优化

·Datafile parts

对动态记录格式,这指出有多少数据块。对于一个没有碎片的优化过的表,这与Data records相同。

·Deleted data

不能回收的删除数据有多少字节。你可以优化表以使这个空间减到最小。参见第7章:优化

·Datafile pointer

数据文件指针的大小,以字节计。它通常是2、3、4或5个字节。大多数表用2个字节管理,但是目前这还不能从MySQL控制。对固定表,这是一个记录地址。对动态表,这是一个字节地址。

·Keyfile pointer

索引文件指针的大小,以字节计。它通常是1、2或3个字节。大多数表用 2 个字节管理,但是它自动由MySQL计算。它总是一个块地址。

·Max datafile length

表的数据文件(.MYD文件)能够有多长,以字节计。

·Max keyfile length

表的键值文件(.MYI文件)能够有多长,以字节计。

· Recordlength

每个记录占多少空间,以字节计。

·Record format

用于存储表行的格式。上面的例子使用Fixed length。其他可能的值是Compressed和Packed。

·table description

在表中所有键值的列表。对每个键,给出一些底层的信息:

oKey

该键的编号。

oStart

该索引部分从记录的哪里开始。

oLen

该索引部分是多长。对于紧凑的数字,这应该总是列的全长。对字符串,它可以比索引的列的全长短些,因为你可能会索引到字符串列的前缀。

oIndex

unique或multip(multiple)。表明一个值是否能在该索引中存在多次。

oType

该索引部分有什么数据类型。这是一个packed、stripped或empty选项的ISAM数据类型。

oRoot

根索引块的地址。

oBlocksize

每个索引块的大小。默认是1024,但是从源码构建MySQL时,该值可以在编译时改变。

oRec/key

这是由优化器使用的统计值。它告诉对该键的每个值有多少条记录。唯一键总是有一个1值。在一个表被装载后(或变更很大),可以用myisamchk -a更新。如果根本没被更新,给定一个30的默认值。

在上面例子的表中,第9个键有两个table description行。者说明它是有2个部分的多部键。

·Keyblocks used

键块使用的百分比是什么。当在例子中使用的表刚刚用myisamchk重新组织时,该值非常高(很接近理论上的最大值)。

·Packed

MySQL试图用一个通用后缀压缩键。这只能被用于CHAR/VARCHAR/DECIMAL列的键。对于左部分类似的长字符串,能显著地减少使用空间。在上面的第3个例子中,第4个键是10个字符长,可以减少60%的空间。

·Max levels

对于该键的B树有多深。有长键的大表有较高的值。

·Records

表中有多少行。

·M.recordlength

平均记录长度。对于有定长记录的表,这是准确的记录长度,因为所有记录的长度相同。

·Packed

MySQL从字符串的结尾去掉空格。Packed值表明这样做达到的节约的百分比。

·Recordspace used

数据文件被使用的百分比。

·Empty space

数据文件未被使用的百分比。

·Blocks/Record

每个记录的平均块数(即,一个碎片记录由多少个连接组成)。对固定格式表,这总是1。该值应该尽可能保持接近1.0。如果它变得太大,你可以重新组织表。参见第7章:优化

·Recordblocks

多少块(链接)被使用。对固定格式,它与记录的个数相同。

·Deleteblocks

多少块(链接)被删除。

·Recorddata

在数据文件中使用了多少字节。

·Deleted data

在数据文件中多少字节被删除(未使用)。

·Lost space

如果一个记录被更新为更短的长度,就损失了一些空间。这是所有这样的损失之和,以字节计。

·Linkdata

当使用动态表格式,记录碎片用指针连接(每个4~ 7字节)。 Linkdata指这样的指针使用的内存量之和。

如果一张表已经用myisampack压缩了,myisamchk -d打印每个表列的附加信息。对于它的一个例子及其含义的描述,参见8.2节,“myisampack:生成压缩、只读MyISAM表”。