譯者:晏子 (clyan@sohu.com)
GB 碼主頁:http://linuxdb.yeah.net
Big5 轉碼者:statue
(statue@bbs.yzu.edu.tw)
詞彙轉換:彭武興 (wilson@mailbox.com.tw)
Big5 碼主頁:
http://cnpa.yzu.edu.tw/~cfc/docs/mysqldoc_big5/manual_toc.html
Big5 碼分站:
http://php.wilson.gs/mysqldoc/big5/manual_toc.html
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”。