mysql備份與恢復方法總結與比較

 

這兩天把mysql的各種備份方式總結了一下,部分是摘錄其餘人的內容。mysql

這些一些是綜合了許多文章得出的結論,一些是本身試驗的結果。正則表達式

多是不十分正確,若是各位發現錯誤,請指正!sql

 

MYISAM 引擎 的備份與恢復
一、 直接備份文件(cp 、tar)
方法:關閉mysql或者鎖頂定表,避免寫操做。將數據文件所有複製到備份路徑便可。
鎖表方法:FLUSH TABLES WITH READ LOCK(鎖全部庫全部表)

          LOCK TABLES  tbl_name (鎖某一表) (此種鎖定以前最好執行一下flush tables)shell

解鎖方法:unlock tables
恢復:直接將數據複製到mysql數據目錄下便可
優勢:簡單、方便、效率高
缺點:須要鎖表或關閉數據庫。不具備可移植性!數據易出錯
二、 mysqldump 備份
mysqldump客戶端可用來轉儲數據庫或蒐集數據庫進行備份或將數據轉移到另外一個SQL服務器(不必定是一個MySQL服務器)。
若是你在服務器上進行備份,而且表均爲MyISAM表,應考慮使用 mysqlhotcopy,由於能夠更快地進行備份和恢復。
方法:經常使用語句:

shell> mysqldump -uuser -ppass --default-character-set=utf8 --opt --extended-insert=false /數據庫

--triggers -R --hex-blob -x db_name > db_name.sql(注意參數順序)緩存

恢復:shell>mysqldump –uuser –ppass dn_name<db_name.sql
mysqldump 經常使用參數意義見下
優勢:備份出來的數據比較小,基本是純數據,可跨平臺
缺點:不支持增量備份。會鎖表,若是數據量大,鎖表時間會很長。
三、  mysqlhotcopy 備份
mysqlhotcopy是一個Perl腳本,最初由Tim Bunce編寫並提供。它使用LOCK TABLES、FLUSH TABLES和cp或scp來快速備份數據庫。它是備份數據庫或單個表的最快的途徑,但它只能運行在數據庫目錄所在的機器上。 mysqlhotcopy只用於備份MyISAM。它運行在Unix和NetWare中。使用以前,主機需安裝perl-DBD-MySQL和perl-DBI rpm包
方法:格式

Shell> mysqlhotcopy –uuser –ppass db_name /path/to/bakdir服務器

經常使用選項:
--addtodest  不重命名目標文件(若是存在),合併它們(增量備份)
--checkpoint=db_name.tbl_name    在指定的db_name.tbl_name插入檢查點條目,記錄mysqlhotcopy操做記錄
--method    備份方法使用cp或者scp,默認使用cp
--allowold  若是目標存在不放棄(加上一個_old後綴從新命名它)。
--noindices 備份中不包括所有索引文件。這樣使備份更小、更快。能夠在之後用myisamchk -rq從新構建索引。
--regexp= expr   複製全部數據庫名匹配給出的正則表達式的數據庫。
恢復:將備份出的數據複製(覆蓋)到mysql數據目錄(注意權限)
優勢:支持一次性拷貝多個數據庫,同時還支持正則表達。支持增量備份,備份速度快
缺點:只適用myisam引擎;只能在mysql數據目錄所在的主機上執行;
四、 sql 語法備份
BACKUP TABLE 語法其實和 mysqlhotcopy 的工做原理差很少,都是鎖表,而後拷貝數據文件。它能實如今線備份,可是效果不理想,所以不推薦使用。它只拷貝表結構文件(*.frm)和數據文件(*.myd),不一樣時拷貝索引文件,所以恢復時比較慢。只使用myisam引擎

語法:mysq>backup table tbl_name to ‘/path/to/backup/dir/’ (備份目錄mysql用戶要有寫的權限)app

SELECT INTO OUTFILE 則是把數據導出來成爲普通的文本文件,能夠自定義字段間隔的方式,方便處理這些數據。異步

 SELECT...INTO OUTFILE 'file_name'形式的SELECT能夠把被選擇的行寫入一個文件中。該文件被建立到服務器主機上,所以您必須擁有FILE權限,才能使用此語法。file_name必須是一個新文件,而不能是一個已經存在的文件。

SELECT...INTO OUTFILE語句的主要做用是讓您能夠很是快速地把一個錶轉儲到服務器機器上。若是您想要在服務器主機以外的部分客戶主機上建立結果文件,您不能使用SELECT...INTO OUTFILE。在這種狀況下,您應該在客戶主機上使用好比「mysql –e "SELECT ..." > file_name」的命令,來生成文件。ide

五、 binlog 日誌備份
二進制日誌記錄了全部的 DDL 和 DML 的語句, 但不包括查詢語句, 語句以事件方式保存。若是MySQL服務器啓用了二進制日誌,你可使用mysqlbinlog工具來恢復從指定的時間點開始 (例如,從你最後一次備份)直到如今或另外一個指定的時間點的數據。而壞處是日誌文件增加速度快,很快佔會佔滿磁盤空間,並且二進制日誌會使服務器性能大約慢1%.
以下狀況時,二進制日誌會更換到新的文件:
           (1)服務器重啓
           (2)服務器被更新
           (3)日誌達到最大日誌長度 max_binlog_size
           (4)在 MySQL 命令終端 FLUSH LOGS
開啓方法:修改my.cnf,在[mysqld]下開啓binkog日誌

log-bin=mysql-bin
binlog-do-db=db_test(指定開啓binlog的數據庫,如不知道,默認是所有數據庫)
binlog-do-db=db_test2

expire_logs_day=3(設置日誌的過時天數,過了指定的天數,會自動刪除,如不設置,默認永久保存)    
從新啓動數據庫
恢復方法:

(1)、mysqlbinlog -stop-date=「2012-08-24 9:59:59」 /var/log/mysql/mysql-bin.[0-9]* | mysql -u root –ppass                   (讀取日誌最開始至2012-08-24的全部日誌並恢復)

(2)、mysqlbinlog -stop-date=「2012-08-24 9:59:59」 /var/log/mysql/mysql-bin.[0-9]* | mysql -u root –ppass --one-database db_name (只按時間恢復某一數據庫得信息)

(3)、mysqlbinlog -stop-date=「2012-08-24 9:59:59」 /var/log/mysql/mysql-bin.[0-9]*>file.sql

(將日誌轉換成sql文件,可直接導入到mysql內)
Mysqlbinlog 經常使用參數:
--start-position=N     從二進制日誌中第1個位置等於N參量時的事件開始讀
--stop-position=N      從二進制日誌中第1個位置等於和大於N參量時的事件起中止讀。
--start-datetime=datetime       從二進制日誌中第1個日期時間等於或晚於 datetime參量的事件開始讀取。 datetime值相對於運行mysqlbinlog的機器上的本地時區
---database=db_name,-d db_name       只列出該數據庫的條目(只用本地日誌)。
-h host_name   獲取給定主機上的MySQL服務器的二進制日誌。
--to-last-logs,-t       在MySQL服務器中請求的二進制日誌的結尾處不中止,而是繼續打印直到最後一個二進制日誌的結尾。若是將輸出發送給同一臺MySQL服務器,會致使無限循環。該選項要求--read-from-remote-server。
--disable-logs-bin,-D       禁用二進制日誌。若是使用--to-last-logs選項將輸出發送給同一臺MySQL服務器,能夠避免無限循環。該選項在崩潰恢復時也頗有用,能夠避免複製已經記錄的語句。註釋:該選項要求有SUPER權限。
六、 mysql 主從複製
MySQL支持單向、異步複製,複製過程當中一個服務器充當主服務器,而一個或多個其它服務器充當從服務器。(這與 同步複製能夠進行對比, 同步複製是MySQL簇的一個特徵)。主服務器將更新寫入二進制日誌文件,並維護文件的一個索引以跟蹤日誌循環。這些日誌能夠記錄發送到從服務器的更新。當一個從服務器鏈接主服務器時,它通知主服務器從服務器在日誌中讀取的最後一次成功更新的位置。從服務器接收從那時起發生的任何更新,而後封鎖並等待主服務器通知新的更新。
主從複製嚴格來講不算一種備份方式,它只是將主mysql上全部的寫操做在從的從新執行了一遍。這樣寫操做在主庫上,在從庫上能夠讀數據庫,從而實現讀寫分離,下降了主庫的壓力,提升了查詢速度。而在從庫上執行上面的備份方法,能夠大膽的鎖表或關閉數據庫,提升mysql的高可用性。
[具體配置方法見附錄]
七、 軟件備份XtarBackup (innobackupex
Xtrabackup下的innobackupex 支持myisam的備份。備份時也會鎖表(不支持增量備份)
備份

shell>innobackupex –defaults-file=/etc/my.cnf –user=username –password=passwd --databases=」databases1 databases2」 /bak/path/to/dir

恢復:

Shell>innobackupex –apply-log –defaults-file=/etc/my.cnf –user=username –password=passwd /path/to/bak/dir/data

由於innobackupex存在bug,因此執行完上面的命令後,須要手動將備份出的(.frm .MYD .MYI)文件覆蓋的mysql的數據目錄!
 
Innodb 引擎 的備份與恢復
一、 Mysqldump

Shell> mysqldump -uuser -ppass --default-character-set=utf8 --opt --extended-insert=false /

--triggers -R --hex-blob --single-transaction db_name > db_name.sql

恢復:shell>mysqldump –uuser –ppass dn_name<db_name.sql
二、  軟件備份XtarBackup(xtrabackup)
xtrabackup

優勢:支持熱備,支持增量備份。
xtrabackup缺點:備份是物理拷貝+邏輯備份的方式備份數據庫,會發生物理磁盤的讀操做,可是物理備份的速度會比較快。
總的來看xtrabackup會比mysqldump優秀不少,由於他支持熱備和增量備份。可是這個也是根據數據庫狀況而定,若是是在slave上作備份,不用太多的考慮表鎖問題,mysqldump也是很不錯的。還有就是若是數據量不大,小於5G,數據基本都是update語句較多的狀況下,不太適合使用xtrabackup作全備和增量備份策略,由於xtrabackup增量備份的原理是經過lsn(日誌序號)來操做的,若是你的數據庫更新太頻繁,天天新的lsn太多,那增量備份尚未全備來的快,還有就是xtrabackup全備的時候會備份ib_logfile*和ibdata*,就算你使用的獨享表空間也會備份這些文件,因此每次全備的size會比較大,磁盤空間和系統資源的佔用也比較多。

Xtrabackup中包含兩個工具:
xtrabackup 只能備份InnoDB和XtraDB兩種數據表,支持在線熱備份,能夠在不加鎖的狀況下備份Innodb數據表,不過此工具不能操做Myisam引擎表
innobackupex  是一個腳本封裝,封裝了xtrabackup,能同時處理Innodb和Myisam,但在處理Myisam時須要加一個讀鎖。
方法:

(1)   普通備份(全量備份) 

Xtrabackup –defaulets-file=/etc/my.cnf –backup –target-dir=/path/to/backdir/

注意:xtrabackup只備份數據文件,並不備份數據表結構(.frm),因此這裏要手動備份一下,以便xtrabackup恢復的時候使用。 

(2)     增量備份 xtrabackup –default-file=/etc/my.cnf –backup –target-dir=/path/to/backdir –incremental-basedir=/path/to/base/backdir

補充:
myisamchk
myisamchk能夠得到有關數據庫表的信息或檢查、修復、優化他們。
myisamchk適用MyISAM表。
當你運行 myisamchk時,必須確保其它程序不使用表。

使用以前先執行「FLUSH TABLES」 強制清空仍然在內存中的任何表修改,同時確保myisamchk執行過程當中其餘程序不使用表。不然會報錯「warning: clients are using or haven't closed the table properly」

避免此問題出現的最簡單方法是用check table命令來檢查表,用法「sql>check table dbname.tabname」
 
mysqldump
mysqldump支持下面的選項:

--add-drop--database 在每一個CREATE DATABASE語句前添加DROP DATABASE語句。

---database,-B 轉儲幾個數據庫。一般狀況,mysqldump將命令行中的第1個名字參量看做數據庫名,後面的名看做表名。使用該選項,它將全部名字參量看做數據庫名。CREATE DATABASE IF NOT EXISTS db_name和USE db_name語句包含在每一個新數據庫前的輸出中。
--tables 覆蓋---database或-B選項。選項後面的全部參量被看做表名。

--default-character-set=charset 使用charsetas默認字符集。若是沒有指定,mysqldump使用utf8。若是數據表不是採用默認的 latin1 字符集的話,那麼導出時必須指定該選項,不然再次導入數據後將產生亂碼問題。

--delayed-insert 使用INSERT DELAYED語句插入行。

--delete-master-logs 在主複製服務器上,完成轉儲操做後刪除二進制日誌。該選項自動啓用--master-data。

--disable-keys,-K   對於每一個表,用/*!40000 ALTER TABLE tbl_name DISABLE KEYS */;和/*!40000 ALTER TABLE tbl_name ENABLE KEYS */;語句引用INSERT語句。這樣能夠更快地裝載轉儲文件,由於在插入全部行後建立索引。該選項只適合MyISAM表。

--extended-insert,-e 使用包括幾個VALUES列表的多行INSERT語法。這樣使轉儲文件更小,重載文件時能夠加速插入。

--flush-logs,-F   開始轉儲前刷新MySQL服務器日誌文件。該選項要求RELOAD權限。請注意若是結合--all--database(或-A)選項使用該選項,根據每一個轉儲的數據庫刷新日誌。例外狀況是當使用--lock-all-tables或--master-data的時候:在這種狀況下,日誌只刷新一次,在全部 表被鎖定後刷新。若是你想要同時轉儲和刷新日誌,應使用--flush-logs連同--lock-all-tables或--master-data。

--force,-f  在錶轉儲過程當中,即便出現SQL錯誤也繼續。

--host=host_name,-h host_name   從給定主機的MySQL服務器轉儲數據。默認主機是localhost。

--hex-blob 使用十六進制格式導出二進制字符串字段。若是有二進制數據就必須使用本選項。影響到的字段類型有 BINARY、VARBINARY、BLOB。
--lock-all-tables,-x    全部數據庫中的全部表加鎖。在總體轉儲過程當中經過全局讀鎖定來實現。該選項自動關閉--single-transaction和--lock-tables。
--lock-tables,-l 開始轉儲前鎖定全部表。用READ LOCAL鎖定表以容許並行插入MyISAM表。對於事務表例如InnoDB和BDB,--single-transaction是一個更好的選項,由於它不根本須要鎖定表。請注意當轉儲多個數據庫時,--lock-tables分別爲每一個數據庫鎖定表。所以,該選項不能保證轉儲文件中的表在數據庫之間的邏輯一致性。不一樣數據庫表的轉儲狀態能夠徹底不一樣。
--master-data[=value] 該選項將二進制日誌的位置和文件名寫入到輸出中。該選項要求有RELOAD權限,而且必須啓用二進制日誌。若是該選項值等於1,位置和文件名被寫入CHANGE MASTER語句形式的轉儲輸出,若是你使用該SQL轉儲主服務器以設置從服務器,從服務器從主服務器二進制日誌的正確位置開始。若是選項值等於2,CHANGE MASTER語句被寫成SQL註釋。若是value被省略,這是默認動做。
--master-data 選項啓用--lock-all-tables,除非還指定--single-transaction(在這種狀況下,只在剛開始轉儲時短期得到全局讀鎖定。又見--single-transaction。)在任何一種狀況下,日誌相關動做發生在轉儲時。該選項自動關閉--lock-tables。

--single-transaction 該選項從服務器轉儲數據以前發出一個BEGIN SQL語句。它只適用於事務表,例如InnoDB和BDB,由於而後它將在發出BEGIN而沒有阻塞任何應用程序時轉儲一致的數據庫狀態。當使用該選項時,應記住只有InnoDB表能以一致的狀態被轉儲。例如,使用該選項時任何轉儲的MyISAM或HEAP表仍然能夠更改狀態。--single-transaction選項和--lock-tables選項是互斥的,由於LOCK TABLES會使任何掛起的事務隱含提交。要想轉儲大的表,應結合--quick使用該選項。

--no-data,-d 不寫表的任何行信息。若是你只想轉儲表的結構這頗有用。

--opt          該選項是速記;等同於指定 --add-drop-tables--add-locking --create-option --disable-keys--extended-insert --lock-tables --quick --set-charset。它能夠給出很快的轉儲操做併產生一個能夠很快裝入MySQL服務器的轉儲文件。該選項默認開啓,但能夠用--skip-opt禁用。要想只禁用確信用-opt啓用的選項,使用--skip形式;例如,--skip-add-drop-tables或--skip-quick。

--quick,-q 該選項用於轉儲大的表。它強制mysqldump從服務器一次一行地檢索表中的行而不是檢索全部行並在輸出前將它緩存到內存中。
--routines,-R 在轉儲的數據庫中轉儲存儲程序(函數和程序)。使用---routines產生的輸出包含CREATE PROCEDURE和CREATE FUNCTION語句以從新建立子程序。可是,這些語句不包括屬性,例如子程序定義者或建立和修改時間戳。這說明當重載子程序時,對它們進行建立時定義者應設置爲重載用戶,時間戳等於重載時間。若是你須要建立的子程序使用原來的定義者和時間戳屬性,不使用--routines。相反,使用一個具備mysql數據庫相應權限的MySQL帳戶直接轉儲和重載mysql.proc表的內容。
--triggers 爲每一個轉儲的錶轉儲觸發器。該選項默認啓用;用--skip-triggers禁用它。

MySQL表級鎖的鎖模式
MySQL的表級鎖有兩種模式:表共享讀鎖(Table Read Lock)和表獨佔寫鎖(Table Write
Lock)。MyISAM在執行查詢語句(SELECT)前,會自動給涉及的全部表加讀鎖,在執行更新操做(UPDATE、DELETE、INSERT等)前,會自動給涉及的表加寫鎖。
因此對MyISAM表進行操做,會有如下狀況:
a、對MyISAM表的讀操做(加讀鎖),不會阻塞其餘進程對同一表的讀請求,但會阻塞對同一表的寫請求。只有當讀鎖釋放後,纔會執行其它進程的寫操做。
b、對MyISAM表的寫操做(加寫鎖),會阻塞其餘進程對同一表的讀和寫操做,只有當寫鎖釋放後,纔會執行其它進程的讀寫操做。

鎖表方法
FLUSH TABLES WITH READ LOCK;
這個命令是全局讀鎖定,執行了命令以後全部庫全部表都被鎖定只讀。通常都是用在數據庫聯機備份,這個時候數據庫的寫操做將被阻塞,讀操做順利進行。

解鎖的語句也是unlock tables。 LOCK TABLES tab_name

相關文章
相關標籤/搜索