MySQL工具系列之myisamchk进行表的维护和崩溃恢复
2010-09-01 12:53:08 阿炯

1.为了检查/修复MyISAM表(.MYI和.MYD),你应该使用myisamchk实用程序。为了检查/修复ISAM表(.ISM和.ISD),你应该使用isamchk实用程序。

在下文中,我们将讨论myisamchk,但是也适用于老的isamchk。
你可以使用myisamchk实用程序来获得有关你的数据库表的信息、检查和修复他们或优化他们。下列小节描述如何调用myisamchk(包括它的选项的描述),如何建立一个表维护的时间表,并且如何使用myisamchk执行其各种功能。

如果你用--skip-locking运行mysqld(它在一些系统上是缺省的,如Linux),当mysqld正在使用同一个表时,你不能可靠地使用 myisamchk检查一张表。如果你能肯定在你运行myisamchk时没有人通过mysqld正在存取表,在你开始检查表之前,你仅需做 mysqladmin flush-tables。如果你不能保证,那么当你检查表时,你必须停掉mysqld。如果你在mysqld正在更新表时运行myisamchk,你可能得到一个表已破坏的警告,即使它没有。

如果你没使用--skip-locking,你能在任何时间使用myisamchk检查表。当你这样时,所有试图更新表的客户在继续前将等到myisamchk就绪。

如果你使用myisamchk修复或优化表,你必须总是保证mysqld服务器不在使用表(如果你正在使用--skip-locking,这也适用)。如果你不停掉mysqld,在你运行myisamchk前,你至少应该做一个mysqladmin flush-tables。

在大多数情况下,你也可使用命令OPTIMIZE TABLES优化并修复表,但是这不如myisamchk快或可靠(在真正的致命错误的情况下)。在另一方面,OPTIMIZE TABLE较易使用并且你不必须关心清空表。见7.9OPTIMIZE TABLE句法。

1.1.1 myisamchk调用语法
myisamchk这样调用:
shell> myisamchk [options] tbl_name

options 指定你想要myisamchk做什么。他们在下面描述。(你也可以通过调用myisamchk --help得到一张选项表。) 没有选项,myisamchk简单地检查你的表。为了得到更多的信息或告诉myisamchk执行校正操作,指定在下面和下小节描述的选项择。

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

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

如果你不在数据库目录下,你可通过指定到目录的路径检查所有在那里的表:
shell> myisamchk /path/to/database_dir/*.MYI

你甚至可以通过为MySQL数据目录的路径指定一个通配符来检查所有的数据库中的所有表:
shell> myisamchk /path/to/datadir/*/*.MYI

myisamchk支持下列选项:

-a, --analyze
分析键值的分布。这通过让联结优化器更好地选择表应该以什么次序联结和应该使用哪个键来改进联结性能。
-#, --debug=debug_options
输出调试记录文件。debug_options字符串经常是d:t:o,filename。
-d, --description
打印出关于表的一些信息。
-e, --extend-check
非常彻底地检查表。这仅在极端情况下是必要的。通常,myisamchk应该找出所有错误,即使没有改选项。
-f, --force
覆盖老的临时文件。如果你在检查表时使用-f (运行myisamchk没有-r),myisamchk在检查期间将自动为出现一个错误的表用-r重启。
--help
显示一条帮助消息并且退出。
-i, --information
打印有关被检查的表的信息统计。
-k #, --keys-used=#
与-r一起使用。告诉ISAM表处理器仅更新头#个索引。较高编号的索引被撤销。这能用来使插入变得更快!撤销的索引能通过使用myisamchk -r被重新激活。
-l, --no-symlinks
在修复时,不跟随符号连接。通常myisamchk修复一个符号连接所指的表。
-q, --quick
与-r一起使用使得一个修复更快。通常,原来的数据文件没被接触;你能指定第二个-q强制使用原来的数据文件。
-r, --recover
恢复模式。可以修复几乎所有一切,除非唯一的键不是唯一。
-o, --safe-recover
恢复模式。使用一个老的恢复方法;这比-r慢些,但是能处理一-r不能处理的情况。
-O var=option, --set-variable var=option
设置一个变量的值。可能的变量列在下面。
-s, --silent
沉默模式。当错误发生时,仅写输出。你能使用-s两次(-ss)非常沉默地做myisamchk。
-S, --sort-index
以从高到低的顺序排序索引树块。这将优化搜寻并且将使按键值的表扫描更快。
-R index_num, --sort-records=index_num
根据一个索引排序记录。这使你的数据更局部化并且可以加快在该键上的SELECT和ORDER BY的范围搜索。(第一次做排序可能很慢!) 为了找出一张表的索引编号,使用SHOW INDEX,它以myisamchk看见他们的相同顺序显示一张表的索引。索引从1开始编号。
-u, --unpack
解开一个用myisampack压缩的表。
-v, --verbose
冗长模式。打印更多的信息。这能与-d和-e一起使用。为了更冗长,使用-v多次(-vv, -vvv)!
-V, --version
打印myisamchk版本并退出。
-w, --wait
如果表被锁定,等待。

对--set-variable(-O)选项,可能的变量是:
key_buffer_size 当前值: 16776192
read_buffer_size 当前值: 262136
write_buffer_size 当前值: 262136
sort_buffer_size 当前值: 2097144
sort_key_blocks 当前值: 16
decode_bits 当前值: 9

1.1.2 myisamchk内存使用
当你运行myisamchk时,内存分配很重要。myisamchk使用不超过你用-O选项指定的内存量。如果你想在很大的文件上使用myisamchk,你首先应该确定你想要它使用多少内存。缺省仅使用大约 3M 来修复。通过使用更大的值,你能使myisamchk更快地操作。例如,如果你有多于32M内存,你能使用例如这些选项(除了任何你可能指定的选项):
shell> myisamchk -O sort=16M -O key=16M -O read=1M -O write=1M ...

使用-O sort=16M应该可能对大多数情形就足够了。

必须明白,myisamchk使用在TMPDIR里面的临时文件。如果TMPDIR指向一个内存文件系统,你可能很容易得到内存溢出的错误。如果它发生,设定TMPDIR指向有更多空间的某个目录并且重启myisamchk。

1.2 建立一个数据库表维护规范
在一个定期基础而非等到问题出现才实施数据库表的检查是一个好主意。为维护目的,你能使用myisamchk -s检查。-s选项使myisamchk以沉默模式运行,当错误出现时,仅仅打印消息。

在服务器启动时检查表是一个好主意。例如,无论何时机器在更新当中重新启动了,你通常需要检查所有可能被影响了的表。(这是一个期望破坏了的表) 如果重启后有一个旧的.pid(进程ID),你能为safe_mysqld加入一个测试,运行myisamchk检查所有在过去24小时修改过的表)。(.pid文件在mysqld启动时由它创建,并它正常终止时删除。在系统启动时存在一个.pid文件表明mysqld异常地终止了)。一个更好的测试将是检查任何表,它的最后修改时间是比.pid文件更新。

你也应该定期在正常系统操作期间检查表。在TcX,我们运行一个cron任务,每周一次检查我们所有重要的表,在一个crontab文件中使用这样的行:
35 0 * * 0 /path/to/myisamchk -s /path/to/datadir/*/*.MYI

这打印出损坏的表的信息,因此我们能检验并且在需要时修复他们。当我们现在几年(这确实是真的)都没有任何意外损坏的表时(由于除硬件故障外的其他原因造成损坏的表),每周一次对我们是足够了。

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

1.3 获得关于一个表的信息
为了获得关于一个表的描述或统计,使用显示在下面的命令。我们以后更详细地解释某些信息。
myisamchk -d tbl_name
以描述模式运行myisamchk,生成你的表的描述。如果你用--skip-locking选项启动MySQL服务器,myisamchk可以当它运行时报告被一个更新的表的错误。然而,既然在描述模式中myisamchk不改变表,没有破坏数据的任何风险。
myisamchk -d -v tbl_name
为了生成更多关于myisamchk正在做什么的信息,加上-v告诉它以冗长模式运行。
myisamchk -eis tbl_name
仅显示一个表最重要的信息。因为必须读取整个表,它很慢。
myisamchk -eiv tbl_name
这类似-eis,只是告诉你正在做什么。

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
Datafilepointer (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 stripped 2 25062400 1024
3 219 8 multip. double 73 40907776 1024
4 63 10 multip. text packed stripped 5 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

这是对于用在上述例子中的表的数据大小和索引文件的大小:
-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产生信息的类型在下面解释。keyfile是索引文件,记录和行是同义词。

ISAM file
ISAM(索引)文件名。

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

Creation time
数据文件被创建的时间。

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

Data records
在表中有多少记录。

Deleted blocks
有多少删除的块仍然保留着空间。你可以优化表以使这个空间减到最小。见1.4.3 表优化。

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

Deleted data
不能回收的删除数据有多少字节。你可以优化表以使这个空间减到最小。见1.4.3 表优化。

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
在表中所有键值的一张表。对每个键,给出一些底层的信息:

Key
该键的编号。

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

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

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

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

Root
根索引块的地址。

Blocksize
每个索引块的大小。缺省是1024,但是值可以在编译时改变。

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

在上面第一个例子中,第个9键是有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。如果它变得太大,你可用myisamchk重新组织表。见1.4.3 表优化。

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

Deleteblocks
多少块(连接)被删除。

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

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

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

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

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

1.4 使用myisamchk进行崩溃恢复
由MySQL用来存储数据的文件格式以已经被广泛地测试过,但是总是有外部情况可以导致数据库表被破坏:
* mysqld进程在一个写入当中被杀死。
* 计算机的意外关闭(例如,如果计算机掉电)。
* 一个硬件错误

这章描述如何检查和处理在MySQL数据库中的数据损坏。如果你的表损坏很多,你应该尝试找出其原因!在执行崩溃恢复时,理解在一个数据库中的每一个表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前做一个备份。

1.4.1 怎样检查表的错误

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

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

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

1.4.2 怎样修复表
一张损坏的表的症状通常是查询意外中断并且你能看到例如这些错误:
* tbl_name.frm被锁定不能改变。
* 不能找到文件tbl_name.MYI(Errcode :### )。
* 从表处理器的得到错误###(此时,错误135是一个例外)。
* 意外的文件结束。
* 记录文件被毁坏。

在这些情况下,你必须修复表。myisamchk通常能检测并且修复出错的大部分东西。
修复过程包含最多4个阶段,在下面描述。在你开始前,你应该cd到数据库目录和检查表文件的权限,确保他们可被运行mysqld的Unix用户读取(和你,因为你需要存取你正在检查的文件)。如果它拒绝你修改文件,他们也必须是可被你写入的。

阶段1:检查你的表
运行myisamchk *.MYI或(myisamchk -e *.MYI,如果你有更多的时间)。使用-s(沉默)选项禁止不必要的信息。

你必须只修复那些myisamchk报告有一个错误的表。对这样的表,继续到阶段2。
如果在检查时,你得到奇怪的错误(例如out of memory错误),或如果myisamchk崩溃,到阶段3。

阶段 2 :简单安全的修复
首先,试试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. 使用表描述文件创建新的(空)数据和索引文件:
shell> mysql db_name
mysql> DELETE FROM tbl_name;
mysql> quit

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

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

阶段4:非常困难的修复
只有描述文件也破坏了,你才应该到达这个阶段。这应该从未发生过,因为在表被创建以后,描述文件就不再改变了。
1. 从一个备份恢复描述文件并且回到阶段3。你也可以恢复索引文件并且回到阶段2。对后者,你应该用myisamchk -r启动。
2. 如果你没有一个备份但是确切地知道表是怎样被创建的,在另一个数据库中创建表的一个拷贝。删除新的数据文件,然后从其他数据库将描述和索引文件移到破坏的数据库中。这给了你新的描述和索引文件,但是让数据文件独自留下来了。回到阶段2并且尝试重建索引文件。

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

shell> myisamchk -r tbl_name

你可以用SQL的OPTIMIZE TABLE语句使用的相同方式来优化一张表,OPTIMIZE TABLE比较容易,但是myisamchk更快。也没有在一个实用程序和服务器之间不必要的交互可能性,因为当你使用OPTIMIZE TABLE时,服务器做所有的工作。

myisamchk也有你可用来改进一个表的性能的很多其他选项:
-S, --sort-index
-R index_num, --sort-records=index_num
-a, --analyze

对于选项完整的描述见1.1.1 myisamchk调用语法。

1.5 日志文件维护
当MySQL与日志文件一起使用时,你有时想要删除/备份旧的日志文件并且告诉MySQL在新文件中开始记录。见9.2 更新日志。
在一个 Linux (Redhat)的安装上,你可为此使用mysql-log-rotate脚本。如果你从RPM分发安装MySQL,脚本应该自动被安装了。在其他系统上,你必须自己安装一个短脚本,你可从cron启动来处理日志文件。
你可以通过使用mysqladmin flush-logs或SQL命令FLUSH LOGS来强制MySQL开始使用新的日志文件。如果你正在使用MySQL 3.21,你必须使用mysqladmin refresh。

上面的命令做下列事情:
* 如果使用标准日志(--log),关闭并重新打开日志文件。( mysql.log为缺省)。
* 如果使用更新日志(--log-update),关闭更新日志并且重新打开有一个更高的顺序闭编号的新日志文件。

如果你只使用一个更新日志,你只须清空日志文件,然后移走旧的更新日志文件到一个备份中。如果你使用一般的日志,你可以这样做:
shell> cd mysql-data-directory
shell> mv mysql.log mysql.old
shell> mysqladmin flush-tables

然后做一个备份并删除mysql.old。
---------------------------------
myisamchk是MyISAM表维护的一个非常实用的工具。可以使用myisamchk实用程序来获得有关数据库表的信息或检查、修复、优化他们。myisamchk适用MyISAM表(对应.MYI和.MYD文件的表)。
1.myisamchk的调用方法
myisamchk [options] tbl_name ...
其中options指定你想让myisamchk干什么。

它允许你通过使用模式“*.MYI”指定在一个目录所有的表。
shell> myisamchk *.MYI

推荐的快速检查所有MyISAM表的方式是:
shell> myisamchk --silent --fast /path/to/datadir/*/*.MYI
当你运行myisamchk时,必须确保其它程序不使用表。

当你运行myisamchk时内存分配重要.MYIsamchk使用的内存大小不能超过用-O选项指定的。对于大多数情况,使用-O sort=16M应该足够了。另外在修复时myisamchk需要大量硬盘空间,基本上是所涉及表空间的双倍大小。

2.myisamchk的一般选项
--debug=debug_options, -# debug_options
输出调试记录文件。debug_options字符串经常是'd:t:o,filename'。

--silent,-s
沉默模式。仅当发生错误时写输出。

--wait, -w
如果表被锁定,不是提示错误终止,而是在继续前等待到表被解锁。
如果不使用--skip-external-locking,可以随时使用myisamchk来检查表。当检查表时,所有尝试更新表的客户端将等待,直到myisamchk准备好可以继续。
请注意如果用--skip-external-locking选项运行mysqld,只能用另一个myisamchk命令锁定表。

--var_name=value
可以通过--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
如果想要快速修复,将key_buffer_size和sort_buffer_size变量设置到大约可用内存的25%。
可以将两个变量设置为较大的值,因为一个时间只使用一个变量。
myisam_block_size是用于索引块的内存大小。
stats_method影响当给定--analyze选项时,如何为索引统计搜集处理NULL值。

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

--check-only-changed, -C
只检查上次检查后有变更的表。

--extend-check, -e
非常仔细地检查表。如果表有许多索引将会相当慢。

--fast,-F
只检查没有正确关闭的表。

--force, -f
如果myisamchk发现表内有任何错误,则自动进行修复。

--information, -i
打印所检查表的统计信息。

--medium-check, -m
比--extend-check更快速地进行检查。只能发现99.99%的错误

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

--read-only, -T
不要将表标记为已经检查。如果你使用myisamchk来检查正被其它应用程序使用而没有锁定的表很有用

4.myisamchk的修复选项
--backup, -B
将.MYD文件备份为file_name-time.BAK

--character-sets-dir=path
字符集安装目录。

--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可以重新激活被禁用的索引。

--parallel-recover, -p
与-r和-n的用法相同,但使用不同的线程并行创建所有键。

--quick,-q
不修改数据文件,快速进行修复。

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

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

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

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

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

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

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

--description, -d
打印出关于表的描述性信息。
例如:
[root@qa-sandbox-1 mysql]# myisamchk -d user.MYI
MyISAM file: user.MYI
Record format: Packed
Character set: latin1_swedish_ci (8)
Data records: 6 Deleted blocks: 1
Recordlength: 346

table description:
Key Start Len Index Type
1 1 180 unique char packed stripped
181 48 char stripped

6.如何修复表

检查你的表
如果你有很多时间,运行myisamchk *.MYI或myisamchk -e *.MYI。使用-s(沉默)选项禁止不必要的信息。
如果mysqld服务器处于宕机状态,应使用--update-state选项来告诉myisamchk将表标记为'检查过的'。

简单安全的修复
首先,试试myisamchk -r -q tbl_name(-r -q意味着“快速恢复模式”)
如果在修复时,你得到奇怪的错误(例如out of memory错误),或如果myisamchk崩溃,到阶段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。
7. 将老的数据文件拷贝到新创建的数据文件之中。(不要只是将老文件移回新文件之中;你要保留一个副本以防某些东西出错)。回到阶段2。现在myisamchk -r -q应该工作了。(这不应该是一个无限循环)。你还可以使用REPAIR TABLE tbl_name USE_FRM,将自动执行整个程序。

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

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

7.清理碎片
对Innodb 表则可以通过执行以下语句来整理碎片,提高索引速度:
ALTER TABLE tbl_name ENGINE = Innodb;
这其实是一个 NULL 操作,表面上看什么也不做,实际上重新整理碎片了。
对myisam表格,为了组合碎片记录并且消除由于删除或更新记录而浪费的空间,以恢复模式运行myisamchk:
shell> myisamchk -r tbl_name

你可以用SQL的OPTIMIZE TABLE语句使用的相同方式来优化表,OPTIMIZE TABLE可以修复表并对键值进行分析,并且可以对索引树进行排序以便更快地查找键值。

8.建立表检查计划
运行一个crontab,每天定期检查所有的myisam表格。
35 0 * * 0 /path/to/myisamchk --fast --silent /path/to/datadir/*/*.MYI

9.获取表的信息
myisamchk -d tbl_name:以“描述模式”运行myisamchk,生成表的描述
myisamchk -d -v tbl_name: 为了生成更多关于myisamchk正在做什么的信息,加上-v告诉它以冗长模式运行。
myisamchk -eis tbl_name:仅显示表的最重要的信息。因为必须读取整个表,该操作很慢。
myisamchk -eiv tbl_name:这类似 -eis,只是告诉你正在做什么。

-----------------------
MySQL数据库损坏数据的恢复
环境:windows2003
数据库:mysql
损坏数据文件名:products
将数据库内容物理文件直接导入到mysqldata下,每只表各3个文件,依次分别为:.frm .MYD .MYI
我又想到了mysql下应有自己本身的修复程序等,于是想通过其来进行恢复,心想应不会太差劲吧,在网上查找了资料,提示:由于临时断电,使用kill -9中止MySQL服务进程,或者是mysql正在高速运转时进行强制备份操作时等,所有的这些都可能会毁坏MySQL的数据文件。如果在被干扰时,服务正在改变文件,文件可能会留下错误的或不一致的状态。因为这样的毁坏有时是不容易被发现的,当你发现这个错误时可能是很久以后的事了。

于是,当你发现这个问题时,也许所有的备份都有同样的错误。
我想我现在碰到的问题可能是这个问题,因为备份的数据也是有部分损坏的数据,所以导致不能完全运行,意识到myisamchk程序对用来检查和修改的 MySQL数据文件的访问应该是唯一的。如果MySQL服务正在使用某一文件,并对myisamchk正在检查的文件进行修改,myisamchk会误以为发生了错误,并会试图进行修复--这将导致MySQL服务的崩溃!这样,要避免这种情况的发生,通常我们需要在工作时关闭MySQL服务。
作为选择,你也可以暂时关闭服务以制作一个文件的拷贝,然后在这个拷贝上工作。当你做完了以后,重新关闭服务并使用新的文件取代原来的文件(也许你还需要使用期间的变更日志)。
MySQL数据目录不是太难理解的。每一个数据库对应一个子目录,每个子目录中包含了对应于这个数据库中的
数据表的文件。每一个数据表对应三个文件,它们和表名相同,但是具有不同的扩展名。tblName.frm文件是
表的定义,它保存了表中包含的数据列的内容和类型。tblName.MYD文件包含了表中的数据。tblName.MYI文件包含了表的索引(例如,它可能包含lookup表以帮助提高对表的主键列的查询)。
要检查一个表的错误,只需要运行myisamchk(在MySQL的bin目录下)并提供文件的位置和表名,或者是表的索引
文件名:
% myisamchk /usr/local/mysql/var/dbName/tblName
% myisamchk /usr/local/mysql/var/dbName/tblName.MYI
上面的两个命令都可以执行对指定表的检查。要检查数据库中所有的表,可以使用通配符:
% myisamchk /usr/local/mysql/var/dbName/*.MYI

要检查所有数据库中的所有表,可以使用两个通配符:
% myisamchk /usr/local/mysql/var/*/*.MYI
如果不带任何选项,myisamchk将对表文件执行普通的检查。如果你对一个表有怀疑,但是普通的检查不能发现任何错误,你可以执行更彻底的检查(但是也更慢),这需要使用--extend-check选项:
% myisamchk --extend-check /path/to/tblName
对错误的检查是没有破坏性的,这意味着你不必担心执行对你的数据文件的检查会使已经存在的问题变得更糟。另一方面,修复选项,虽然通常也是安全的,但是它对你的数据文件的更改是无法撤消的。因为这个原因,我们强烈推荐你试图修复一个被破坏的表文件时首先做个备份,并确保在制作这个备份之前你的MySQL服务是关闭的。

当你试图修复一个被破坏的表的问题时,有三种修复类型。如果你得到一个错误信息指出一个临时文件不能建立,删除信息所指出的文件并再试一次--这通常是上一次修复操作遗留下来的。
这三种修复方法如下所示:
% myisamchk --recover --quick /path/to/tblName
% myisamchk --recover /path/to/tblName
% myisamchk --safe-recover /path/to/tblName

第一种是最快的,用来修复最普通的问题;而最后一种是最慢的,用来修复一些其它方法所不能修复的问题。

检查和修复MySQL数据文件
如果上面的方法无法修复一个被损坏的表,在你放弃之前,你还可以试试下面这两个技巧:
如果你怀疑表的索引文件(*.MYI)发生了不可修复的错误,甚至是丢失了这个文件,你可以使用数据文件(*.MYD)和数据格式文件(*.frm)重新生成它。首先制作一个数据文件(tblName.MYD)的拷贝。重启你的MySQL服务并连接到这个服务上,使用下面的命令删除表的内容:
mysql> DELETE FROM tblName;
在删除表的内容的同时,会建立一个新的索引文件。退出登录并重新关闭服务,然后用你刚才保存的数据文件(tblName.MYD)覆盖新的(空)数据文件。最后,使用myisamchk执行标准的修复(上面的第二种方法),根据表的数据的内容和表的格式文件重新生成索引数据。

如果你的表的格式文件(tblName.frm)丢失了或者是发生了不可修复的错误,但是你清楚如何使用相应的CREATE TABLE语句来重新生成这张表,你可以重新生成一个新的.frm文件并和你的数据文件和索引文件(如果索引文件有问题,使用上面的方法重建一个新的)一起使用。首先制作一个数据和索引文件的拷贝,然后删除原来的文件(删除数据目录下有关这个表的所有记录)。

启动MySQL服务并使用当初的CREATE TABLE文件建立一个新的表。新的.frm文件应该可以正常工作了,但是最好你还是执行一下标准的修复(上面的第二种方法)。如果有类似问题,建议自己先分析问题根源,查找资料,自己动手解决,不但可以多学更多知识技巧,更重要的是自己也在解决问题的同时得到了快乐.

------------------------------------------
使用myisamchk命令进行崩溃恢复Mysql数据表
由MySQL用来存储数据的文件格式以已经被广泛地测试过,但是总是有外部情况可以导致数据库表被破坏:
1.mysqld进程在一个写入当中被杀死。
2.计算机的意外关闭(例如,如果计算机掉电)。
3.一个硬件错误

例如:
Table ‘.\数据库名\表名’ is marked as crashed and should be repaired

在执行崩溃恢复时,理解在一个数据库中的每一个表tbl_name对应的在数据库目录中的3个文件是很重要的:
文件                   用途
“tbl_name.frm” 表定义(表格)文件
“tbl_name.MYD” 数据文件
“tbl_name.MYI” 索引文件

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

怎样检查表的错误
为了检查一张表,使用下列命令:

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

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

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

myisamchk用法
注意:使用myisamchk前,要确保mysqld没有在访问要检查的表。最好停止mysqld。
1 执行myisamchk –update-state -s *.myi,检查有哪些索引文件出了问题(可能会化费比较长的时间)。
update-state选项只有在停止mysqld的时候使用,-s表示忽略一些正常的表列出的信息,只列出错误。

2 对于每一个损坏的表,尝试myisamchk -r -q table_name。这是快速修复模式,会自动检查索引表和数据表是否能够一致。如果一致,则可以修复。

3 如果快速修复模式失败,考虑:myisamchk -r table_name,会删除不一致的数据和索引,并重新构建索引。
4 如果3失败,考虑:myisamchk –safe-recover table_name

该文章最后由 阿炯 于 2012-05-07 14:06:06 更新,目前是第 3 版。