天天看點

[MySQL Reference Manual] 7 備份和恢複 7. 備份和恢複

本章主要會介紹:

1.備份的類型:邏輯備份,實體備份,全備和增量4種

2.建立備份的方法

3.還原方法,包括還原到時間點

4.備份計劃,壓縮和加密

5.表維護,恢複損壞的表

<a href="http://www.cnblogs.com/Amaranthus/p/3903430.html#_Toc395468188">7. 備份和恢複</a>

<a href="http://www.cnblogs.com/Amaranthus/p/3903430.html#_Toc395468189">7.1備份和還原類型</a>

<a href="http://www.cnblogs.com/Amaranthus/p/3903430.html#_Toc395468190">7.1.1 實體備份VS邏輯備份</a>

<a href="http://www.cnblogs.com/Amaranthus/p/3903430.html#_Toc395468191">7.1.2 Online VS OFFLINE</a>

<a href="http://www.cnblogs.com/Amaranthus/p/3903430.html#_Toc395468192">7.1.3 本地VS遠端</a>

<a href="http://www.cnblogs.com/Amaranthus/p/3903430.html#_Toc395468193">7.1.4 快照備份</a>

<a href="http://www.cnblogs.com/Amaranthus/p/3903430.html#_Toc395468194">7.1.5 全備VS增量備份</a>

<a href="http://www.cnblogs.com/Amaranthus/p/3903430.html#_Toc395468195">7.1.6 完全恢複VS時間點(增量)恢複</a>

<a href="http://www.cnblogs.com/Amaranthus/p/3903430.html#_Toc395468196">7.1.7 表維護</a>

<a href="http://www.cnblogs.com/Amaranthus/p/3903430.html#_Toc395468197">7.1.8 備份排程,壓縮,加密</a>

<a href="http://www.cnblogs.com/Amaranthus/p/3903430.html#_Toc395468198">7.2 資料庫備份方法</a>

<a href="http://www.cnblogs.com/Amaranthus/p/3903430.html#_Toc395468199">7.2.1 使用MySQL企業備份工具熱備</a>

<a href="http://www.cnblogs.com/Amaranthus/p/3903430.html#_Toc395468200">7.2.2 使用mysqldump和mysqlhotcopy備份</a>

<a href="http://www.cnblogs.com/Amaranthus/p/3903430.html#_Toc395468201">7.2.3 使用複制表檔案備份</a>

<a href="http://www.cnblogs.com/Amaranthus/p/3903430.html#_Toc395468202">7.2.4 文本檔案備份</a>

<a href="http://www.cnblogs.com/Amaranthus/p/3903430.html#_Toc395468203">7.2.5 使用binary log建立增量備份</a>

<a href="http://www.cnblogs.com/Amaranthus/p/3903430.html#_Toc395468204">7.2.6 使用slave備份</a>

<a href="http://www.cnblogs.com/Amaranthus/p/3903430.html#_Toc395468205">7.2.7 恢複錯誤表</a>

<a href="http://www.cnblogs.com/Amaranthus/p/3903430.html#_Toc395468206">7.2.8 使用檔案系統快照備份</a>

<a href="http://www.cnblogs.com/Amaranthus/p/3903430.html#_Toc395468207">7.3 備份還原政策例子</a>

<a href="http://www.cnblogs.com/Amaranthus/p/3903430.html#_Toc395468208">7.3.1 建立備份政策</a>

<a href="http://www.cnblogs.com/Amaranthus/p/3903430.html#_Toc395468209">7.3.2 使用備份還原</a>

<a href="http://www.cnblogs.com/Amaranthus/p/3903430.html#_Toc395468210">7.3.3 備份政策總結</a>

<a href="http://www.cnblogs.com/Amaranthus/p/3903430.html#_Toc395468211">7.4 使用mysqldump備份</a>

<a href="http://www.cnblogs.com/Amaranthus/p/3903430.html#_Toc395468212">7.4.1 使用SQL格式輸出</a>

<a href="http://www.cnblogs.com/Amaranthus/p/3903430.html#_Toc395468213">7.4.2 加載SQL格式輸出</a>

<a href="http://www.cnblogs.com/Amaranthus/p/3903430.html#_Toc395468214">7.4.3 使用文本格式的輸出</a>

<a href="http://www.cnblogs.com/Amaranthus/p/3903430.html#_Toc395468215">7.4.4 加載文本格式輸出</a>

<a href="http://www.cnblogs.com/Amaranthus/p/3903430.html#_Toc395468216">7.4.5 mysqldump提示</a>

<a href="http://www.cnblogs.com/Amaranthus/p/3903430.html#_Toc395468217">7.4.5.1 如何複制資料庫</a>

<a href="http://www.cnblogs.com/Amaranthus/p/3903430.html#_Toc395468218">7.4.5.2如何複制資料庫從A伺服器到B伺服器</a>

<a href="http://www.cnblogs.com/Amaranthus/p/3903430.html#_Toc395468219">7.4.5.3 dump存儲程式</a>

<a href="http://www.cnblogs.com/Amaranthus/p/3903430.html#_Toc395468220">7.4.5.4 分開dump資料庫結構和資料</a>

<a href="http://www.cnblogs.com/Amaranthus/p/3903430.html#_Toc395468221">7.4.5.5 使用mysqldump測試更新相容性問題</a>

<a href="http://www.cnblogs.com/Amaranthus/p/3903430.html#_Toc395468222">7.5 使用binary log時間點(增量)恢複</a>

<a href="http://www.cnblogs.com/Amaranthus/p/3903430.html#_Toc395468223">7.5.1 使用時間的時間來做時間點恢複</a>

<a href="http://www.cnblogs.com/Amaranthus/p/3903430.html#_Toc395468224">7.5.2 使用Event位置來做時間點恢複</a>

<a href="http://www.cnblogs.com/Amaranthus/p/3903430.html#_Toc395468225">7.6 MyISAM表的維護和Crash恢複</a>

<a href="http://www.cnblogs.com/Amaranthus/p/3903430.html#_Toc395468226">7.6.1 使用myisamchk災難恢複</a>

<a href="http://www.cnblogs.com/Amaranthus/p/3903430.html#_Toc395468227">7.6.2 如何檢查MyISAM表的錯誤</a>

<a href="http://www.cnblogs.com/Amaranthus/p/3903430.html#_Toc395468228">7.6.3 修複MyISAM表</a>

<a href="http://www.cnblogs.com/Amaranthus/p/3903430.html#_Toc395468229">7.6.4 MyISAM表優化</a>

<a href="http://www.cnblogs.com/Amaranthus/p/3903430.html#_Toc395468230">7.6.5 建立MyISAM表維護計劃</a>

實體備份是直接複制備份資料庫目錄或者檔案,這種備份比較适合大的比較重要的資料庫。

邏輯備份是把資料庫資訊儲存為資料庫結構(create database ,create table)和資料(insert語句或者text文本)。比較适合小的資料庫。

實體備份方法有幾個特點:

1.一系列的複制資料庫檔案和檔案夾,通常是備份全部或者部分資料文檔

2.實體備份一般比邏輯備份快,隻需要複制資料不需要轉化

3.輸出比邏輯備份少

4.對于繁忙,重要的資料庫備份的速度和窄資料比較重要

5.備份和還原粒度可以從資料文檔到個别資料檔案。

6.備份可以包含配置檔案和日志

7.對于MEMORY表不能用這種方式備份,因為資料不在磁盤中

8.備份隻能被移植到相同或者相識的硬體上(不明白)

9.backup隻能在服務停止是運作,若在運作是運作,那麼需要合适的鎖定,防止備份的時候資料被修改。mysql企業版備份在備份的時用到的表會自動加鎖。

10.實體備份工具mysqlbackup,檔案系統級别的指令(cp,scp,tar,rsync),或者mysqlhotcopy備份MyISAM。

對于還原:

1.mysql企業級備份工具可以還原它的備份

2.ndb_restore恢複ndb表

3.檔案系統級别複制或者mysqlhotcopy可以備份,可以複制到原來的檔案目錄來恢複

邏輯備份方法有幾個特點:

1.邏輯備份通過查詢獲得資料和資料庫結構。

2.邏輯備份比實體備份慢,因為需要通路資料然後轉化為邏輯結構

3.邏輯備份結果比實體備份結果要大。

4.邏輯備份還原的粒度,從執行個體級到标記。

5.邏輯備份不能包含,日志和配置檔案

6.備份是以邏輯格式存放,恢複很友善

7.備份需要服務啟動

8.主要的備份工具有sqldump和SELECT … INTO OUTFILE語句,MEMORY引擎照樣備份。

9.可以使用遠端的邏輯備份來還原。

線上備份是在服務啟動下備份,離線備份是在服務停止狀态下備份。也可以稱為熱備(hot back),冷備(cold back)。除此之外還有暖備(warm back),意思是服務在運作狀态下,但是備份在通路資料庫的時候不讓修改資料。

線上備份有幾個特點:

1.備份不會打擾其他用戶端,但是是否可以通路資料,和用戶端發過來的操作有關。

2.必須要加适當的鎖,不讓發生資料修改,以至于出現備份一緻性問題。

離線備份幾個特點:

1.用戶端在備份期間不可用。因為這個問題備份可以放到slave上面進行。

2.因為用戶端都不能通路,是以沒有一緻性問題,比較簡單。

上面2個備份的差別和還原的差別類似。但是線上的還原比線上備份對用戶端影響更大,在還原時,client通路資料庫。

本地備份是備份的結果放在MySQL所在的伺服器上,遠端是生産的備份放在其他伺服器上。

mysqldump:可以把生産在本地或者遠端

mysqlhotcopy:在本地執行,并在備份本地表檔案的時候不讓資料修改,備份生産在本地

SELECT… INTO OUTFILE可以從遠端或者本地連接配接,但是備份生産在本地

盡管複制檔案的目标是在遠端,但是都是在本地初始化

一些檔案系統可以支援快照,在一個時間點上,通關過了檔案系統的邏輯copy,不需要備份整個檔案系統。快照主要依賴于copy-on-write技術實作。LVM的快照可以檢視《鳥哥linux私房菜 基礎篇》 15.1。

全備是某個時間點的所有資料

增量備份是2個時間點内,資料的變更,MySQL中增量備份由binary log實作。

完全恢複是恢複全備中的所有資料。如果全備恢複不能滿足目前,可以使用全備之後的增量備份來還原

增量恢複是2個時間點内的資料修改,也被叫做時間點恢複,讓資料庫資料狀态更新到指定事件。增量備份一般在全備之後,使用binary log實作。

如果表出錯,那麼肯定會出現資料一緻性問題。對于INNODB表基本上不會發送。

備份排程是用來自動産生備份。

壓縮用來減少備份占用的空間。

加密保護資料安全性。

MySQL本身不包含這些能力,可以通過MySQL企業級備份工具,壓縮innodb備份。檔案系統可以壓縮,加密備份。

MySQL企業級備份工具,備份沖instance到table級别,可以增量,全備,壓縮備份。

innodb表可以直接熱備,對于其他引擎進行warm備份。

mysqldump的備份例子:

shell&gt; mysqldump db_name &gt; backup-file.sql

恢複資料庫:

shell&gt; mysql db_name &lt; backup-file.sql

shell&gt; mysql -e "source /path-to-backup/backup-file.sql" db_name

遷移資料庫:

shell&gt; mysqldump --opt db_name | mysql --host=remote_host -C db_name

備份多個資料庫:

shell&gt; mysqldump --databases db_name1 [db_name2 ...] &gt; my_databases.sql

mysqlhotcopy是一個perl腳本,使用FLUSH TABLES,LOCK TABLES和cp,scp備份資料庫。隻能備份myisam和ARCHIVE的表。

shell&gt; mysqlhotcopy db_name [/path/to/new_directory]

shell&gt; mysqlhotcopy db_name_1 ... db_name_n /path/to/new_directory

也可以用正規表達式,備份資料庫中的表:

shell&gt; mysqlhotcopy db_name./regex/

用~字首排除表名

shell&gt; mysqlhotcopy db_name./~regex/

對于每個表都有自己檔案的存儲過程可以使用複制表的檔案來做備份,為了擷取一緻性的備份,要停止服務或者flush表:

FLUSH TABLES tbl_list WITH READ LOCK;

當備份檔案的時候,隻需要在表上加READ LOCK,其他用戶端能夠照常讀取表,但是不能寫入。flush用處:在備份之前,把所有被修改的page都寫入到檔案中。

通過這個方法可以建立一個bianry備份,備份所有的表檔案。mysqlhotcopy就是使用這個方法,但是mysqlhotcopy不對innodb起作用,因為innodb的資料庫檔案夾沒有必要儲存表的所有資料,此外雖然服務沒有發起修改資料但是innodb還是可能會修改緩存在記憶體中的資料,并且不重新整理到磁盤。

建立文本檔案備份,可以使用SELECT * FROM OUTFILE ‘file_name’FROM tbl_name 。

也可以使用mysqldump建立文本檔案備份。

binary log提供了資料修改的sql,是以可以使用bianry log 來做增量備份。當增量備份的時候,使用flush logs,來重繞binary log,然後複制上次全備或者增量備份到最近全部複制,下次做全備時也要使用flush log。(flush log在dump之前)

當你在master上執行備份,問題很多,是以可以把備份放到slave上。

在slave備份的時候,不管用什麼方法,都要備份master info和relay log info。當要恢複複制的時候,等還原完slave,都需要使用master info和relay log info來恢複複制。如果slave在複制LOAD DATA INFILE語句,就需要備份任何在—slave-load-tmpdir選項中的SQL_LOAD-*檔案,用來恢複中斷的load data infile語句。

如果你要恢複出錯的MyISAM表,可以嘗試使用REPAIR TABLE或者myisamchk –r基本上都能恢複。

如果有支援Veritas檔案系統:

1.連接配接用戶端,然後執行FLUSH TABLES WITH READ LOCK

2.在另外一個shell,執行 mount vxfs snapshot

3.用戶端上,unlock tables

4.從快照中複制檔案

5.解除安裝快照

和lvm的快照處理方法不同,具體可以看《鳥哥linux私房菜 基礎篇》15.1

crash有記下幾種:1.系統crash,2.斷電,3.檔案系統crash,4.硬體錯誤。

當系統crash或者斷電後,假設mysql磁盤資料可以用,innodb可能沒有一緻性問題的資料,但是在日志檔案發現挂起的送出事務和未送出事務。那麼innodb會重做送出事務,復原未送出事務。

假設crash之後,mysql的磁盤資料不可用,也就是說不能成功啟動服務。那麼就有必要恢複備份資料,那麼之前就需要有備份。需要備份政策。

如在innodb表的資料中執行備份:

shell&gt; mysqldump --single-transaction --all-databases &gt; backup_sunday_1_PM.sql

備份操作要在所有的表上面擷取全局的讀鎖(flush tables with read lock),來保證資料不被修改。當長的update語句執行的時候可能會被flush 堵塞。直到語句完成。

假設是在innodb表的資料庫上面,使用—single-transaction可以保證mysqldump的讀一緻性。就算資料被其他應用修改,mysqldump也不會讀入。—single-transaction隻在innodb上有效。

對于大的資料庫做一次全備是很不容易的,是以使用增量來配合全備就很有效率。

增量備份相對較小,備份速度快,當恢複完全備之後恢複增量備份。

當全備的時候要做flush logs,這樣從全備以來的資料修改都會被記錄在目前的binary log:

shell&gt; mysqldump --single-transaction --flush-logs --master-data=2 \

         --all-databases &gt; backup_sunday_1_PM.sql

執行完上面指令後,生産一個新的日志檔案,因為—flush-logs導緻binary log 被重新整理打開一個新的日志。

--master-data選項導緻mysqldump寫資訊到binary log。

-- Position to start replication or point-in-time recovery from

-- CHANGE MASTER TO MASTER_LOG_FILE='gbichot2-bin.000007',MASTER_LOG_POS=4;

這個指令意味着:

1.dump檔案包含所有的在gbichot2-bin.000007生産之前的所有資料修改

2.所有備份之後的資料修改不在dump檔案中,在gbichot2-bin.000007以及之後的日志中。

假設後來在周1 13:00,通過flush logs建立了一個增量備份,gbichot2-bin.000008,那麼在原先gbichot2-bin.000007中包含了全備到周1 13:00所有的資料修改記錄。

假設在周2 13:00又通過flush logs執行了增量備份,gbichot2-bin.000008包含了周1 13:00 到周2 13:00之間的所有資料的修改記錄。

binary log 是比較占用空間的,可以使用—delete-master-logs來删除binary log:

         --all-databases --delete-master-logs &gt; backup_sunday_1_PM.sql

注意:

如果有配置複制的情況下使用—delete-master-logs很危險。可能出現還沒有被複制到slave的日志被删除。

假設在周3 8:00出現crash,需要從備份恢複,那麼先還原全備:

shell&gt; mysql &lt; backup_sunday_1_PM.sql

然後還原2個差異備份:

shell&gt; mysqlbinlog gbichot2-bin.000007 gbichot2-bin.000008 | mysql

等執行完之後,資料已經被恢複到了周2 13:00,但是還是有資料丢失,如果還能取到尾日志的情況(就是gbichot2-bin.000009),執行:

shell&gt; mysqlbinlog gbichot2-bin.000009 ... | mysql

執行完之後資料就恢複到了周3的8:00。

系統crash或者斷電,innodb會自己修複,但是為了安全性考慮:

1.确定已經啟動了binary log

2.定期的做全備

3.定期的做增量備份

mysqldump有2中方式:

1.不帶—tab,那麼mysqldump會輸出一個檔案所有的表結構和資料都在以sql方式在一個檔案中

2.帶—tab,那麼mysqldump會輸出一個資料庫接口檔案(sql),和一個文本檔案(資料)

指定所有資料庫輸出:

shell&gt; mysqldump --all-databases &gt; dump.sql

指定資料庫輸出:

shell&gt; mysqldump --databases db1 db2 db3 &gt; dump.sql

如果指定了—all-databases或者—databases,mysqldump會輸出create database,和use,這樣就能夠保證資料會被寫入到指定的資料庫。如果指定了—add-drop-database那麼會先drop資料庫然後create。

dump單個資料庫:

shell&gt; mysqldump --databases test &gt; dump.sql

或者

shell&gt; mysqldump test &gt; dump.sql

但是不指定—databases不會有create database和use。是以:

1.在使用dump檔案的時候,需要指定預設資料庫

2.可以指定和原來不一樣的資料庫

3.如果資料庫不存在需要先建立

4. —all-databases沒有效果

加載sql個是資料很友善:

shell&gt; mysql &lt; dump.sql

也可以

mysql&gt; source dump.sql

如果是不帶資料庫的dump,需要先建立資料庫:

shell&gt; mysqladmin create db1

shell&gt; mysql db1 &lt; dump.sql

mysql&gt; CREATE DATABASE IF NOT EXISTS db1;

mysql&gt; USE db1;

當使用選項—tab=dir_name就會輸出文本格式,并輸出到dir_name,每個資料庫有2個檔案,1,資料庫結構(.sql),2.文本存儲的資料(.txt)。

建立文本輸出:

shell&gt; mysqldump --tab=/tmp db1

因為是server寫的,是以到時候dump檔案是owner是運作服務的使用者。服務使用select…into outfile,是以需要有file權限的使用者來操作,如果輸出目錄出現同名檔案就會報錯。

如果在遠端服務上執行,那麼可能會出現.txt檔案在遠端,.sql檔案在本地。是以最好在本地運作。

資料檔案的輸出可以指定格式;

--fields-terminated-by=str 列分隔符預設為tab

--fields-enclosed-by=char 封裝列值,預設不使用

--fields-optionally-enclosed-by=char 封裝非數值列,預設不适用

--fields-escaped-by=char 需要跳過的字元,預設沒有

--lines-terminated-by=str 換行符預設為0xA

shell&gt; mysqldump --tab=/tmp --fields-terminated-by=,

         --fields-enclosed-by='"' --lines-terminated-by=0x0d0a db1

可以使用hex來代替字元:

--fields-enclosed-by='"'

--fields-enclosed-by=0x22

shell&gt; mysql db1 &lt; t1.sql

shell&gt; mysqlimport db1 t1.txt

mysql&gt; LOAD DATA INFILE 't1.txt' INTO TABLE t1;

如果是帶格式的,不是預設格式可以使用如下:

shell&gt; mysqlimport --fields-terminated-by=,

         --fields-enclosed-by='"' --lines-terminated-by=0x0d0a db1 t1.txt

mysql&gt; LOAD DATA INFILE 't1.txt' INTO TABLE t1

    -&gt; FIELDS TERMINATED BY ',' FIELDS ENCLOSED BY '"'

    -&gt; LINES TERMINATED BY '\r\n';

mysqldump可以解決一下問題:

1.如何複制資料庫

2.如何複制資料庫從A伺服器到B伺服器

3.輸出存儲程式(存儲過程,函數,觸發器,事件)

4.分開輸出資料庫結構和資料

shell&gt; mysqldump db1 &gt; dump.sql

shell&gt; mysqladmin create db2

shell&gt; mysql db2 &lt; dump.sql

在服務A中:

shell&gt; mysqldump --databases db1 &gt; dump.sql

在服務B中:

可以使用參數:

--events:用來導出排程事件

--routines:導出存儲過程和函數

--triggers:導出觸發器

當導出表的時候 –triggers預設是啟動的,其他2個選項預設是不系統的。可以使用—skip-events.—skip-routines,--skip-triggers跳過。

當制定—no-data的時候不帶資料導出,--no-create-info不帶結構導出。

shell&gt; mysqldump --no-data test &gt; dump-defs.sql

shell&gt; mysqldump --no-create-info test &gt; dump-data.sql

對于隻dump結構可以如下:

shell&gt; mysqldump --no-data --routines --events test &gt; dump-defs.sql

在生産伺服器上導出結構:

在更新伺服器上導入:

shell&gt; mysql &lt; dump-defs.sql

檢視列印的警告和錯誤。

如果沒有問題或者處理了問題,導入資料:

生産伺服器:

shell&gt; mysqldump --all-databases --no-create-info &gt; dump-data.sql

更新伺服器:

shell&gt; mysql &lt; dump-data.sql

然後再檢查資料是否正确導入。

時間點恢複,實質恢複到指定時間點,一般運作在全備之後。

使用—start-datetime,--stop-datetime來指定時間,

shell&gt; mysqlbinlog --stop-datetime="2005-04-20 9:59:59" \

         /var/log/mysql/bin.123456 | mysql -u root -p

從開始恢複到—stop-datetime指定的時間

shell&gt; mysqlbinlog --start-datetime="2005-04-20 10:01:00" \

從—start-datetime開始恢複到最後

使用以下方法來檢視确定準确的時間:

shell&gt; mysqlbinlog /var/log/mysql/bin.123456 &gt; /tmp/mysql_restore.sql

然後打開/tmp/mysql_restore.sql來檢查。

不是用時間可以使用Event位置來指定開始和結束:

shell&gt; mysqlbinlog --stop-position=368312 /var/log/mysql/bin.123456 \

         | mysql -u root -p

shell&gt; mysqlbinlog --start-position=368315 /var/log/mysql/bin.123456 \

Event位置在binary log的log_pos下.

myisamchk可以用來檢查,修複,優化MyISAM表。

盡管myisamchk很安全,但是還是要全備一下資料庫,以防萬一。

myisamchk操作會熬制MyISAM全文索引重建,需要注意。

MyISAM表維護也可以使用SQL語句:

1.MyISAM表檢查,可以使用CHECK TABLE.

2.MyISAM表修複,可以使用REPAIR TABLE

3.MyISAM表優化,可以使用OPTIMIZE TABLE

4.MyISAM表分析,可以使用ANALYZE TABLE

使用myisamchk,要保證服務沒有使用這個表,不然會出現沒必要的和服務之間的互動行為。

若能保證不會有别人通路mysqld,那麼隻需要執行mysqladmin flush-tabls,如果無法保證那麼就關閉服務。如果在運作myisamchk時,mysqld修改,就會出現告警說表出錯,就算沒有出錯還是會被認為出錯。

如果服務啟動external鎖啟動服務,可以在任何時候使用myisamchk檢查表,如果服務參數修改資料,就會堵塞,等待myisamchk完成。

如果使用myisamchk修複或者優化表,在沒有啟用external鎖的時候要保證mysqld不使用這個表。如果你不關閉mysqld,在執行myisam之前至少要mysqladmin flush-tabls。如果服務和myisamchk同時通路就有可能會表出錯。

myisam表,每個表有3個檔案,.frm結構檔案,.myd資料檔案,.myi索引檔案。

雖然每個檔案都有可能出現問題,但是一般不會出現在.frm結構檔案中。

myisamchk一行一行的檢查.myd資料檔案,當完成時,删除老的myd檔案,使用新的myd替代。

如果使用—quick,myisamchk不會建立一個臨時myd檔案,而是假設myd檔案是正确的,并生成新的索引。然後myisamchk自動發現myd檔案是否出錯,如果出錯就停止修複。

如果指定2次—quick,這樣myisamchk在一些錯誤上不會終止修複,而是嘗試去修改myd檔案來解決錯誤。2次—quick一般在沒有多少空間的情況下使用。使用之前記得要備份。

myisamchk tbl_name:可以發現大多數錯誤,隻涉及到資料檔案的錯誤不會被發現

myisamchk –m tbl_name:可以發現大多數錯誤,先檢查所有索引項,然後通過讀取所有行,計算所有key的checksum,然後和index tree對比。

myisamchk –e tbl_name:做全面的檢查,檢查讀取每一行,驗證他們實際上是指向目前行的。這個檢查很慢,特别是大表,有很多索引的。一般發現一個錯誤就停止了,可以加-v選項,但也最多隻能有20個錯誤。

myisamchk –e -i tbl_name:檢查和上面一樣,-i就是讓myisamchk列印一些靜态資訊。

表出錯的症狀,包括查詢突然異常,或者有一下錯誤:

1.tbl_name.frm被鎖定

2.找不到tbl_name.myi檔案

3.異常的檔案結尾

4.資料檔案crash

5.從錯誤表上擷取nnn錯誤。

為了擷取更多的錯誤資訊,可以使用perror nnn,nnn為錯誤碼擷取更多資訊。

shell&gt; perror 126 127 132 134 135 136 141 144 145

MySQL error code 126 = Index file is crashed

MySQL error code 127 = Record-file is crashed

MySQL error code 132 = Old database file

MySQL error code 134 = Record was already deleted (or record file crashed)

MySQL error code 135 = No more room in record file

MySQL error code 136 = No more room in index file

MySQL error code 141 = Duplicate unique key or constraint on write or update

MySQL error code 144 = Table is crashed and last repair failed

MySQL error code 145 = Table was marked as crashed and should be repaired

其中135和136并不算是錯誤,隻是所有檔案或者資料檔案空間不足可以使用:

ALTER TABLE tbl_name MAX_ROWS=xxx AVG_ROW_LENGTH=yyy;

如果無法确定的目前表的使用量,可以使用show create table

對于其他錯誤就必須修複表了,表修複有4個階段,在修複之前要保證對表檔案有通路權限。

如果在指令行上修複表,最好先把服務停掉,如果在遠端使用mysqladmin shutdown,會一段時間之後才能停止,因為需要一段時間把所有index的修改寫入到磁盤。

階段1:檢查表

使用myisamchk *.MYI或者myisamchk -e *.MYI來檢查表,可以使用-s(slient)跳過不必要的資訊。

如果伺服器沒有啟動,使用—update-state告訴myisamchk标記檢查過的表。

隻需要修複出現錯誤的表,對于這些表進入第二階段進行修複。

如果檢查的時候出現無法預期的錯誤,或者myisamchk奔潰,進入第三階段修複

階段2:簡單安全修複

先運作 myisamchk -r -q tbl_name,視圖修複索引檔案,如果資料檔案包含了所有資訊,删除連接配接(是什麼)指向了正确的資料檔案中的位置。那麼就能修複錯誤。

否則的話,以下過程:

1.先備份資料檔案

2.使用myisamchk –r tbl_name 來清理資料檔案中的錯誤的行和已經删除的行,并重新建構index檔案。

3.如果之前的步驟失敗,使用myisamchk –safe-recover tbl_name,安全模式修複使用老的修複方法來處理一些正常無法修複的問題。

如果出現異常錯誤,或者myisamchk崩潰進入階段3

注:

如果想要檢查快點可以把sort_buffer_size和key_buffer_size放大為可用記憶體的25%

階段3:比較困難的修複

到了這個階段隻有索引檔案頭16KB塊出現問題,或者索引檔案消失的情況

1.把資料檔案放到一個安全的地方

2.建立一個空的資料檔案和索引檔案

shell&gt; mysql db_name

mysql&gt; SET autocommit=1;

mysql&gt; TRUNCATE TABLE tbl_name;

mysql&gt; quit

3.把老的資料檔案複制過來,替換新的資料檔案,然後進入第二階段,直接運作簡單修複應該就可以正常了。

注意:如果有複制,那麼需要先停止,因為涉及到檔案系統操作。

除了使用myisamchk –r –q,還可以使用REPAIR TABLE tbl_name USE_FRM 語句

階段4:非常困難修複

進入到這個階段說明frm檔案出錯。

1.從備份中恢複放入frm檔案,然後傳回到階段3

2.如果沒有備份,但是記得表結構,可以直接建立一個表,删除新的資料檔案,然後複制frm,myi檔案到你crash的資料庫裡面,然後到階段2重新建立索引檔案。

為了合并碎片行,清理由删除或者update造成的浪費的空間,使用myisamchk的恢複模式,重新建立索引:

shell&gt; myisamchk -r tbl_name

當然可以使用OPTIMIZE TABLE語句來優化表。

mysiamchk還有其他選項可以用來提高表的性能:

--analyze(-a):分析key的分布(更新統計資訊),可以提高join的性能。

--sort-index(-s):排序index塊,可以優化查詢,讓表掃描更快

--sort-records=index_num(-R index_num):根據給定的索引重排資料行。可以提高range-base select和order by操作。

檢查和修複表的方法:

1.CHECK TABLE,REPAIR TABLE語句來檢查修複

2.使用myisamchk工具

可以通過crontab工具來完成定期的MyISAM表的維護

35 0 * * 0 /path/to/myisamchk --fast --silent /path/to/datadir/*/*.MYI

通常mysql表不需要維護,但是對變長字段修改頻繁,删除頻繁的表可以做一下維護

shell&gt; myisamchk -r -s --sort-index --myisam_sort_buffer_size=16M */*.MYI

<b>    本文轉自 Fanr_Zh 部落格園部落格,原文連結:http://www.cnblogs.com/Amaranthus/p/3903430.html</b><b>,如需轉載請自行聯系原作者 </b>