【小白福利—初級DBA入門必看】MySQL常用工具介紹(五)——客戶端工具MySQL_check

1 . 簡介

mysqlcheck用來維護表:check檢查、repair修復、optimize優化、analyze分析。
除檢查表是read鎖定外,其它都是write鎖定。
表維護操作可能耗時較多,尤其是–databases和–all-databases選項要維護大量表時。
當mysql升級程序決定要check表,相當於調用mysqlcheck。
最好在執行表修復操作前備份表,因爲某些情況下(如文件系統錯誤),該操作可能導致數據丟失。
mysqlcheck實際上是根據選項參數確定CHECK TABLE, REPAIR TABLE, ANALYZE TABLE, OPTIMIZE TABLE四種語句,並將其發送到服務器執行。這四種語句不一定支持所有儲存引擎,這種情況下會顯示錯誤信息。
調用方式:
shell> mysqlcheck [options] [–tables] db_name [tbl_name …]
shell> mysqlcheck [options] --databases db_name …
shell> mysqlcheck [options] --all-databases
選項可以從[mysqlcheck]和[client]中讀取。
mysqlcheck相對於其他客戶端程序有些特殊。他還可以通過改名、建立軟連接等方式,修改默認的–check行爲爲其他行爲,程序名稱與行爲對應如下:
在這裏插入圖片描述

2 . 選項介紹與部分選項舉例說明

#注意:這裏的默認值,不是使用“程序名 --no-defaults --help”打印的輸出,而是指未指定時內部初始值,該值可被自身選項顯示指定,也可能會受其他互斥選項、相關選項更改。這裏只寫出默認啓用的布爾型選項,以及有內部值的其他選項。有內部值的選項可以不顯示給出。
2.1 所有客戶端共有選項
mysqlcheck作爲MySQL提供的客戶端的之一,具有以下五種通用選項。
2.1.1 影響選項文件讀取的選項
在這裏插入圖片描述
2.1.2 幫助與版本
在這裏插入圖片描述
2.1.3 連接的建立
在這裏插入圖片描述
在這裏插入圖片描述
連接方式參數說明:優先級–protocol>–pipe>-h;
linux兩種連接方式:若未指定–host和-h,或指定爲localhost,或指定爲空(–host=或–host=’’),則使用unix套接字;否則使用tcp/ip。
windows三種連接方式:若未指定–host和-h,或指定爲localhost,且服務端開啓了共享內存,則使用共享內存;若指定爲.,或tcp禁用且socket未指定或主機指定爲空(–host=),則使用命名管道;否則tcp。
連接方式舉例
全平臺使用tcp/ip:
mysql --protocol=tcp [-h127.0.0.1] [–port=3306]
mysql -h127.0.0.1 [–port=3306]

unix使用socket:
mysql [–host=localhost] [–socket=/tmp/mysql.sock]

windows使用命名管道:需在服務端開啓命名管道支持
mysql --protocol=pipe
mysql --pipe
mysql --host=.

windows使用共享內存:未知,存在問題。理論上應當在服務上開啓共享內存後使用
mysql [–host=localhost] --shared-memory-base-name=MYSQL,但是實際上使用的tcp,或者
mysql --protocol=memory --shared-memory-base-name=MYSQL,但是會報錯ERROR 2046 (HY000): Can’t open shared memory; cannot send request event to server (5);

2.1.4 字符集

在這裏插入圖片描述
2.1.5 調試日誌
在這裏插入圖片描述

2.2 mysqlcheck特定選項
在這裏插入圖片描述

3 常見用法舉例

分析所有的數據庫的數據表:mysqlcheck -A -a
優化sakila,clientoptions數據庫:mysqlcheck --optimize -B sakila clientoptions
檢查mysql.user表:mysqlcheck --check mysql user

4 附錄:表維護語句介紹

4.1 ANALYZE TABLE Syntax
ANALYZE [NO_WRITE_TO_BINLOG | LOCAL]
TABLE tbl_name [, tbl_name] …
語句需要SELECT和insert權限。
analyze table執行索引分佈分析,並存儲分佈。對MyISAM表,該語句等同於myisamchk --analyze。
analyze table工作於innodb、ndb、MyISAM表,不適用於視圖。
支持分區表,可以使用ALTER TABLE … ANALYZE PARTITION來分析一個或多個分區。
對innodb、MyISAM表,分析期間將以讀鎖鎖定表。
4.1.1 analyze table的輸出
輸出爲一個表,一個表可能有多行輸出,該表最後一行是(表名,check,status,信息)。
在這裏插入圖片描述
4.1.2 索引分佈分析
若自上次分析後表沒有變更,不會再次分析表。
MySQL使用存儲的索引分佈來一定程度上決定表的join順序,而不是一個常量。此外,索引分佈還可以用來決定一個查詢中的某個表當使用哪個索引。
關於索引分佈如何工作的更多信息可參考 Section 14.8.11.1, “Configuring Persistent Optimizer Statistics Parameters” and Section 14.8.11.3, “Estimating ANALYZE TABLE Complexity for InnoDB Tables”. Also see Section 14.6.1.6, “Limits on InnoDB Tables”.
特別是,若innodb_stats_persistent=ON,在innodb表載入了大量的數據,或者爲其創建了一個新索引後,必須運行analyze table。
要檢查存儲的索引分佈基數,使用show index語句或者information_schema.statistics表。 See Section 13.7.5.22, “SHOW INDEX Syntax”, and Section 24.24, “The INFORMATION_SCHEMA STATISTICS Table”.

4.1.3 其他注意信息
analyze table清空來自information_schema.innodb_tablestats的表統計信息,並設置STATS_INITIALIZED列的值爲Uninitialized。下次訪問表時將再次收集統計信息。

4.2 CHECK TABLE Syntax
CHECK TABLE tbl_name [, tbl_name] … [option] … #表名不能重複

option: {
FOR UPGRADE #檢查表是否與當前MySQL版本兼容
| QUICK
| FAST
| MEDIUM
| EXTENDED
| CHANGED
}
檢查表是否有錯、視圖是否存在。適用於InnoDB、MyISQM、ARCHIVE、CSV四種表,對於MyISQM,索引統計信息也會更新。
支持分區表,ALTER TABLE … CHECK PARTITION也可以檢查一個或多個分區。
忽略無索引的虛擬生成列。

4.2.1 check table輸出:
輸出爲一個表,一個表可能有多行輸出,該表最後一行是(表名,check,status,信息),信息應當爲OK。對於MyISAM,如果信息不爲OK或Table is already up to date(表示無需檢查),一般情況下當運行修復。
在這裏插入圖片描述
在這裏插入圖片描述
4.2.2 檢查版本兼容性
FOR UPGRADE選項檢查表是否與當前MySQL版本兼容,因爲數據類型存儲格式、排序順序可能導致數據類型或索引不兼容。
如果兼容,檢查成功;否則 ,會進行全面檢查。全面檢查成功,.frm將被標記爲當前MySQL版本,以確保使用相同版本的服務器進一步檢查表格的速度更快。
可以發現如下不兼容:
4.1和5.1之間,InnoDB和MyISAM表中,TEXT列中end-space的索引順序有變化。
5.0.3和5.0.5之間,新DECIMAL類型的存儲方法有變化。
若表由非當前版本服務器創建,for upgrade會指出.frm版本號不兼容,顯示(表名,check,error,Table upgrade required)。請"REPAIR TABLE tbl_name"以修復表。
Changes are sometimes made to character sets or collations that require table indexes to be rebuilt. For details about such changes, see Section 2.11.3, “Changes in MySQL 5.7”. For information about rebuilding tables, seeSection 2.11.12, “Rebuilding or Repairing Tables or Indexes”.
YEAR(2)類型不提倡,5.7.5中被移除。對於含該類型的表,CHECK TABLE recommends REPAIR TABLE, 以將其轉爲YEAR(4).
5.7.2始,維護觸發器的創建時間。若表有觸發器,CHECK TABLE … FOR UPGRADE爲每個5.7.2前創建的觸發器顯示如下警告,供參考而觸發器無任何變化:Trigger db_name.tbl_name.trigger_name does not have CREATED attribute.
5.7.7始,若avoid_temporal_upgrade=ON(默認),含5.6.4前的舊時間格式(time、datetime、timestamp不支持小數秒精度)的表將被報告爲需要重建;若avoid_temporal_upgrade=OFF,則忽略該項兼容性。
for upgrade對使用非本地分區的表發出警告。因爲非本地分區,5.7不推薦,8.0被刪除。

檢查數據一致性:除for upgrade外的其他選項,選項傳遞給引擎,引擎可能使用或忽略某些選項。

在這裏插入圖片描述
檢查類型可以組合,如下面例子使用快速檢查以決定表是否正常關閉。CHECK TABLE test_table FAST QUICK;
若check table沒有發現標記爲‘corrupted’或‘not closed properly’表有問題,check table會將該標記移除。
若表損壞,很可能在索引部分而不是數據部分。所有檢查類型都對索引進行徹底檢查,故應可找到大多數錯誤。
要檢查預計沒問題的表,不使用檢查選項或使用quick選項。趕時間時當使用quick,但要承擔quick沒有在數據文件中發現錯誤的小風險。(多數情況,正常情況,MySQL當發現數據文件中的任何錯誤。這種情況下,表將被標記爲‘corrupted’,並且在修復前無法使用)
fast和changed主要用於腳本中定期檢查表(如cron)。多數情況,fast先於changed考慮。(唯一例外是當你懷疑你發現MyISAM代碼中的bug時)。
當普通檢查過的表依舊在更新行或通過索引查找行發生錯誤時(若普通檢查成功,這是不太可能),才需考慮extended。
使用CHECK TABLE … EXTENDED可能會影響查詢優化器產生的執行計劃。
一些check table報告的問題可以被自動修正:
Found row where the auto_increment column has the value 0.
這意味着表的auto_increment索引行包含0。這本身不是錯誤,但可能使導出並導入表、alter table時出現問題。在這種情況下,自增列依據自增列的規則改變值,這可能導致重複鍵錯誤等問題。
爲避免這個警告,使用update將0值該成其他值。
4.2.4 check table使用說明:InnoDB
若check table遇到損壞頁,服務器退出以阻值錯誤傳播(bug #10132)。如果是二級索引損壞,但數據可讀,check table依舊導致服務器退出。
若check table遇到聚簇索引中損壞的DB_TRX_ID或 DB_ROLL_PTR字段,check table會導致InnoDB訪問非法的undo日誌記錄,導致mvcc相關服務退出。
若check table遇到表或索引中的錯誤,它報告錯誤,標記索引並有時標記表爲已損壞,組織索引或表的進一步使用。這樣的錯誤包括二級索引的錯誤入口數或錯誤鏈接。
若check table找到二級索引的錯誤入口數,它報告錯誤,但不會導致服務退出或阻止訪問錯誤文件。
check table調查索引頁結構,然後調查每個索引入口。它不驗證指向聚簇記錄的索引指針,不追蹤blob指針。
當innodb表保存在自己的.ibd文件,則文件的前3頁包含頭信息而不是表或索引數據。check table不探查隻影響頭數據的非一致。要驗證整個.ibd的內容,請使用innochecksum命令。
當在大表上運行check table,在執行期間其它線程可能被阻塞。爲避免超時,check table操作將信號量等待閾值(600s)延長至(7200s)。若innodb探測到大於等於240s的信號量等待,innodb開始打印innodb監視器輸出到錯誤日誌。若鎖請求超過信號量等待閾值,innodb中止該過程。爲完全避免信號量等待超時的可能性,執行check table quick而不是check table。
check table對空間索引的功能包括R-tree有效性檢查,以及一個保證R-tree行計數匹配聚簇索引的檢查。
check table支持虛擬生成列上的二級索引。
4.2.5 check table使用說明:MyISAM
check table更新索引統計信息
對於MyISAM,如果check table輸出信息不爲OK或Table is already up to date(表示無需檢查),一般情況下當運行修復。參考Section 7.6, “MyISAM Table Maintenance and Crash Recovery”.
若沒有指定QUICK、MEDIUM、EXTENDED中任一個,即沒有給出檢查方法時:
對於動態格式的MyISAM表,默認的檢查類型爲MEDIUM。效果等同於 myisamchk --medium-check tbl_name。
對於靜態格式的MyISAM表,若也沒有指定CHANGED 、FAST任一個,默認檢查類型同樣爲MEDIUM;否則默認檢查類型爲QUICK。對changed、fast不進行行掃描是因爲行很少損壞。

4.3 CHECKSUM TABLE Syntax
CHECKSUM TABLE tbl_name [, tbl_name] … [QUICK | EXTENDED]
checksum table報告表內容的校驗和。可以使用該語句驗證備份、回滾或其它旨在將數據恢復到已知狀態的操作前後內容相同。
需要SELECT權限。
不支持視圖,對視圖運行,checksum的值始終爲null,並返回警告。
對不存在的表,返回null,並警告。
在校驗和操作期間,以讀鎖鎖定MyISAM和innodb表。
4.3.1 性能注意事項
默認情況下,逐行讀取整個表並計算校驗和。對於大表,可能需要教程時間,故此一般只偶爾執行此操作。這種逐行計算方式,可以通過EXTENDED選項獲得,可以通過沒有以CHECKSUM=1 創建的MyISAM表獲得,也可以通過其他引擎獲得。
對於以CHECKSUM=1 創建的MyISAM表, CHECKSUM TABLE或 CHECKSUM TABLE … QUICK返回‘live’校驗和(即可以快速返回)。如果表不滿足所有這些條件,則QUICK方法返回NULL。QUICK方法不支持innodb表。有關CHECKSUM子句的語法可參考 Section 13.1.18, “CREATE TABLE Syntax”。
checksum和行格式有關。若行格式變化,checksum也變化。若舊時間存儲格式升級爲新格式,如5.5轉換爲5.6,校驗值可能改變。

重要:若校驗和不同,則幾乎可以肯定這些表在某種程度上是不同的。但是由於使用的列散函數不能保證無衝突,故兩個不同的表也可能產生相同的校驗和。

4.4 OPTIMIZE TABLE Syntax
OPTIMIZE [NO_WRITE_TO_BINLOG | LOCAL] #該可選項啓用時可以使語句不記錄到binlog。
TABLE tbl_name [, tbl_name] …
語句需要表的SELECT和insert權限。
optimize table重組數據和相關索引的物理存儲,以節約存儲空間,提高訪問表時的i/o性能。對錶確切的變更取決於表的存儲引擎。
根據表類型,在這些情況下使用optimize table語句::
::在對有獨立表空間的innodb表進行了大量的增、刪、改操作後。表和索引將被重組,並且回收磁盤空間以供操作系統使用。
::在對innodb表的fulltext索引的一部分的列進行了大量的增、刪、改操作後。先設置innodb_optimize_fulltext_only=1。爲將索引維護保持在合理的時間範圍內,考慮設置 innodb_ft_num_word_optimize變量以指定在搜索索引中更新的單詞數,並執行一系列optimize table語句,直到索引完全更新爲止。
::在刪除了MyISAM或archive表的很大一部分後,或對含變長行的MyISAM或archive表做了很多更改後。刪除的行被鏈表維護,後續的insert操作可以重用舊行位置。可以使用optimize table回收未使用的空間並對數據文件進行碎片整理。在對錶進行大量更改後,此語句還可能會提高使用該表的語句的性能,有時甚至會顯著提高。
optimize table支持innodb、MyISAM、archive表。也支持內存ndb表的動態列,但不支持固定寬度的內存列,也不支持磁盤數據表。調節變量 --ndb-optimization-delay,以控制在行批次間的等待時長,從而提高optimize table的性能。For more information, see Previous NDB Cluster Issues Resolved in NDB Cluster 7.3 .對ndb集羣表,可以通過殺掉執行optimize的sql線程打斷optimize table。
不支持視圖。支持分區表,有關於分區表的優化語句請參考第22.3.4節“分區維護”。
默認情況下,optimize table不支持任何其他引擎,並返回一個結果指出缺乏支持。可以通過以–skip-new選項啓動mysqld來開啓optimize table對其他引擎的支持,這時,optimize table僅僅是映射爲alter table。

4.4.1 optimize table的輸出
輸出爲一個表,一個表可能有多行輸出,該表最後一行是(表名,check,status,信息),信息應當爲OK。
在這裏插入圖片描述
optimize table捕獲並拋出在將表統計信息從舊損壞表複製到新創表這個過程中的任何錯誤。例如,若.frm,.myd,.myi文件所有者的系統用戶id和mysqld進程的系統用戶id不同,optimize table將產生一個錯誤:“cannot change ownership of the file” (若mysqld用戶是root時不會錯誤)。

4.4.2 innodb詳情
對innodb,optimize table被映射爲alter table…force(該語句重建表以更新索引統計並釋放聚簇索引中未使用的空間)。
optimize table的輸出舉例:
在這裏插入圖片描述
optimize table將online DDL用於常規、分區innodb表,以減少併發dml操作的停機時間。被optimize table觸發、並被alter table…force執行的表的重建就地完成。僅在操作的準備階段和提交階段短暫地持有排他表鎖。在準備階段,更新元數據並創建中介表;在提交階段,提交表元數據的更改。
在以下條件下,optimize table使用表複製方法重建表::
::old_alter_table=1
::mysqld --skip-new
::含fulltext索引的innodb表。因爲optimize table不能將在線ddl用於此類表。
innodb使用page-allocation方法存儲數據,並且不會像傳統存儲引擎(如MyISAM)那樣遭受碎片。在考慮是否運行優化時,請考慮服務器將處理事務的工作負載::
::一定程度的碎片化是預料之中的。innodb只填充93%的頁面,留出空間,以便在不分頁的情況下更新。
::刪除操作可能留下間隙,使頁填充不如預期,這使optimize table有價值。
::當有足夠的空間時,行更新通常會重寫同頁中的數據,具體取決於數據類型和行格式。請參見 第14.9.1.5節“InnoDB表的壓縮支持”和 第14.11節“InnoDB行格式”。
::隨着時間推移,高併發的工作負載可能在索引中留下間隙,因爲innodb通過其mvcc機制保留了相同數據的多個版本。

4.4.3 MyISAM詳情
對MyISAM表,optimize table如下工作:
1.若表有已刪除行或拆分行,修復該表;
2.若索引頁未排序,將其排序;
3.若表統計信息不是最新的(並且不能通過對索引進行排序來完成修復),更新之。
4.4.4 其它注意事項
optimize table將online DDL用於常規、分區innodb表。否則,MySQL會在optimize table運行期間鎖表。
optimize table不對R-tree索引進行排序,如在POINT 列上的空間索引。(bug #23578)

4.5 REPAIR TABLE Syntax
REPAIR [NO_WRITE_TO_BINLOG | LOCAL]
TABLE tbl_name [, tbl_name] …
[QUICK] [EXTENDED] [USE_FRM]
repaire table修復可能已損壞的表,僅適用於某些引擎。
需要SELECT和insert權限。
通常用不上repair table,但災難發生後,這個語句很可能能將MyISAM表的數據找回。若表經常損壞,嘗試找到原因,以消除使用repair table的需要。See Section B.4.3.3, “What to Do If MySQL Keeps Crashing”, and Section 15.2.4, “MyISAM Table Problems”.
repair table檢查表看是否需要升級,若需要,則按照與 CHECK TABLE … FOR UPGRADE一樣的規則執行升級。
注意::
::表修復前備份;在某些情況,如文件系統錯誤,repair操作可能導致數據丟失。
::若服務器在repair table操作期間奔潰,在重啓後,在對該表執行任何其他操作前,立即執行repair table是非常重要的。在最壞的情況下,你可能的到一個新的乾淨的沒有關於數據文件信息的索引文件,然後下一個操作可能覆蓋數據文件。這種不太可能,但可能的情形,強調了先備份的價值。
::若主庫上的表損壞,在其上運行repair table,任何對該表的改變不會傳播到從庫。

4.5.1 支持的存儲引擎和分區
支持MyISAM,archive,csv表,不支持視圖。對MyISAM,默認效果等同myisamchk --recover tbl_name。
支持分區表,然而USE_FRM不能再分區表修復語句中使用。
也可以使用 ALTER TABLE … REPAIR PARTITION來修復一個或多個分區。Section 13.1.8, “ALTER TABLE Syntax”, and Section 22.3.4, “Maintenance of Partitions”.

4.5.2 選項
NO_WRITE_TO_BINLOG 或LOCAL:當省略該選項,語句默認記錄到binlog。啓用該選項,語句不記錄到binlog。
QUICK:嘗試僅修復索引文件,不修複數據文件。類似myisamchk --recover --quick.
EXTENDED:一行一行的創建索引,而不是使用排序一次性創建索引。類似myisamchk --safe-recover.
USE_FRM:若.myi索引文件丟失或其頭部損壞,可以使用該選項。該選項告訴MySQL忽略.myi文件頭信息,並使用.frm文件重建之。這種類型的修復不能使用myisamchk完成。
注意:
:僅在無法使用常規模式時才使用use_frm選項。告訴服務器忽略.myi索引文件導致存儲在.myi中的重要表元數據不可爲repair過程使用,這可能導致有害後果::
::::當前自增值丟失;
::::表中已刪除記錄的鏈接丟失,這意味着已刪除記錄的可用空間保持非佔用狀態;
::::.myi頭表明表是否壓縮。若忽略頭信息,無法獲知一個表是否壓縮,則repair可能導致表內容的變更或丟失。這意味着use_frm不應使用到壓縮表上。無論如何,這是不必要的:壓縮表是隻讀的,因此表不應損壞。
:若使用use_frm到非當前版本服務器建立的表,repair table不會嘗試修復該表。此時,輸出結果包含(表名,repair,error,Failed repairing incompatible .FRM file)。
:若使用use_frm,repair table不會檢查表是否需要升級。

4.5.3 repair table的輸出
輸出爲一個表,一個表可能有多行輸出,該表最後一行是(表名,check,status,信息),信息應當爲OK。
在這裏插入圖片描述
對於MyISAM,如果信息不爲OK,當嘗試使用myisamchk --safe-recover修復該表。repair table語句沒有實現Myisamchk的所有選項,在myisamchk --safe-recover中,還可以使用repair table不支持的選項,如 --max-record-length。
repair table捕獲並拋出在將表統計信息從舊損壞表複製到新創表這個過程中的任何錯誤。例如,若.frm,.myd,.myi文件所有者的系統用戶id和mysqld進程的系統用戶id不同,repair table將產生一個錯誤:“cannot change ownership of the file” (若mysqld用戶是root時不會錯誤)。

4.5.4 repair table的注意事項*
若avoid_temporal_upgrade=ON(默認),含5.6.4前的舊時間格式(time、datetime、timestamp不支持小數秒精度)的表將被repair table升級;若avoid_temporal_upgrade=OFF,則忽略舊時間列,並不會升級他們。
可以設定一些系統變量以增加repair table的性能。參見第8.6.3節“優化REPAIR TABLE語句”。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章