檢查和維護(hù)MYSQL數(shù)據(jù)庫表
本章的重點(diǎn)是檢測(cè)和解決表的問題,而不論問題是如何引起的。對(duì)于表的檢查和修復(fù),MySQL管理員最好的朋友是myisamchk 和isamchk 實(shí)用程序。這兩個(gè)程序有好幾個(gè)功能,我們丫詰?章討論了怎樣使用它們執(zhí)行索引鍵的分布分析和索引的釋放與激活。還可以使用它們檢查表和修復(fù)有問題的表。這使您能在表變壞之前(使表不能使用之前)修正故障。
myisamchk 和isamchk 提供的全部選項(xiàng)的清單在附錄E 中。有關(guān)其他的背景,請(qǐng)參閱MySQL參考指南的“維護(hù)MySQL安裝”一章。
表的故障檢測(cè)和修正的一般過程如下:
1) 檢查出錯(cuò)的表。如果該表檢查通過,則完成任務(wù),否則必須修復(fù)它。
2) 在開始修復(fù)之前對(duì)表文件進(jìn)行拷貝,以防萬一。
3) 試著修復(fù)表。
4) 如果修復(fù)操作失敗,從數(shù)據(jù)庫備份和更新日志中恢復(fù)此表。
上述過程的最后一步假定您已經(jīng)執(zhí)行了數(shù)據(jù)庫備份并允許更新日志有效。如果不是這樣的話,系統(tǒng)將有危險(xiǎn)。參考第11章查找一下怎樣使用mysqlaump 和怎樣開啟更新日志。您肯定不想不可挽回地丟失一個(gè)表,因此,應(yīng)努力地做備份。
在使用myisamchk 或isamchk 檢查或修復(fù)表之前,應(yīng)該滿足一些初步需求:
建立常規(guī)的數(shù)據(jù)庫備份過程并允許更新日志,以防事情越來越糟使表的毀壞不能修復(fù)。筆者好像在以前提醒過這一點(diǎn)?
在開始試驗(yàn)之前應(yīng)先仔細(xì)地閱讀本章的內(nèi)容。尤其是不應(yīng)該在閱讀“避免與MySQL服務(wù)器交互作用”之前進(jìn)行操作,因?yàn)樗鼘⒂懻摦?dāng)您試圖在一個(gè)表上執(zhí)行檢查或修復(fù)過程時(shí)服務(wù)器正在使用這個(gè)表所引起的問題。它還討論怎樣在服務(wù)器運(yùn)行時(shí)防止那些問題發(fā)生。
當(dāng)運(yùn)行表檢查或修復(fù)時(shí),您應(yīng)該被注冊(cè)在運(yùn)行mysql的賬號(hào)下,因?yàn)槟枰獙?duì)表文件讀寫訪問。
myisamchk 和isamchk 的調(diào)用語法
MySQL的myisamchk 和isamchk 實(shí)用程序很類似,多數(shù)時(shí)候它們可以用同樣的方式使用。它們之間的主要區(qū)別是它們所使用的表的類型。對(duì)于MyISAM 表,使用my i s a m c h k,而對(duì)于ISAM 表,則使用i s a m c h k。您可以通過表的索引文件的擴(kuò)展名來告訴表使用哪種存儲(chǔ)格式。擴(kuò)展名“. M Y I”表明是一個(gè)MyISAM 表,而“. I S M”表明是ISAM 表。
為了使用任一個(gè)實(shí)用程序,應(yīng)指明您所要檢查或修復(fù)的表,以及指明要執(zhí)行的操作類型的選項(xiàng):
% myisamchk options tbl_name...
% isamchk options tbl_name...
tbl_name 參數(shù)可以是表名也可以是該表的索引文件名。如果指定多個(gè)表,可以很容易地使用文件名模式來拾取目錄中所有相應(yīng)的文件:
% myisamchk options *.MYI
% isamchk options *.ISM
不會(huì)因?yàn)楦嬖V了錯(cuò)誤的程序來檢查某個(gè)表而使該表毀壞,但是除了發(fā)布一條警告消息外此程序不做任何事情。例如,下面的第一條語句將檢查當(dāng)前目錄中的所有MyISAM 表,而第二條語句只顯示一條警告消息:
% myisamchk *.MYI 正確
% myisamchk *.ISM 不正確─文件類型錯(cuò)
不論是myisamchk 還是isamchk 都不對(duì)表所在的位置做任何判斷,因此,應(yīng)該或者在包含表文件的目錄中運(yùn)行程序,或者指定表的路徑名。這允許您將表文件拷貝到另一個(gè)目錄中并用該拷貝進(jìn)行操作。
檢查表
myisamchk 和isamchk 提供了表檢查方法,這些方法在徹底檢查表的程度方面有差異。通常用標(biāo)準(zhǔn)方法就足夠了。如果標(biāo)準(zhǔn)檢查報(bào)告沒有發(fā)現(xiàn)錯(cuò)誤而您仍然懷疑有毀壞(或許因?yàn)椴樵儧]有正常地工作),可能要執(zhí)行更徹底的檢查。要想用任意一個(gè)實(shí)用程序執(zhí)行標(biāo)準(zhǔn)的表檢查,則不用帶任何選項(xiàng)直接調(diào)用即可:
% myisamchk tbl_name
% isamchk tbl_name
為了執(zhí)行擴(kuò)充檢查,使用--extend-check 選項(xiàng)。該選項(xiàng)非常慢,但檢查極為徹底。對(duì)于該表的數(shù)據(jù)文件中的每個(gè)記錄,索引文件中的每個(gè)索引的相關(guān)鍵都被檢查以確保它真正指向正確的記錄。myisamchk 還有一個(gè)中間選項(xiàng)- - m e d i um - c h e c k,它不如擴(kuò)展檢查徹底,但速度快。
如果對(duì)于--extend-check 檢查不報(bào)告錯(cuò)誤,則可以肯定表是好的。如果您仍然感覺表有問題,那原因肯定在其他地方。應(yīng)重新檢查任何好像有問題的查詢以驗(yàn)證查詢是正確書寫的。如果您認(rèn)為問題可能是MySQL服務(wù)器的原因,應(yīng)考慮整理一份故障報(bào)告或升級(jí)到新的版本上。
如果myisamchk 或isamchk 報(bào)告表有錯(cuò)誤,應(yīng)用下節(jié)中的說明修復(fù)它們。
修復(fù)表
表的修復(fù)是一項(xiàng)可怕的工作,如果具體問題非常獨(dú)特則更難進(jìn)行。然而,有一些常規(guī)的指導(dǎo)思想和過程,可以遵循它們來增加修正表的機(jī)會(huì)。通常,開始時(shí)可以用最快的修復(fù)方法,看看是否能修正故障。如果發(fā)現(xiàn)不行的話,可以逐步升級(jí)到更徹底的(但更慢的)修復(fù)方法上,直到故障被修復(fù)或您不能繼續(xù)升級(jí)為止(實(shí)際上,大多數(shù)問題不用更大規(guī)模的和更慢的方法就能修正)。如果表不能修復(fù),則從備份中恢復(fù)該表。有關(guān)使用備份文件和更新日志進(jìn)行恢復(fù)的指導(dǎo)在已第11章中給出。
1. 執(zhí)行標(biāo)準(zhǔn)的表修復(fù)
為了修復(fù)一個(gè)表,執(zhí)行下列步驟:
1) 試著用--recover 選項(xiàng)修正表,但也可以用--quick 選項(xiàng)試圖只根據(jù)索引文件的內(nèi)容進(jìn)行恢復(fù)。這樣將不觸及數(shù)據(jù)文件:
% myisamchk --recover --quick tbl_name
% isamchk --recover --quick tbl_name
2) 如果問題仍存在,再試一下上一步的命令,但忽略--quick 選項(xiàng),以允許my i s a m c h k或isamchk 前進(jìn)并修改數(shù)據(jù)文件:
% myisamchk --recover tbl_name
% isamchk --recover tbl_name
3) 如果還不工作,試一試--safe-recover 修復(fù)方法。這種方法比普通的恢復(fù)方法要慢,但能夠修正-recover 方法不能修正的幾個(gè)問題:
% myisamchk --safe-recover tbl_name
% isamchk --safe-recover tbl_name
如果myisamchk 或isamchk 由于一個(gè)“C a n’t create new temp file: file_name” 的錯(cuò)誤消息在任何一步中停止,應(yīng)該重復(fù)這個(gè)命令并增加--force 選項(xiàng)以迫使清除臨時(shí)文件。這個(gè)臨時(shí)文件可能是從上一次失敗的修復(fù)中留下的。
在修復(fù)表之前拷貝它們?cè)趫?zhí)行表修復(fù)前應(yīng)該遵循的一個(gè)常規(guī)的預(yù)防措施是做該表的新拷貝。這種情況未必出現(xiàn),但如果發(fā)生,則可以從拷貝文件中做該表的新的拷貝并試試另一種恢復(fù)方法。
2. 標(biāo)準(zhǔn)表修復(fù)方法失敗時(shí)怎么辦
如果標(biāo)準(zhǔn)的修復(fù)過程未能修復(fù)表,則索引文件可能在修復(fù)時(shí)丟失或毀壞。盡管未必可能,但還是有可能使表的描述文件丟失。不論哪種情況,都需要替換受影響的文件,然后再試試標(biāo)準(zhǔn)修復(fù)過程。
為了重新生成索引文件,可以使用下列過程:
1) 定位到包含崩潰表的數(shù)據(jù)庫目錄中。
2) 將該表的數(shù)據(jù)文件移到安全的地方。
3) 調(diào)用mysql并通過執(zhí)行下列語句重新創(chuàng)建新的空表,該語句使用表的描述文件tbl_name.frm 重新開始生成新的數(shù)據(jù)和索引文件:
mysql> DELETE FROM tbl_name;
4) 退出mysql,將原始的數(shù)據(jù)文件移回到數(shù)據(jù)庫目錄中,替換剛建立的新的空文件。
5) 再試試標(biāo)準(zhǔn)表修復(fù)方法。
為了恢復(fù)該表的描述文件,可先從備份文件中恢復(fù),然后再試著用標(biāo)準(zhǔn)修復(fù)方法。如果由于某些原因沒有備份,但知道建立表的CREATE TABLE 語句,則仍可以恢復(fù)該文件:
1) 定位到包含崩潰表的數(shù)據(jù)庫目錄中。
2) 將該表的數(shù)據(jù)文件移動(dòng)到安全的地方。如果想要使用索引的話,還需將索引文件移走。
3) 調(diào)用mysql并發(fā)布CREATE TABLE 語句建立該表。
4) 退出mysql,將原始數(shù)據(jù)文件移回?cái)?shù)據(jù)庫目錄中,替換剛才新建的數(shù)據(jù)文件。如果在步驟2移動(dòng)了索引文件,則也要將其移回?cái)?shù)據(jù)庫目錄中。
5) 再試試標(biāo)準(zhǔn)表修復(fù)方法。
避免與MySQL服務(wù)器交互作用
當(dāng)您正在運(yùn)行表的檢查/修復(fù)實(shí)用程序時(shí),您或許不想讓MySQL服務(wù)器和實(shí)用程序同時(shí)訪問一個(gè)表。如果兩個(gè)程序都向表中寫數(shù)據(jù)顯然是一件壞事,但是,當(dāng)一個(gè)程序在寫入時(shí)另一個(gè)程序在讀取也不是件好事。如果表正由一個(gè)程序?qū)懭耄瑫r(shí)進(jìn)行讀取的另一個(gè)程序會(huì)被
搞亂。
如果您關(guān)閉服務(wù)器,就可以保證在服務(wù)器和myisamchk 或isamchk 之間沒有交互作用。但是管理員極不愿意使服務(wù)器完全地脫機(jī),因?yàn)檫@使得沒有故障的數(shù)據(jù)庫和表也不可用。本節(jié)中討論的過程將幫助您避免服務(wù)器和myisamchk 或isamchk 之間的交互作用。
服務(wù)器有兩種類型的鎖定方法。它使用內(nèi)部鎖定避免客戶機(jī)的請(qǐng)求相互干擾──例如,避免客戶機(jī)的SELECT 查詢被另一個(gè)客戶機(jī)的UPDATE查詢所干擾。服務(wù)器還使用外部鎖定(文件級(jí)鎖)來防止其他程序在服務(wù)器使用表時(shí)修改該表的文件。通常,在表的檢查操作中服務(wù)器將外部鎖定與myisamchk 或isamchk 組合使用。但是,外部鎖定在某些系統(tǒng)中是禁用的,因?yàn)樗荒芸煽康剡M(jìn)行工作。對(duì)運(yùn)行myisamchk 和isamchk 所選擇的過程取決于服務(wù)器是否能使用外部鎖定。如果不使用,則必須使用內(nèi)部鎖定協(xié)議。
如果服務(wù)器用--skip-locking 選項(xiàng)運(yùn)行,則外部鎖定禁用。該選項(xiàng)在某些系統(tǒng)中是缺省的,如L i n ux。可以通過運(yùn)行mysqladmin variables 命令確定服務(wù)器是否能夠使用外部鎖定。檢查skip_locking 變量的值并按以下方法進(jìn)行:
如果skip_locking 為o ff,則外部鎖定有效。您可以繼續(xù)并運(yùn)行任一個(gè)實(shí)用程序來檢查表。服務(wù)器和實(shí)用程序?qū)⒑献鲗?duì)表進(jìn)行訪問。但是,在運(yùn)行任何一個(gè)實(shí)用程序之前,應(yīng)該用mysqladmin flush-tables 刷新表的高速緩存。為了修復(fù)表,應(yīng)該使用表的修復(fù)鎖定協(xié)議。
如果skip_locking 為o n,則禁用外部鎖定,但在myisamchk 或isamchk 檢查或修復(fù)一個(gè)表時(shí)服務(wù)器并不知道,最好關(guān)閉服務(wù)器。如果堅(jiān)持使服務(wù)器保持開啟狀態(tài),需要確保在您使用此表時(shí)沒有客戶機(jī)來訪問它。必須使用恰當(dāng)?shù)逆i定協(xié)議告訴服務(wù)器使該表獨(dú)處,并阻塞客戶機(jī)對(duì)其訪問。
這里所描述的鎖定協(xié)議使用服務(wù)器的內(nèi)部鎖定機(jī)制,以防止服務(wù)器在您利用my i s a m c h k或isamchk 工作時(shí)訪問表。通常的辦法是調(diào)用mysql并對(duì)要檢查或修復(fù)的表發(fā)布L O C K TABLE 語句。然后,在mysql空閑時(shí)(即運(yùn)行,但除了保持該表鎖定外不用它做任何事情),運(yùn)行myisamchk 或i s a m c h k。在myisamchk 或isamchk 結(jié)束后,可以切換到mysql會(huì)話中并釋放該鎖以告訴服務(wù)器程序執(zhí)行完畢此表可以再次使用了。
檢查和修復(fù)的鎖定協(xié)議有點(diǎn)區(qū)別。對(duì)于檢查,您只需要獲得讀鎖。在這種情況下,只能讀取表,但不能修改它,因此它也允許其他客戶機(jī)讀取它。讀鎖足以防止其他客戶機(jī)修改表。對(duì)于修復(fù),您必須獲得寫鎖以防止任何客戶機(jī)在您對(duì)表進(jìn)行操作時(shí)修改它。
鎖定協(xié)議使用LOCK TABLE 和UNLOCK TABLE 語句獲得并釋放鎖。協(xié)議還使用F L U S H TABLES 告訴服務(wù)器刷新磁盤中任何未決的改變,并在通過表修復(fù)實(shí)用程序修改表后重新打開該表。您必須從單個(gè)mysql會(huì)話中執(zhí)行所有L O C K、FLUSH 和UNLOCK 語句。如果鎖定一個(gè)表然后退出mysql,則該鎖將釋放,且運(yùn)行myisamchk 或isamchk 將不再是安全的!
如果保持打開兩個(gè)窗口的狀態(tài),且一個(gè)運(yùn)行mysql,而另一個(gè)運(yùn)行myisamchk 或i s a m c h k,則運(yùn)行鎖定過程將會(huì)變得很容易。這樣允許您很容易地在程序之間進(jìn)行切換。如果不是運(yùn)行在視窗環(huán)境中,當(dāng)運(yùn)行myisamchk 或isamchk 時(shí),將需要使用外殼程序的作業(yè)控制工具暫停和恢復(fù)mysql。下面的指導(dǎo)顯示出對(duì)myisamchk 或isamchk 的命令,可用與您正在使用的表相對(duì)應(yīng)的那個(gè)命令。
1. 對(duì)檢查操作鎖定表
此過程只針對(duì)表的檢查,不針對(duì)表的修復(fù)。在窗口1中,調(diào)用mysql并發(fā)布下列語句:
% mysqldb_name
mysql>LOCK TABLE tbl_name READ;
mysql>FLUSH TABLES;
該鎖防止其他客戶機(jī)在檢查時(shí)寫入該表和修改該表。FLUSH 語句導(dǎo)致服務(wù)器關(guān)閉表的文件,它將刷新仍然在高速緩存中的任何未寫入的改變。
當(dāng)mysql空閑時(shí),切換到窗口2 并檢查該表:
% myisamchk tbl_name
% isamchk tbl_name
當(dāng)myisamchk 或isamchk 結(jié)束時(shí),切換回到窗口1的mysql會(huì)話并釋放該表鎖:
mysql>UNLOCK TABLE;
如果myisamchk 或isamchk 指出發(fā)現(xiàn)該表的問題,將需要執(zhí)行表的修復(fù)。
2. 對(duì)修復(fù)操作鎖定表
修復(fù)表的鎖定過程類似于檢查表的過程,但有兩個(gè)區(qū)別。第一,您必須得到寫鎖而非讀鎖。由于您將要修改表,因此根本不允許客戶機(jī)對(duì)其進(jìn)行訪問。第二,必須在執(zhí)行修復(fù)之后發(fā)布FLUSH TABLE 語句,因?yàn)閙yisamchk 和isamchk 建立了新的索引文件,除非再次刷新
該表的高速緩存否則服務(wù)器將不會(huì)注意到它:
% mysqldb_name
mysql>LOCK TABLE tbl_name WRITE;
mysql>FLUSH TABLES;
利用mysql的空閑切換到窗口2,做該表的數(shù)據(jù)庫文件的拷貝,然后運(yùn)行myisamchk 或i s a m c h k:
% cp tbl_name.* |some|other|directory
% myisamchk --recover tbl_name
% isamchk --recover tbl_name
--recover 選項(xiàng)只是針對(duì)安裝而設(shè)置的。這些特殊選項(xiàng)的選擇將取決于您執(zhí)行修復(fù)的類型。myisamchk 或isamchk 運(yùn)行完成后,切換回到窗口1的mysql會(huì)話,再次刷新該表的高速緩存并釋放表鎖:
mysql>FLUSH TABLES;
mysql>UNLOCK TABLE;
快速運(yùn)行myisamchk 和i s a m c h k
myisamchk 和isamchk 的運(yùn)行可能會(huì)花很長(zhǎng)時(shí)間,尤其是您正在處理一個(gè)大表或使用一個(gè)更廣泛的檢查或修復(fù)方法時(shí)。通過告訴這些程序在運(yùn)行時(shí)使用更多的內(nèi)存,能夠提高它們的速度。這兩個(gè)實(shí)用程序都有幾個(gè)可設(shè)置的操作參數(shù)。其中最重要的是控制程序使用的緩沖
區(qū)大小的變量:
變量 | 含義 |
key _ buffer _ s i z e | 用于存放索引塊的緩沖區(qū)大小 |
r e a d _ buffer _ s i z e | 讀操作用的緩沖區(qū)大小 |
sort _ buffer _ s i z e | 排序用的緩沖區(qū)大小 |
w r i t e _ buffer _ s i z e | 寫操作用的緩沖區(qū)大小 |
要想查看任一個(gè)程序使用的這些變量的缺省值,可用--help 選項(xiàng)運(yùn)行該程序。要想指定其他的值,可在該命令上使用--set-variable variable=value 或-O variable=value。您可以將變量的名字簡(jiǎn)化成key、r e a d、sort 和w r i t e。例如,可告訴myisamchk 使用16MB 的排序緩沖區(qū)和1MB 的讀寫緩沖區(qū),其調(diào)用如下:
% myisamchk -0 sort=16M -0 read=1M write=1M ...
sort _ buffer_size 只能利用--recover 選項(xiàng)來使用(而不是利用- - s a f e _ r e c o ver),在這種情況下,key _ buffer 不能使用。
減少服務(wù)器的停機(jī)時(shí)間
防止服務(wù)器訪問(您正在處理的)表的另一種方法是在數(shù)據(jù)目錄的外面使用該表文件的拷貝。這樣并不能消除交互作用的問題,因?yàn)槿匀槐仨毞乐狗⻊?wù)器訪問(并可能修改)正在進(jìn)行拷貝的表。但是,如果您不愿意使服務(wù)器脫機(jī)的話,該路線可能是使服務(wù)器停機(jī)時(shí)間最小化的一種方法,這對(duì)您是有吸引力的。在將該表的文件拷貝到另一個(gè)目錄時(shí)關(guān)閉服務(wù)器,然后恢復(fù)服務(wù)器。
myisamchk 的未來打算
myisamchk 的表檢查和修復(fù)功能打算在MySQL3.23 版本系列的某個(gè)時(shí)候被合并到服務(wù)器中。如果這種打算實(shí)現(xiàn),對(duì)表的檢查和修復(fù)將更容易,因?yàn)榉⻊?wù)器與my i s a m c h k的交互問題將不再會(huì)出現(xiàn)。
同樣,您能夠告訴服務(wù)器在啟動(dòng)時(shí)檢查表,因此在啟動(dòng)服務(wù)器前將不需要設(shè)置任何特殊的命令在引導(dǎo)期間執(zhí)行。該程序不對(duì)ISAM 表進(jìn)行操作,因此在服務(wù)器獲得表的檢修復(fù)能力時(shí),應(yīng)考慮將ISAM 表轉(zhuǎn)換成MyISAM 表。請(qǐng)查看新發(fā)行版的MySQL參考指南,了解在此范圍內(nèi)有什么新進(jìn)展。可以用ALTER TABLE 語句轉(zhuǎn)換表的類型:
ALTER TABLE tbl_name TYPE=MYISAM
關(guān)鍵字:MYSQL、數(shù)據(jù)庫、服務(wù)器
新文章:
- CentOS7下圖形配置網(wǎng)絡(luò)的方法
- CentOS 7如何添加刪除用戶
- 如何解決centos7雙系統(tǒng)后丟失windows啟動(dòng)項(xiàng)
- CentOS單網(wǎng)卡如何批量添加不同IP段
- CentOS下iconv命令的介紹
- Centos7 SSH密鑰登陸及密碼密鑰雙重驗(yàn)證詳解
- CentOS 7.1添加刪除用戶的方法
- CentOS查找/掃描局域網(wǎng)打印機(jī)IP講解
- CentOS7使用hostapd實(shí)現(xiàn)無AP模式的詳解
- su命令不能切換root的解決方法
- 解決VMware下CentOS7網(wǎng)絡(luò)重啟出錯(cuò)
- 解決Centos7雙系統(tǒng)后丟失windows啟動(dòng)項(xiàng)
- CentOS下如何避免文件覆蓋
- CentOS7和CentOS6系統(tǒng)有什么不同呢
- Centos 6.6默認(rèn)iptable規(guī)則詳解