物理備份對比邏輯備份
物理備份是指直接復制包含數據的文件夾和文件。這種類型的備份適用於大數據量且非常重要,遇到問題需要快速回復的數據庫。
邏輯備份保存能夠代表數據庫信息的邏輯結構(CREATE DATABASE, CREATE TABLEs等)和內容(INSERT …,或者分隔符分割的文本文件),這種類型的備份適合小數據量備份。可以通過備份文件進行庫結構,表機構或者數據的修改。
物理備份主要有以下特點:
- 備份文件包含所有的數據庫文件夾和文件,即是mysql數據文件夾下的全部(所有數據庫實例)或者部分(單個或多個數據庫實例)。
- 物理備份相較於邏輯備份快,它只涉及文件的拷貝而無需轉換。
- 備份文件較邏輯備份緊湊。
- 備份速度及壓縮性是備份的重要因素,尤其對業務繁忙且比較重要的數據庫。因此Mqsql企業級的備份使用物理備份。.
- 備份和恢復的力度包括整個數據文件級別、單個文件級別,根據數據庫引擎的不同可能提供表級別的力度。例如,Innodb引擎可以使用單表單文件存儲。MyISAM表包含一系列相關文件。.
- 除了基本的數據庫文件,備份還可以包含其它一些如日志、配置等相關的文件。
- MEMORY 引擎類型表很難使用這種類型備份,因為它的數據存儲在內存中。.
- 備份的跨平台性要求設備間具有相似的硬件特性設備間進行。
- 備份一般在mysql服務器停止的時候進行,如果需要運行中執行備份,則需要對特定表進行鎖操作,放置備份期間,表數據變化。
- 物理備份工具包括mysql的 mysqlbackup及文件系統級別的命令,如, scp, tar, rsync等
- 恢復:
- MySQL Enterprise Backup 可以恢復它所備份的備份。
- ndb_restore 用於恢NDB 表。
- 文件復制方式的復制,只需要將備份文件放到他們原始的位置即可。
邏輯備份有以下特點:
- 備份是以查詢mysql服務器方式來獲取數據庫結構及內容信息。
- 備份速度比物理備份慢,因為它需要首先訪問數據庫獲取數據,然后再轉化為相應的邏輯格式。如果備份實在客戶端,那么服務器還需要將備份發送到客戶端。
- 備份文件比物理備份的文件大,尤其是以文本方式存儲的時候。
- 備份和恢復粒度包括服務器級別、數據庫級別、表級別。與存儲引擎無關。
- 備份不包括日志和配置文件,及其它任何數據庫相關的非數據文件。
- 備份以邏輯格式存儲,與機器無關,可以跨平台使用。
- 邏輯備份需要mysql服務器在運行狀態。
- 備份工具包括 mysqldump 及 SELECT ... INTO OUTFILE 語句,其實這些工具使用於任何引擎。即使是MEMORY。
- 恢復,對於SQL-format dump 文件可以使用 mysql 客戶端。對於分隔符分割的文本類型文件,可以使用LOAD DATA INFILE 語句或者mysqlimport 客戶端。
在線備份 vs 線下備份
在線備份,即備份時,可以實時服務器信息。線下備份,即,在服務器停止的時候執行備份。相應的備份文件也可以稱為熱備或者冷備。還一種可以稱之為溫備,即備份的時候,服務器運行,但是不允許進行數據修改。
在線備份特點:
- 對於其它客戶端,備份是非侵入性的。不影響其它客戶端進行時特定允許的數據操作。
- 注意備份期間數據鎖的使用。
線下備份特點:
- 對客戶端的影響是不可逆的。因此,一般備份采取在備機上進行備份。
- 備份過程很簡單,客戶端無法進行干預。
備份的線上和線下區別基本相似。但是,線上恢復的時候,因為需要進行較多的鎖操作,所以受的影響比較大。恢復期間不要進行數據訪問操作。
本地備份 vs 遠程備份
本地備份即備份操作和數據庫服務器在同一台服務器上。遠程則相反。對於一些類型的備份,備份命令可以遠程觸發,本地寫備份。
- mysqldump 可以連接本地或者遠端服務器。生成本地或者遠端備份。分隔符分割的文本存儲在服務器所在服務器產生。
- SELECT ... INTO OUTFILE 本地或者遠程觸發。輸出在服務器端。
- 物理備份基本上都是本地執行。雖然備份可能會需要發送到其它服務器。
快照備份
一些文件系統支持快照。可以保存特定時間點的一份邏輯備份。而不需要復制整個文件系統。Mysql本身不提供這種功能,需要地方放工具如Veritas, LVM, or ZFS提供。
全量備份 vs 增量備份
全量備份即備份mysql管理的所有數據。增量備份即備份改變的數據。全量備份可以通過以上講述的一些備份方法進行備份。增量備份則需要通過啟用服務器二進制日志(記錄數據變化)來使用。
全量恢復 vs 增量恢復
全量恢復及恢復備份中所有的數據,是數據庫恢復到備份時數據庫狀態。如果全量恢復的狀態不夠實時,可以接着使用增量恢復,恢復全量備份到這一刻所有的數據變化,是數據庫狀態保持最新。
增量恢復即恢復一個時間段內的數據變化。基於二進制日志,作為全量備份的補充。二進制文件中存儲數據改變命令操作,通過重新執行相應的操作,使得數據庫恢復到特定的狀態.
備份規划、壓縮和加密
...
二、數據庫備份方法
使用mysqldump 備份
mysqldump 可以備份所有類型的表。對於 InnoDB
類型的表,可以通過--single-transaction
選項使用在線無鎖備份。
通過復制表數據文件備份
對於那些使用獨立文件存儲表的引擎,備份可以通過復制表文件進行。例如,MyISAM
表存儲文件(.frm:
表結構
, *.MYD
:表數據
, and *.MYI
:表索引)。為了保持數據的一致性,備份時需要關閉服務器或者鎖定相應的數據表:
FLUSH TABLES tbl_list WITH READ LOCK;
備份只需要讀鎖,這樣備份的同時不影響其它客戶端進行數據檢索。Flush操作是為了確保所有活躍的索引頁都已經寫盤。
也可以通過拷貝表文件來創建二進制備份,但,前提是在此期間不能進行任何的數據更新操作。 (對於包含Innodb類型表的數據庫不能采取此方法,因為即使不進行任何更新操作,Innodb仍然可能有更改的數據緩存在內存中)。
分隔符文本類型備份
操作命令: SELECT * INTO OUTFILE '
file_name
' FROM
tbl_name
.。備份文件生成在mysql服務器上。執行此語句需要確保輸出文件不存在,服務器不允許文件覆蓋操作,避免由此產生安全隱患。這一方法適用於任何類型數據文件,但是只能保存表記錄,無法保存表結構。
另一種創建文本類型備份(包含 CREATE TABLE
語句)的方法是使用 mysqldump 附帶--tab
選。加載文本類型本分可以使用 LOAD DATA INFILE
或者 mysqlimport.
二進制文件增量備份
MySQL支持增量備份。啟動服務器時附帶 --log-bin
選項啟用二進制日志功能。二進制文件記載了自某一次備份以來所有的數據更新操作。生成一份增量備份時, 需要使用FLUSH LOGS
或者mysqldump --flush-logs 生成一份新的日志文件,執行完成之后,將自某一次備份之后到最新的二進制日志文件復制到備份位置,即增量備份文件。恢復時,重新執行這些增量備份文件。
shell> mysqlbinlog binlog_files | mysql -u root -p
使用備機執行備份
備份一定程度上影響服務器的性能,因此通常我們選擇在備機上進行備份。
備機備份時,首先需要備份主機信息及中繼日志(relay log)。因為備份備機數據時,無論選用哪種備份方法,當重新使用備份數據恢復后,都需要重新將備份的主機信息及中繼日志進行復制。 當備機執行LOAD DATA INFILE
語句時,需要備份相應的SQL_LOAD-*
使用的文件夾。備機需要在LOAD DATA INFILE
崩潰時使用這些文件進行恢復。文件夾位置: --slave-load-tmpdir
。如果服務器啟動時並未指定此選項,則使用系統tmpdir
變量信息。
恢復崩潰表
恢復 MyISAM
表時,首先使用 REPAIR TABLE
或者 myisamchk -r 嘗試恢復,這通常能解決99.9% 以上的問題。
使用文件系統快照備份
Veritas文件系統下備份步驟如下:
- 首先客戶端執行
FLUSH TABLES WITH READ LOCK
. - 另起shell,執行
mount vxfs snapshot
。 - 在之前的客戶端執行
UNLOCK TABLES
. . - 拷貝快照文件.
- Unmount snapshot.
LVM及ZFS文件系統執行備份過程類似。
三、mysqldump 備份
使用mysqldump 備份及恢復,
dump文件作用:
- 數據備份,災難恢復
- 建立備機數據。
- 實驗數據:
- 數據副本
- 升級測試
mysqldump 根據配置不同,提供兩種輸出格式
- 不附帶
--tab
,mysqldump將sql語句寫到標准輸出,包括CREATE
語句和插入語句
。輸出可以保存為文件以備后續重新載入使用。可以通過配置選擇需要備份的對象。 - 使用
--tab
, mysqldump 每個表生成兩個文件對象。一個tab分隔符的文本文件tbl_name
.txt
,另一個包含CREATE TABLE
語句的文件tbl_name
.sql
。
使用mysqldump生成SQL格式備份
默認情況下mysqldump 輸出到標准輸出。使用以下命令輸出到文件:
shell> mysqldump [arguments] > file_name
備份所有數據庫 --all-databases
:
shell> mysqldump --all-databases > dump.sql
備份部分數據庫則在--databases
選項后添加數據庫名稱:
shell> mysqldump --databases db1 db2 db3 > dump.sql
--databases
選項標識后面命令行的指令都為數據庫名,如果沒有這個選項,則第一個為數據庫名,后續為表名。
--all-databases
和 --databases
,選項,使得mysqldump 創建的備份文件包括 CREATE DATABASE
及 USE
語句。這樣在恢復時,就可以針對特定的數據庫進行恢復,不至於造成所有的恢復都恢復到默認數據庫里。如果需要備份文件包含drop數據庫語句,則使用 --add-drop-database
選項。這樣就會在CREATE DATABASE
語句之前添加DROP DATABASE
語句。
備份單個數據庫:
shell> mysqldump --databases test > dump.sql
備份單個數據庫時可以不使用 –database選項:
shell> mysqldump test > dump.sql
不使用--databases
選項,備份文件不包含CREATE DATABASE
和 USE
語句:
- 恢復時需要指定數據庫。
- 如果指定的數據庫不存在,則需要首先創建。
- 不包含
DROP DATABASE
語句。
備份指定的表:
test t1 t3 t7 > dump
.
sql
SQL-Format 備份文件加載
生成時包含 --all-databases 或者 --databases 選項的,備份文件包含CREATE DATABASE 和 USE 語句,不需要再指定數據庫:
shell> mysql < dump.sql
sql命令行,使用source:
mysql> source dump.sql
備份不包含數據庫創建語句,確保指定恢復的數據庫存在:
shell> mysqladmin create db1
指定數據庫:
shell> mysql db1 < dump.sql
sql命令行執行:
mysql> CREATE DATABASE IF NOT EXISTS db1;
mysql> USE db1;
mysql> source dump.sql
文本分隔符格式備份
mysqldump --tab=
dir_name
,生成tbl.sql, tbl.txt文件到指定的輸出文件夾愛。.sql
文件包含CREATE TABLE
語句,.txt
文件包含表數據,一個文件行對應一條表記錄。
如下備份數據庫d1到 /tmp
目錄:
shell> mysqldump --tab=/tmp db1
.txt
包含服務器寫入的表數據。服務器使用SELECT ... INTO OUTFILE
語句寫文件,所以必須確保具有 FILE
訪問權。如果需要生成的文件已存在則會報錯。
The server sends the CREATE
definitions for dumped tables to mysqldump, which writes them to .sql
files. These files therefore are owned by the user who executes mysqldump.
--tab
最好本地使用,如果遠程使用,則必須確保服務器和客戶端都存在此目錄。這樣.txt
文件會寫到遠程客戶端文件夾,
.sql
文件會本地寫。
mysqldump --tab.txt
文件,每行一條表記錄,tab符分割,列值沒有修飾符,換行符分割行。
分割符設置,默認為tab
列值修飾符,默認無
非數字列值修飾符,默認無
特殊字符列值修飾符,默認無
行分隔符,默認換行
如下,雙引號修飾符
--fields-enclosed-by='"'
16進制雙引號修飾符:
--fields-enclosed-by=0x22
修飾符綜合使用:
shell> mysqldump --tab=/tmp --fields-terminated-by=, --fields-enclosed-by='"' --lines-terminated-by=0x0d0a db1
文本分割符備份文件載入
Shell命令:
shell> mysql db1 < t1.sql
shell> mysqlimport db1 t1.txt
mysql命令:
mysql> USE db1;
mysql> LOAD DATA INFILE 't1.txt' INTO TABLE t1;
If you used any data-formatting options with mysqldump 使用了任何數據格式化選項,則mysqlimport 或者 LOAD DATA INFILE 也不需使用相應的配置:
shell> mysqlimport --fields-terminated-by=, --fields-enclosed-by='"' --lines-terminated-by=0x0d0a db1 t1.txt
或者:
mysql> USE db1; mysql> LOAD DATA INFILE 't1.txt' INTO TABLE t1 FIELDS TERMINATED BY ',' FIELDS ENCLOSED BY '"' LINES TERMINATED BY '\r\n';
mysqldump 提示
數據庫復制
shell> mysqldump db1 > dump.sql shell> mysqladmin create db2 shell> mysql db2 < dump.sql
不要添加 --databases
選項,避免備份文件包含USE
語句。
服務器之間數據庫復制
服務器1:
shell> mysqldump --databases db1 > dump.sql
將備份文件復制到服務器2:
服務器2執行:
shell> mysql < dump.sql
備份存儲程序(存儲過程、函數、觸發器、事件)
--events
:事件--routines
:儲過程、函數--triggers
:觸發器(默認包含)
顯式剔除:--skip-events
, --skip-routines
, or --skip-triggers
.
分別備份表定義及數據
shell> mysqldump --no-data test > dump-defs.sql //備份定義 shell> mysqldump --no-create-info test > dump-data.sql //備份數據 shell> mysqldump --no-data --routines --events test > dump-defs.sql
使用mysqldump測試升級
生產服務器備份:
shell> mysqldump --all-databases --no-data --routines --events > dump-defs.sql
另外的升級服務器:
shell> mysql < dump-defs.sql
因為備份文件不包含數據,所以可以很快執行,這樣可以很快發現問題。
恢復數據:
生產服務器:
shell> mysqldump --all-databases --no-create-info > dump-data.sql
另外的升級服務器:
shell> mysql < dump-data.sql
四、二進制文件增量恢復
作為全全量備份的補充,用於將服務器更新到最新狀態。
規則:
查看二進制文件命令:
mysql> SHOW BINARY LOGS;
查看當前主二進制文件名稱:
mysql> SHOW MASTER STATUS;
- mysqlbinlog 將二進制日志轉化為文本格式,以便於閱讀和執行其中的指令,根據時間及位置定位日志中的事件。
- 使用 mysql 客戶端執行 mysqlbinlog 命令如下:
- 使用 mysqlbinlog 查看二進制日志內容
shell> mysqlbinlog binlog_files | mysql -u root -p shell> mysqlbinlog binlog_files | more
將二進制文件保存為文本類型文件:
shell> mysqlbinlog binlog_files > tmpfile shell> ... edit tmpfile ...
- 可以對生成的文本類型日志進行編輯,然后再做執行:
shell> mysql -u root -p < tmpfile
一個連接執行一個二進制日志會存在問題,下面是一個反面示例:
shell> mysqlbinlog binlog.000001 | mysql -u root -p # DANGER!! shell> mysqlbinlog binlog.000002 | mysql -u root -p # DANGER!!
使用一個連接執行所有的二進制日志文件:
shell> mysqlbinlog binlog.000001 binlog.000002 | mysql -u root -p
或者將所有的人日志寫入一個文件執行:
shell> mysqlbinlog binlog.000001 > /tmp/statements.sql shell> mysqlbinlog binlog.000002 >> /tmp/statements.sql shell> mysql -u root -p -e "source /tmp/statements.sql"
對於包含全局事物ID事件執行:
shell> mysqlbinlog --skip-gtids binlog.000001 > /tmp/dump.sql shell> mysqlbinlog --skip-gtids binlog.000002 >> /tmp/dump.sql shell> mysql -u root -p -e "source /tmp/dump.sql"
基於時間的增量恢復
mysqlbinlog使用 --start-datetime 和 --stop-datetime 選項確定執行的日志事件范圍。例如,10點的時候刪除了一張表,如果要恢復,就需要分別執行10點之前和之后的日志,如下:
shell> mysqlbinlog --stop-datetime="2005-04-20 9:59:59" \ /var/log/mysql/bin.123456 | mysql -u root -p shell> mysqlbinlog --start-datetime="2005-04-20 10:01:00" \ /var/log/mysql/bin.123456 | mysql -u root -p
查看而不執行:
shell> mysqlbinlog /var/log/mysql/bin.123456 > /tmp/mysql_restore.sql
mysqlbinlog不能很好的處理對於多個事件作為一個事件執行的日志。
基於日志位置的增量恢復
mysqlbinlog --start-position || --stop-position 精確到行號基於位置恢復。能夠很好的解決處理同時發生的多個事務的情景。為了確定精確的位置,首先使用 mysqlbinlog 獲取特定事務時間點前后一定范圍的日志,將其存儲到文本文件:
shell> mysqlbinlog --start-datetime="2005-04-20 9:55:00" \ --stop-datetime="2005-04-20 10:05:00" \ /var/log/mysql/bin.123456 > /tmp/mysql_restore.sql
找到位置后,就可以執行基於位置的增量恢復:
shell> mysqlbinlog --stop-position=368312 /var/log/mysql/bin.123456 \ | mysql -u root -p shell> mysqlbinlog --start-position=368315 /var/log/mysql/bin.123456 \ | mysql -u root -p
二進制日志各sql語句之前包含SET TIMESTAMP 語,重新執行的日志產生的日志會反映當時執行的時間戳。
MyISAM 表維護及崩潰恢復
myisamchk 檢查,修復及優化MyISAM
表
( .MYD
數據 .MYI
索引)。
雖然使用myisamchk修復表很安全,但也建議修復,或者維護前先備份。
myisamchk涉及或者影響索引的操作會引起MyISAM
全文索引使用全部的文本重建索引。這與
mysql
服務器使用創建索引的值不一致。因此操作時需要設置相關的選項。
MyISAM
表維護也可以使用相應的sql語句替代相關的myisamchk 操作。
CHECK TABLE
:檢查表REPAIR TABLE
.:修復表OPTIMIZE TABLE
:優化表ANALYZE TABLE
:分析表
這些語句可以單獨使用,或者使用mysqlcheck 執行相關的功能。使用myisamchk 的一個好處就是服務器可以做所有的工作,但同時要確保,服務器在 myisamchk 操作期間,不要進行任何其它操作,避免不必要的交互。
使用myisamchk 進行崩潰恢復
如果 mysqld 數據庫服務實例運行沒有開啟external locking (默認禁用,用於多線程下MyISAM數據表鎖定,及一個線程要使用某個表,必須等待其它線程釋放對這些表的鎖)。那么當服務器運行中,使用某些表時,就無法可靠的使用 myisamchk 進行檢查。如果確認某些表沒有被使用,那么只需要在使用 myisamchk檢查表之前執行mysqladmin flush-tables 操作。如果無法確定,就需要先關閉mysqld 實例,再執行。如果在使用 myisamchk 檢查表的同時,有mysqld 實例更新數據表,那么無論表是否崩潰,都會收到一個表崩潰的警告。
如果服務器啟動時啟用了external locking, 就可以隨時使用 myisamchk 來檢查表。這種情況下,當服務器試圖更新 myisamchk 正在檢查的表時,就會等待服務器檢查完畢再就緒執行表相關操作。
external locking啟用、服務器對表的訪問、mysqladmin flush-tables。
MyISAM
表涉及的三個文件:
File |
Purpose |
|
Definition (format) file |
|
Data file |
|
Index file |
通常出問題的就是數據文件和索引文件。
myisamchk工作過程:一行一行的復制舊的數據文件.MYD
到一個新的數據文件,然后刪除舊的數據文件,重命名新的數據文件為原有的數據文件名。
如果使用了 --quick
選項, myisamchk 將不會對數據文件進行處理,而僅僅創建一個新的索引文件。這種操作是安全的 myisamchk 可以自動檢測 .MYD
文件是否崩潰,如果崩潰就放棄修復。如果使用兩次 --quick
選項,則在某些異常情境下,如(主見重復), myisamchk將會嘗試通過修改.MYD
來修復。
通常情況下,在磁盤空間不足時,使用雙--quick
選項比較有用。但在此之前也要先備份表。
MyISAM 表錯誤檢查
表檢查命令:
這個命令通常能檢查99.99%的錯誤,但是對於只是由數據文件引起的錯誤則無法檢查。 執行檢查不需要附帶選項或者使用 -s 后台運行選項。
這個命令通常能檢查99.999% 的錯誤。它首先檢查所有的索引,然后檢查所有的數據行。他會計算所有主鍵校驗碼然后和索引中的校驗碼進行對比。
這一命令選項會執行全面的檢查 (-e 意為 “extended check”).,它會對每一個索引鍵執行一個檢查讀取的操作,確保所有的索引鍵都能執行正確的數據行位置。對於大數據量,有較多索引的表來說,這將耗費大量的時間。通常情況下,myisamchk 會在發現錯誤時停止,如果要獲取更多的錯誤,可以使用-v (verbose) 選項,最多能獲取到20個異常錯誤。
功能和上一個選項很像,-i選項會額外的打印相應的統計信息。
一般情況下,使用不附帶任何選項的myisamchk 命令即可。
MyISAM表修復
常見的查詢崩潰及錯誤如下:
- 找不到tbl_name.MYI文件 (Errcode: nnn)
- Unexpected end of file
- 記錄崩潰
- Got error nnn from table handler
可以運行perror nnn(錯誤號) 獲取更多的錯誤信息:
shell> 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 (索引文件沒有多余的空間)並不是myisamchk能夠修復的錯誤。可以通過ALTER TABLE 來修改 MAX_ROWS 和AVG_ROW_LENGTH 表選項:
ALTER TABLE tbl_name MAX_ROWS=xxx AVG_ROW_LENGTH=yyy;
如果不知道當前的表選項,可以使用命令SHOW CREATE TABLE查看。
其它錯誤可以使用myisamchk 來修復。
修復過程包含三個步驟:所有修復前,首先需要切換到數據庫文件夾的位置,並檢查表文件的訪問權限。
命令行修復表前,首先需要先停止mysqld 服務器。需要注意的是,執行完mysqladmin shutdown返回后,mysqld服務器直到完全停止(所有語句執行完畢,所有的索引變化都刷盤)前,還可以被訪問。
.\mysqlcheck.exe test drivers -h localhost -uroot -proot
步驟 1: 表檢查
運行myisamchk *.MYI,如果時間富裕,就使用myisamchk -e *.MYI。使用 -s (silent)避免顯示不必要的信息。
如果mysqld服務器停止,需要使用--update-state 來使得myisamchk 將表標記為“已檢查”。
只應該使用myisamchk修復已檢查出錯誤的表。然后執行步驟2。
如果執行修復期間發生不可預測的錯誤(如內存溢出等),或者myisamchk崩潰,則執行步驟3。
步驟 2: 簡單安全修復
首先,執行myisamchk -r -q tbl_name (-r –q 意為快速恢復模式)。此模式下,會嘗試在不訪問數據文件的情況下修復索引文件。如果數據文件包含所有應該包含的,刪除鏈接都能夠指向數據文件正確的位置,那么則繼續執行下一個表修復,否則的話,執行如下的步驟:
- 繼續執行前,首先備份數據文件
- 使用myisamchk -r tbl_name (-r 意為 “恢復模式”)。此操作會刪除錯誤和已刪除的行記錄,並重構索引文件。
- 如果上述的步驟失敗了。則使用 myisamchk --safe-recover tbl_name.。安全恢復模式使用一種舊的恢復方法,用於處理一些常規恢復模式無法處理的問題(速度相對會慢)
附記:
如果想要修復過程執行的快一些,則可以設置sort_buffer_size 和 key_buffer_size 變量為可用內存的25%。
步驟 3: 復雜修復
使用這一步驟的情景包括:索引文件的前16KB 空間完全損壞,或者包括錯誤的信息;索引文件丟失。遇到這種情景,則需要創建一個新的索引文件,步驟如下:
- 將數據文件移動到安全的地方
- 使用表定義文件創建新的數據(空)及索引文件:
shell> mysql db_name mysql> SET autocommit=1; mysql> TRUNCATE TABLE tbl_name; mysql> quit
- 將舊的數據文件拷貝覆蓋到新的數據文件位置(注意保留舊的數據文件,以免出現不必要的問題)
注意:如果在應用復制機制,首先需要停止復制,因為復制涉及到文件系統的操作,這些事mysql服務器無法記錄的。
執行完步驟3后,重新回到步驟2.,執行myisamchk -r -q 應該就可以修復了。(注意避免循環執行步驟2,3)
也可以使用REPAIR TABLE tbl_name USE_FRM SQL 語句,可以自動執行所有的步驟。
MyISAM 表優化
合並碎片記錄,回收浪費的空間(刪除或者更新操作引起),可以執行myisamchk 安全模式修復:
shell> myisamchk -r tbl_name
也可以使用OPTIMIZE TABLE
SQL語句。OPTIMIZE TABLE
執行表修復和鍵分析,同時排序索引樹,使得查找更快。
myisamchk其它選項:
--analyze
或者-a
::執行鍵分布分析。通過啟用聯合優化器,選擇優化的聯合順序及聯合鍵索引,提升聯合操作性能。--sort-index
或者–S
:排序索引塊,這一優化使得基於索引的查找及表掃描執行更快。--sort-records=
index_num
或者-R
index_num
:根據特定的索引排序行數據。這一操作會使得數據更加聚集,加速使用此索引的基於范圍的查詢和排序操作。
MyISAM 表維護定時計划
進行常規的表檢查,而不要遇到問題再修復。
一種檢查修復MyISAM
表的方式是使用CHECK TABLE
和REPAIR TABLE
語句。
另一種方式使用 myisamchk。使用myisamchk -s 命令,運行靜默方式,只打印myisamchk錯誤信息。
設置服務器自動檢查MyISAM
表,則需要在啟動
mysql
服務器時,添加
--myisam-recover-options
選項。
也可以使用應用系統的定時任務執行常規的表檢查,例如,使用 cron 定時任務工具: crontab
文件:
35 0 * * 0 /path/to/myisamchk --fast --silent /path/to/datadir/*/*.MYI
此命令會打印表崩潰錯誤信息,以便可以執行相應的檢查和修復。
也可以根據維護記錄調整表維護頻率。
通常情況下,MySQL 表極少需要維護,如果經常在涉及動態字段(VARCHAR
, BLOB
, 或者 TEXT
)的表執行更新操作,或者有表經常執行刪除操作。那么進行必要的碎片整理及空間回收會很有必要。可以通過使用 OPTIMIZE TABLE
來執行。另外也可以,通過停止mysqld 服務器,進到數據文件夾,執行如下命令:
shell> myisamchk -r -s --sort-index --myisam_sort_buffer_size=16M */*.MYI