5.9.4. 表維護(hù)和崩潰恢復(fù)
我們提供的服務(wù)有:網(wǎng)站建設(shè)、成都網(wǎng)站制作、微信公眾號(hào)開(kāi)發(fā)、網(wǎng)站優(yōu)化、網(wǎng)站認(rèn)證、鹽都ssl等。為上千多家企事業(yè)單位解決了網(wǎng)站和推廣的問(wèn)題。提供周到的售前咨詢(xún)和貼心的售后服務(wù),是有科學(xué)管理、有技術(shù)的鹽都網(wǎng)站制作公司
后面幾節(jié)討論如何使用myisamchk來(lái)檢查或維護(hù)MyISAM表(對(duì)應(yīng).MYI和.MYD文件的表)。
你可以使用myisamchk實(shí)用程序來(lái)獲得有關(guān)你的數(shù)據(jù)庫(kù)表的信息或檢查、修復(fù)、優(yōu)化他們。下列小節(jié)描述如何調(diào)用myisamchk(包括它的選項(xiàng)的描述),如何建立表的維護(hù)計(jì)劃,以及如何使用myisamchk執(zhí)行各種功能。
盡管用myisamchk修復(fù)表很安全,在修復(fù)(或任何可以大量更改表的維護(hù)操作)之前先進(jìn)行備份也是很好的習(xí)慣
影響索引的myisamchk操作會(huì)使ULLTEXT索引用full-text參數(shù)重建,不再與MySQL服務(wù)器使用的值兼容。要想避免,請(qǐng)閱讀5.9.5.1節(jié),“用于myisamchk的一般選項(xiàng)”的說(shuō)明。
在許多情況下,你會(huì)發(fā)現(xiàn)使用SQL語(yǔ)句實(shí)現(xiàn)MyISAM表的維護(hù)比執(zhí)行myisamchk操作要容易地多:
· 要想檢查或維護(hù)MyISAM表,使用CHECK TABLE或REPAIR TABLE。
· 要想優(yōu)化MyISAM表,使用OPTIMIZE TABLE。
· 要想分析MyISAM表,使用ANALYZE TABLE。
可以直接這些語(yǔ)句,或使用mysqlcheck客戶(hù)端程序,可以提供命令行接口。
這些語(yǔ)句比myisamchk有利的地方是服務(wù)器可以做任何工作。使用myisamchk,你必須確保服務(wù)器在同一時(shí)間不使用表。否則,myisamchk和服務(wù)器之間會(huì)出現(xiàn)不期望的相互干涉。
5.9.5. myisamchk:MyISAM表維護(hù)實(shí)用工具
5.9.5.1. 用于myisamchk的一般選項(xiàng)
5.9.5.2. 用于myisamchk的檢查選項(xiàng)
5.9.5.3. myisamchk的修復(fù)選項(xiàng)
5.9.5.4. 用于myisamchk的其它選項(xiàng)
5.9.5.5. myisamchk內(nèi)存使用
5.9.5.6. 將myisamchk用于崩潰恢復(fù)
5.9.5.7. 如何檢查MyISAM表的錯(cuò)誤
5.9.5.8. 如何修復(fù)表
5.9.5.9. 表優(yōu)化
可以使用myisamchk實(shí)用程序來(lái)獲得有關(guān)數(shù)據(jù)庫(kù)表的信息或檢查、修復(fù)、優(yōu)化他們。myisamchk適用MyISAM表(對(duì)應(yīng).MYI和.MYD文件的表)。
調(diào)用myisamchk的方法:
shell myisamchk [options] tbl_name ...
options指定你想讓myisamchk做什么。在后面描述它們。還可以通過(guò)調(diào)用myisamchk --help得到選項(xiàng)列表。
tbl_name是你想要檢查或修復(fù)的數(shù)據(jù)庫(kù)表。如果你不在數(shù)據(jù)庫(kù)目錄的某處運(yùn)行myisamchk,你必須指定數(shù)據(jù)庫(kù)目錄的路徑,因?yàn)閙yisamchk不知道你的數(shù)據(jù)庫(kù)位于哪兒。實(shí)際上,myisamchk不在乎你正在操作的文件是否位于一個(gè)數(shù)據(jù)庫(kù)目錄;你可以將對(duì)應(yīng)于數(shù)據(jù)庫(kù)表的文件拷貝到別處并且在那里執(zhí)行恢復(fù)操作。
如果你愿意,可以用myisamchk命令行命名幾個(gè)表。還可以通過(guò)命名索引文件(用“ .MYI”后綴)來(lái)指定一個(gè)表。它允許你通過(guò)使用模式“*.MYI”指定在一個(gè)目錄所有的表。例如,如果你在數(shù)據(jù)庫(kù)目錄,可以這樣在目錄下檢查所有的MyISAM表:
shell myisamchk *.MYI
如果你不在數(shù)據(jù)庫(kù)目錄下,可通過(guò)指定到目錄的路徑檢查所有在那里的表:
shell myisamchk /path/to/database_dir/*.MYI
你甚至可以通過(guò)為MySQL數(shù)據(jù)目錄的路徑指定一個(gè)通配符來(lái)檢查所有的數(shù)據(jù)庫(kù)中的所有表:
shell myisamchk /path/to/datadir/*/*.MYI
推薦的快速檢查所有MyISAM表的方式是:
shell myisamchk --silent --fast /path/to/datadir/*/*.MYI
如果你想要檢查所有MyISAM表并修復(fù)任何破壞的表,可以使用下面的命令:
shell myisamchk --silent --force --fast --update-state \
-O key_buffer=64M -O sort_buffer=64M \
-O read_buffer=1M -O write_buffer=1M \
/path/to/datadir/*/*.MYI
該命令假定你有大于64MB的自由內(nèi)存。關(guān)于用myisamchk分配內(nèi)存的詳細(xì)信息,參見(jiàn)5.9.5.5節(jié),“myisamchk內(nèi)存使用”。
當(dāng)你運(yùn)行myisamchk時(shí),必須確保其它程序不使用表。否則,當(dāng)你運(yùn)行myisamchk時(shí),會(huì)顯示下面的錯(cuò)誤消息:
warning: clients are using or haven't closed the table properly
這說(shuō)明你正嘗試檢查正被另一個(gè)還沒(méi)有關(guān)閉文件或已經(jīng)終止而沒(méi)有正確地關(guān)閉文件的程序(例如mysqld服務(wù)器)更新的表。
如果mysqld正在運(yùn)行,你必須通過(guò)FLUSH TABLES強(qiáng)制清空仍然在內(nèi)存中的任何表修改。當(dāng)你運(yùn)行myisamchk時(shí),必須確保其它程序不使用表。避免該問(wèn)題的最容易的方法是使用CHECK TABLE而不用myisamchk來(lái)檢查表。
5.9.5.1. 用于myisamchk的一般選項(xiàng)
本節(jié)描述的選項(xiàng)可以用于用myisamchk執(zhí)行的任何類(lèi)型的表維護(hù)操作。本節(jié)后面的章節(jié)中描述的選項(xiàng)只適合具體操作,例如檢查或修復(fù)表。
· --help,-?
顯示幫助消息并退出。
· --debug=debug_options, -# debug_options
輸出調(diào)試記錄文件。debug_options字符串經(jīng)常是'd:t:o,filename'。
· --silent,-s
沉默模式。僅當(dāng)發(fā)生錯(cuò)誤時(shí)寫(xiě)輸出。你能使用-s兩次(-ss)使myisamchk沉默。
· --verbose,-v
冗長(zhǎng)模式。打印更多的信息。這能與-d和-e一起使用。為了更冗長(zhǎng),使用-v多次(-vv, -vvv)!
· --version, -V
顯示版本信息并退出。
· --wait, -w
如果表被鎖定,不是提示錯(cuò)誤終止,而是在繼續(xù)前等待到表被解鎖。請(qǐng)注意如果用--skip-external-locking選項(xiàng)運(yùn)行mysqld,只能用另一個(gè)myisamchk命令鎖定表。
還可以通過(guò)--var_name=value選項(xiàng)設(shè)置下面的變量:
變量
默認(rèn)值
decode_bits
9
ft_max_word_len
取決于版本
ft_min_word_len
4
ft_stopword_file
內(nèi)建列表
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
可以用myisamchk --help檢查myisamchk變量及其 默認(rèn)值:
當(dāng)用排序鍵值修復(fù)鍵值時(shí)使用sort_buffer_size,使用--recover時(shí)這是很普通的情況。
當(dāng)用--extend-check檢查表或通過(guò)一行一行地將鍵值插入表中(如同普通插入)來(lái)修改鍵值時(shí)使用Key_buffer_size。在以下情況通過(guò)鍵值緩沖區(qū)進(jìn)行修復(fù):
· 使用--safe-recover。
· 當(dāng)直接創(chuàng)建鍵值文件時(shí),需要對(duì)鍵值排序的臨時(shí)文件有兩倍大。通常是當(dāng)CHAR、VARCHAR、或TEXT列的鍵值較大的情況,因?yàn)榕判虿僮髟谔幚磉^(guò)程中需要保存全部鍵值。如果你有大量臨時(shí)空間,可以通過(guò)排序強(qiáng)制使用myisamchk來(lái)修復(fù),可以使用--sort-recover選項(xiàng)。
通過(guò)鍵值緩沖區(qū)的修復(fù)占用的硬盤(pán)空間比使用排序么少,但是要慢。
如果想要快速修復(fù),將key_buffer_size和sort_buffer_size變量設(shè)置到大約可用內(nèi)存的25%??梢詫蓚€(gè)變量設(shè)置為較大的值,因?yàn)橐粋€(gè)時(shí)間只使用一個(gè)變量。
myisam_block_size是用于索引塊的內(nèi)存大小。
stats_method影響當(dāng)給定--analyze選項(xiàng)時(shí),如何為索引統(tǒng)計(jì)搜集處理NULL值。它如同myisam_stats_method系統(tǒng)變量。詳細(xì)信息參見(jiàn)5.3.3節(jié),“服務(wù)器系統(tǒng)變量”和7.4.7節(jié),“MyISAM索引統(tǒng)計(jì)集合”的myisam_stats_method的描述。
ft_min_word_len和ft_max_word_len表示FULLTEXT索引的最小和最大字長(zhǎng)。ft_stopword_file為停止字文件的文件名。需要在以下環(huán)境中對(duì)其進(jìn)行設(shè)置。
如果你使用myisamchk來(lái)修改表索引(例如修復(fù)或分析),使用最小和最大字長(zhǎng)和停止字文件的 默認(rèn)全文參數(shù)值(除非你另外指定)重建FULLTEXT索引。這樣會(huì)導(dǎo)致查詢(xún)失敗。
出現(xiàn)這些問(wèn)題是因?yàn)橹挥蟹?wù)器知道這些參數(shù)。它們沒(méi)有保存在MyISAM索引文件中。如果你修改了服務(wù)器中的最小或最大字長(zhǎng)或停止字文件,要避免該問(wèn)題,為用于mysqld的myisamchk指定相同的ft_min_word_len,ft_max_word_len和ft_stopword_file值。例如,如果你將最小字長(zhǎng)設(shè)置為3,可以這樣使用myisamchk來(lái)修復(fù)表:
shell myisamchk --recover --ft_min_word_len=3 tbl_name.MYI
要想確保myisamchk和服務(wù)器使用相同的全文
有兩種方法,一種方法使用mysql的check table和repair table 的sql語(yǔ)句,另一種方法是使用MySQL提供的多個(gè)myisamchk, isamchk數(shù)據(jù)檢測(cè)恢復(fù)工具。
前者使用起來(lái)比較簡(jiǎn)便。推薦使用。
1、check table 和 repair table 登陸mysql 終端: mysql -uxxxxx -p dbname check table tabTest;
如果出現(xiàn)的結(jié)果說(shuō)Status是OK,則不用修復(fù),如果有Error,可以用: repair table tabTest; 進(jìn)行修復(fù),修復(fù)之后可以在用check table命令來(lái)進(jìn)行檢查。
在新版本的phpMyAdmin里面也可以使用check/repair的功能。
2. myisamchk, isamchk 其中myisamchk適用于MYISAM類(lèi)型的數(shù)據(jù)表,而isamchk適用于ISAM類(lèi)型的數(shù)據(jù)表。
這兩條命令的主要參數(shù)相同,一般新的系統(tǒng)都使用MYISAM作為缺省的數(shù)據(jù)表類(lèi)型,這里以myisamchk為例子進(jìn)行說(shuō)明。
當(dāng)發(fā)現(xiàn)某個(gè)數(shù)據(jù)表出現(xiàn)問(wèn)題時(shí)可以使用: myisamchk tablename.MYI 進(jìn)行檢測(cè),如果需要修復(fù)的話(huà),可以使用: myisamchk -of tablename.MYI 關(guān)于myisamchk的詳細(xì)參數(shù)說(shuō)明,可以參見(jiàn)它的使用幫助。
需要注意的時(shí)在進(jìn)行修改時(shí)必須確保MySQL服務(wù)器沒(méi)有訪問(wèn)這個(gè)數(shù)據(jù)表,保險(xiǎn)的情況下是最好在進(jìn)行檢測(cè)時(shí)把MySQL服務(wù)器Shutdown掉。
2、另外可以把下面的命令放在你的rc.local里面啟動(dòng)MySQL服務(wù)器前: [ -x /tmp/mysql.sock ] /pathtochk/myisamchk -of /DATA_DIR/*/*.MYI 。
其中的/tmp/mysql.sock是MySQL監(jiān)聽(tīng)的Sock文件位置,對(duì)于使用RPM安裝的用戶(hù)應(yīng)該是/var/lib/mysql/mysql.sock,對(duì)于使用源碼安裝則是/tmp/mysql.sock可以根據(jù)自己的實(shí)際情況進(jìn)行變更,而pathtochk則是myisamchk所在的位置,DATA_DIR是你的MySQL數(shù)據(jù)庫(kù)存放的位置。
需要注意的是,如果你打算把這條命令放在你的rc.local里面,必須確認(rèn)在執(zhí)行這條指令時(shí)MySQL服務(wù)器必須沒(méi)有啟動(dòng)!
最后檢測(cè)修復(fù)所有數(shù)據(jù)庫(kù)(表)。
一、背景
近期,公司RDS云產(chǎn)品的MySQL Server版本進(jìn)行升級(jí),由目前使用的5.7.26版本升級(jí)到最新版本5.7.31;升級(jí)后測(cè)試同學(xué)發(fā)現(xiàn):在MySQL創(chuàng)建用戶(hù)后,5.7.31版本重新啟動(dòng)集群會(huì)出現(xiàn)啟動(dòng)失敗的現(xiàn)象;而5.7.26版本在相同測(cè)試場(chǎng)景下是正常啟動(dòng)的。這到底是為什么呢?
二、問(wèn)題復(fù)現(xiàn)
2.1 實(shí)驗(yàn)環(huán)境
2.2 操作步驟
按照測(cè)試同學(xué)的測(cè)試步驟,首先創(chuàng)建一個(gè)用戶(hù):
然后關(guān)閉mysqld;這里需要介紹一下,我們集群的關(guān)閉方式是如下方式:
這種方式的內(nèi)部實(shí)現(xiàn)類(lèi)似于kill -9模式。所以我在線(xiàn)下環(huán)境使用kill -9的方式來(lái)復(fù)現(xiàn),操作如下:
然后重啟mysqld,操作如下:
此時(shí)問(wèn)題復(fù)現(xiàn)了,mysqld啟動(dòng)失敗,我們查看了下error日志,信息如下:
根據(jù)報(bào)錯(cuò)信息可以看出:MySQL的權(quán)限系統(tǒng)表發(fā)生了損壞,導(dǎo)致了mysqld啟動(dòng)失??;由于在MySQL 5.7及其之前版本該表是MyISAM引擎,且該引擎不支持事務(wù),所以在mysqld異常崩潰會(huì)導(dǎo)致該類(lèi)型引擎表的損壞;但在mysqld啟動(dòng)時(shí)是有參數(shù)控制MyISAM引擎的恢復(fù)模式,且該參數(shù)在我們產(chǎn)品中也配置到了my.cnf中,如下所示:
2.3 參數(shù)解析
對(duì)于該參數(shù)的官方文檔的解釋如下:
設(shè)置MyISAM存儲(chǔ)引擎恢復(fù)模式。選項(xiàng)值是OFF、DEFAULT、BACKUP、FORCE或QUICK的值的任意組合。如果指定多個(gè)值,請(qǐng)用逗號(hào)分隔。指定不帶參數(shù)的選項(xiàng)與指定DEFAULT相同,指定顯式值" "將禁用恢復(fù)(與OFF值相同)。如果啟用了恢復(fù),則mysqld每次打開(kāi)MyISAM表時(shí),都會(huì)檢查該表是否標(biāo)記為已崩潰或未正確關(guān)閉。(只有在禁用外部鎖定的情況下運(yùn)行,最后一個(gè)選項(xiàng)才起作用。)在這種情況下,mysqld在表上運(yùn)行檢查。如果表已損壞,mysqld將嘗試對(duì)其進(jìn)行修復(fù)。
服務(wù)器自動(dòng)修復(fù)表之前,它將有關(guān)修復(fù)的注釋寫(xiě)到錯(cuò)誤日志中。如果您希望能夠在無(wú)需用戶(hù)干預(yù)的情況下從大多數(shù)問(wèn)題中恢復(fù),則應(yīng)使用選項(xiàng)BACKUP,F(xiàn)ORCE。即使某些行將被刪除,這也會(huì)強(qiáng)制修復(fù)表,但是它將舊的數(shù)據(jù)文件保留為備份,以便您以后可以檢查發(fā)生了什么。
全局變量,只讀變量,默認(rèn)為OFF。
三、問(wèn)題修復(fù)
這類(lèi)MySQL用戶(hù)表?yè)p耗的問(wèn)題解決方式也是有多種,我這里列舉其中一種:
(1)my.cnf中的[mysqld]標(biāo)簽下添加skip_grant_tables,啟動(dòng)時(shí)跳過(guò)加載系統(tǒng)字典。
(2)重啟mysqld,然后修復(fù)mysql schema下的所有表。
(3)在[mysqld]標(biāo)簽下注釋或刪除掉skip_grant_tables,然后重啟mysqld。
此時(shí)mysqld是可以正常啟動(dòng)的,無(wú)異常。
四、深入排查
在產(chǎn)品化中,以上修復(fù)方式很不優(yōu)雅,只是作為臨時(shí)的解決方案;并且也存在一些令人疑惑的點(diǎn):
帶著這些疑問(wèn),我們繼續(xù)排查出現(xiàn)該現(xiàn)象的原因;此時(shí)Google也沒(méi)有找到一些有效的信息,那么只能通過(guò)MySQL源代碼來(lái)尋找一些答案。
首先需要下載mysql 5.7.31版本的源代碼,并搭建mysql debug環(huán)境;具體步驟可以自動(dòng)Google搜索一下,本文就不再贅述了。
在源代碼中搜索一下關(guān)鍵詞,用于打斷點(diǎn)的位置,然后進(jìn)行調(diào)試:
定位到相關(guān)代碼,大概是sql/mysqld.cc的4958行,且存在if條件判斷,此時(shí)我們開(kāi)始調(diào)試:
通過(guò)以上調(diào)試信息,可以判斷出acl_init函數(shù)返回的值為真;此時(shí)我們查看該函數(shù)的代碼 (sql/auth/sql_auth_cache.cc:1365):
根據(jù)該函數(shù)的注釋發(fā)現(xiàn):該函數(shù)是初始化負(fù)責(zé)用戶(hù)/數(shù)據(jù)庫(kù)級(jí)特權(quán)檢查的結(jié)構(gòu),并從mysql schema中的表中為其加載特權(quán)信息;且return值為1代表的是初始化權(quán)限失敗。
此后開(kāi)始逐步調(diào)試,觀察return相關(guān)信息,當(dāng)調(diào)試到lock_table_names函數(shù)時(shí),我們發(fā)現(xiàn)在Phase 3時(shí)return值為true,且根據(jù)代碼注釋發(fā)現(xiàn)true代表是Failure;具體代碼如下(sql/sql_base.cc:5549):
調(diào)試信息如下:
可以看到flags的值為0,而MYSQL_OPEN_SKIP_SCOPED_MDL_LOCK為宏定義值0x1000,與flags的值 做按位與操作,結(jié)果自然也是0,當(dāng)然MYSQL_LOCK_IGNORE_GLOBAL_READ_ONLY也是如此;need_global_read_lock_protection是bool類(lèi)型值,代表是否需要全局讀鎖的保護(hù),這個(gè)值是在table- mdl_request.type不為MDL_SHARED_READ_ONLY發(fā)生改變;check_readonly函數(shù)相關(guān)信息 下面概述。
此時(shí)也查看了下MySQL 5.7.26版本代碼作為對(duì)比,發(fā)現(xiàn)lock_table_names函數(shù)下的Phase 3后的部分代 碼是在5.7.29版本后新增的。如果是git clone的MySQL代碼可以用git blame命令查詢(xún)文件變化的信息:
上述展示的信息中,最左側(cè)的列值為commit id為05824063和0405ebee,有興趣的同學(xué)可以詳細(xì)看下。
此功能解決的問(wèn)題是 BUG#28438114: SET READ_ONLY=1 SOMETIMES DOESN'T BLOCK CONCURRENT DDL.;當(dāng)然這個(gè)代碼的變更功能也在5.7 Release Notes中有所體現(xiàn),如下所示( m/doc/relnotes/mysql/5.7/en/news-5-7-29.html ):
最后我們?cè)俨榭聪耤heck_readonly函數(shù),該函數(shù)是基于read_only和super_read_only狀態(tài)執(zhí)行標(biāo)準(zhǔn)化檢查,是禁止(TRUE)還是允許(FALSE)操作。代碼如下(sql/auth/sql_authorization.cc:489):
此時(shí)第一反應(yīng)就是去檢查my.cnf中是否包含read_only相關(guān)參數(shù),檢查之后發(fā)現(xiàn)確實(shí)是使用了該參數(shù), 如下:
此時(shí)注釋掉該參數(shù),然后再次啟動(dòng)mysqld,發(fā)現(xiàn)MyISAM表可以自動(dòng)修復(fù),且正常啟動(dòng);error log信息如下:
由于docker一些限制,我們?cè)趍ysqld啟動(dòng)會(huì)涉及兩次;所以解決該問(wèn)題的方式為:第一次mysqld的啟動(dòng)時(shí)先關(guān)閉read_only參數(shù),第二次啟動(dòng)時(shí)開(kāi)啟read_only參數(shù)。之所以選擇默認(rèn)開(kāi)啟read_only參數(shù), 是為了避免在mysqld啟動(dòng)后,選主邏輯未完成時(shí)的保護(hù)措施;當(dāng)然選主完成后,會(huì)自動(dòng)對(duì)master執(zhí)行 set global read_only=0 操作。
五、總結(jié)
六、附錄
調(diào)試的棧幀信息如下,有興趣的小伙伴可以研究下:
熟悉MySQL體系結(jié)構(gòu)和innodb存儲(chǔ)引擎工作原理;以及MySQL備份恢復(fù)、復(fù)制、數(shù)據(jù)遷移等技術(shù);專(zhuān)注于MySQL、MariaDB開(kāi)源數(shù)據(jù)庫(kù),喜好開(kāi)源技術(shù)。
原文鏈接:
分享文章:mysql中表?yè)p壞怎么辦 mysql表?yè)p壞的常見(jiàn)病因
當(dāng)前URL:http://jinyejixie.com/article6/hpdsig.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供App設(shè)計(jì)、微信公眾號(hào)、域名注冊(cè)、網(wǎng)站內(nèi)鏈、企業(yè)建站、搜索引擎優(yōu)化
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶(hù)投稿、用戶(hù)轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話(huà):028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)
營(yíng)銷(xiāo)型網(wǎng)站建設(shè)知識(shí)