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,只是告訴你正在做什么。
10.Myisamchk產生的信息解釋
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
在表中所有鍵值的列表。對每個鍵,給出一些底層的信息:
Key
該鍵的編號。
Start
該索引部分從記錄的哪里開始。
Len
該索引部分是多長。對于緊湊的數字,這應該總是列的全長。對字符串,它可以比索引的列的全長短些,
因為你可能會索引到字符串列的前綴。
Index
unique或multip(multiple)。表明一個值是否能在該索引中存在多次。
Type
該索引部分有什么數據類型。這是一個packed、stripped或empty選項的ISAM數據類型。
Root
根索引塊的地址。
Blocksize
每個索引塊的大小。默認是1024,但是從源碼構建MySQL時,該值可以在編譯時改變。
Rec/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指這樣的指針使用的內存量之和。