翻译:晏子(yanzi) 主页:http://linuxdb.yeah.net
myisamchk
进行表的维护和崩溃恢复为了检查/修复MyISAM表(.MYI
和.MYD
),你应该使用myisamchk
实用程序。为了检查/修复ISAM表(.ISM
和.ISD
),你应该使用isamchk
实用程序。见9.4 MySQL 表类型。
在下文中,我们将讨论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
句法。
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
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
。
在一个定期基础而非等到问题出现才实施数据库表的检查是一个好主意。为维护目的,你能使用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。
为了获得关于一个表的描述或统计,使用显示在下面的命令。我们以后更详细地解释某些信息。
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-version
Creation time
Recover time
Data records
Deleted blocks
Datafile: Parts
Data
records
相同。 Deleted data
Datafile pointer
Keyfile pointer
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
Rec/key
myisamchk
-a
更新。如果这根本没被更新,给定一个30的缺省值。Keyblocks used
myisamchk
被重新组织,值非常高(很接近理论上的最大值)。
Packed
CHAR
/VARCHAR
/DECIMAL
键。对长字符串如姓名,这能显著地减少使用空间。在上面的第3个例子中,第4个键是10个字符长并且在空间上达到60%的缩减。Max levels
Records
M.recordlength
Packed
Packed
值表明这样做达到的节约的百分比。
Recordspace used
Empty space
Blocks/Record
myisamchk
重新组织表。见13.4.3 表优化。 Recordblocks
Deleteblocks
Recorddata
Deleted data
Lost space
Linkdata
Linkdata
被这样的指针使用的内存量之和。
如果一张表已经用myisampack
压缩了,myisamchk -d
打印每个表列的附加信息。对于它的一个例子及其含义的描述,见12.5 MySQL压缩只读表生成器。
myisamchk
进行崩溃恢复由MySQL用来存储数据的文件格式以已经被广泛地测试过,但是总是有外部情况可以导致数据库表被破坏:
mysqld
进程在一个写入当中被杀死。这章描述如何检查和处理在MySQL数据库中的数据损坏。如果你的表损坏很多,你应该尝试找出其原因!见G.1 调试一个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
前做一个备份。
为了检查一张表,使用下列命令:
myisamchk tbl_name
myisamchk
或用-s
或--silent
选项的任何一个。
myisamchk -e tbl_name
-e
意思是“扩展检查”)。它对每一行做每个键的读检查以证实他们确实指向正确的行。这在一个有很多键的大表上可能花很长时间。myisamchk
通常将在它发现第一个错误以后停止。如果你想要获得更多的信息,你能增加--verbose
(-v
)选项。这使得myisamchk
继续一直到最多20个错误。在一般使用中,一个简单的myisamchk
(没有除表名以外的参数)就足够了。myisamchk -e -i tbl_name
-i
选项告诉myisamchk
还打印出一些统计信息。一张损坏的表的症状通常是查询意外中断并且你能看到例如这些错误:
在这些情况下,你必须修复表。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
意味着“快速恢复模式”)。这将试图不接触数据文件来修复索引文件。如果数据文件包含它应有的一切和在数据文件指向正确地点的删除连接,这应该管用并且表可被修复。开始修理下一张表。否则,使用下列过程:
myisamchk -r tbl_name
(-r
意味着“恢复模式”)。这将从数据文件中删除不正确的记录和已被删除的记录并重建索引文件。myisamchk --safe-recover tbl_name
。安全恢复模式使用一个老的恢复方法,处理常规恢复模式不行的少数情况(但是更慢)。如果在修复时,你得到奇怪的错误(例如out of memory
错误),或如果myisamchk
崩溃,到阶段3。
舞台 3 :困难的修理
如果在索引文件的第一个16K块被破坏,或包含不正确的信息,或如果索引文件丢失,你只应该到这个阶段 。在这种情况下,创建一个新的索引文件是必要的。按如下这样做:
shell> mysql db_name mysql> DELETE FROM tbl_name; mysql> quit
回到阶段2。现在myisamchk -r -q
应该工作了。(这不应该是一个无限循环)。
阶段4:非常困难的修复
只有描述文件也破坏了,你才应该到达这个阶段。这应该从未发生过,因为在表被创建以后,描述文件就不再改变了。
myisamchk
-r
启动。 为了组合成碎片的记录并且消除由于删除或更新记录而浪费的空间,
以恢复模式运行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
对于选项完整的描述见13.1.1
myisamchk
调用语法。
当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”。