本章主要會介紹:html
1.備份的類型:邏輯備份,物理備份,全備和增量4種mysql
2.建立備份的方法linux
3.還原方法,包括還原到時間點web
4.備份計劃,壓縮和加密正則表達式
5.表維護,恢復損壞的表sql
7. 備份和恢復shell
7.1備份和還原類型數據庫
7.2.2 使用mysqldump和mysqlhotcopy備份
物理備份是直接複製備份數據庫目錄或者文件,這種備份比較適合大的比較重要的數據庫。
邏輯備份是把數據庫信息保存爲數據庫結構(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表基本上不會發送。
MyISAM的表維護能夠看7.6 MyISAM表的維護和Crash恢復
備份調度是用來自動產生備份。
壓縮用來減小備份佔用的空間。
加密保護數據安全性。
MySQL自己不包含這些能力,能夠經過MySQL企業級備份工具,壓縮innodb備份。文件系統能夠壓縮,加密備份。
MySQL企業級備份工具,備份衝instance到table級別,能夠增量,全備,壓縮備份。
innodb表能夠直接熱備,對於其餘引擎進行warm備份。
具體看:http://dev.mysql.com/doc/refman/5.6/en/backup-types.html
mysqldump的備份例子:
shell> mysqldump db_name > backup-file.sql
恢復數據庫:
shell> mysql db_name < backup-file.sql
shell> mysql -e "source /path-to-backup/backup-file.sql" db_name
遷移數據庫:
shell> mysqldump --opt db_name | mysql --host=remote_host -C db_name
備份多個數據庫:
shell> mysqldump --databases db_name1 [db_name2 ...] > my_databases.sql
mysqlhotcopy是一個perl腳本,使用FLUSH TABLES,LOCK TABLES和cp,scp備份數據庫。只能備份myisam和ARCHIVE的表。
shell> mysqlhotcopy db_name [/path/to/new_directory]
shell> mysqlhotcopy db_name_1 ... db_name_n /path/to/new_directory
也能夠用正則表達式,備份數據庫中的表:
shell> mysqlhotcopy db_name./regex/
用~前綴排除表名
shell> 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基本上都能恢復。
具體能夠看:7.6 MyISAM表的維護和Crash恢復
若是有支持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> mysqldump --single-transaction --all-databases > 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> mysqldump --single-transaction --flush-logs --master-data=2 \
--all-databases > 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:
shell> mysqldump --single-transaction --flush-logs --master-data=2 \
--all-databases --delete-master-logs > backup_sunday_1_PM.sql
注意:
若是有配置複製的狀況下使用—delete-master-logs很危險。可能出現尚未被複制到slave的日誌被刪除。
假設在周3 8:00出現crash,須要從備份恢復,那麼先還原全備:
shell> mysql < backup_sunday_1_PM.sql
而後還原2個差別備份:
shell> mysqlbinlog gbichot2-bin.000007 gbichot2-bin.000008 | mysql
等執行完以後,數據已經被恢復到了周2 13:00,可是仍是有數據丟失,若是還能取到尾日誌的狀況(就是gbichot2-bin.000009),執行:
shell> 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> mysqldump --all-databases > dump.sql
指定數據庫輸出:
shell> mysqldump --databases db1 db2 db3 > dump.sql
若是指定了—all-databases或者—databases,mysqldump會輸出create database,和use,這樣就可以保證數據會被寫入到指定的數據庫。若是指定了—add-drop-database那麼會先drop數據庫而後create。
dump單個數據庫:
shell> mysqldump --databases test > dump.sql
或者
shell> mysqldump test > dump.sql
可是不指定—databases不會有create database和use。因此:
1.在使用dump文件的時候,須要指定默認數據庫
2.能夠指定和原來不同的數據庫
3.若是數據庫不存在須要先建立
4. —all-databases沒有效果
加載sql個是數據很方便:
shell> mysql < dump.sql
也能夠
mysql> source dump.sql
若是是不帶數據庫的dump,須要先建立數據庫:
shell> mysqladmin create db1
shell> mysql db1 < dump.sql
或者
mysql> CREATE DATABASE IF NOT EXISTS db1;
mysql> USE db1;
mysql> source dump.sql
當使用選項—tab=dir_name就會輸出文本格式,並輸出到dir_name,每一個數據庫有2個文件,1,數據庫結構(.sql),2.文本存儲的數據(.txt)。
建立文本輸出:
shell> 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> mysqldump --tab=/tmp --fields-terminated-by=,
--fields-enclosed-by='"' --lines-terminated-by=0x0d0a db1
可使用hex來代替字符:
--fields-enclosed-by='"'
--fields-enclosed-by=0x22
shell> mysql db1 < t1.sql
shell> mysqlimport db1 t1.txt
或者
mysql> USE db1;
mysql> LOAD DATA INFILE 't1.txt' INTO TABLE t1;
若是是帶格式的,不是默認格式可使用以下:
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能夠解決一下問題:
1.如何複製數據庫
2.如何複製數據庫從A服務器到B服務器
3.輸出存儲程序(存儲過程,函數,觸發器,事件)
4.分開輸出數據庫結構和數據
shell> mysqldump db1 > dump.sql
shell> mysqladmin create db2
shell> mysql db2 < dump.sql
在服務A中:
shell> mysqldump --databases db1 > dump.sql
在服務B中:
shell> mysql < dump.sql
或者
在服務A中:
shell> mysqldump db1 > dump.sql
在服務B中:
shell> mysqladmin create db1
shell> mysql db1 < dump.sql
可使用參數:
--events:用來導出調度事件
--routines:導出存儲過程和函數
--triggers:導出觸發器
當導出表的時候 –triggers默認是啓動的,其餘2個選項默認是不繫統的。可使用—skip-events.—skip-routines,--skip-triggers跳過。
當制定—no-data的時候不帶數據導出,--no-create-info不帶結構導出。
shell> mysqldump --no-data test > dump-defs.sql
shell> mysqldump --no-create-info test > dump-data.sql
對於只dump結構能夠以下:
shell> mysqldump --no-data --routines --events test > dump-defs.sql
在生產服務器上導出結構:
shell> mysqldump --no-data --routines --events test > dump-defs.sql
在升級服務器上導入:
shell> mysql < dump-defs.sql
查看打印的警告和錯誤。
若是沒有問題或者處理了問題,導入數據:
生產服務器:
shell> mysqldump --all-databases --no-create-info > dump-data.sql
升級服務器:
shell> mysql < dump-data.sql
而後再檢查數據是否正確導入。
時間點恢復,實質恢復到指定時間點,通常運行在全備以後。
使用—start-datetime,--stop-datetime來指定時間,
shell> mysqlbinlog --stop-datetime="2005-04-20 9:59:59" \
/var/log/mysql/bin.123456 | mysql -u root -p
從開始恢復到—stop-datetime指定的時間
shell> mysqlbinlog --start-datetime="2005-04-20 10:01:00" \
/var/log/mysql/bin.123456 | mysql -u root -p
從—start-datetime開始恢復到最後
使用如下方法來查看肯定準確的時間:
shell> mysqlbinlog /var/log/mysql/bin.123456 > /tmp/mysql_restore.sql
而後打開/tmp/mysql_restore.sql來檢查。
不是用時間可使用Event位置來指定開始和結束:
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
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> 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個階段,在修復以前要保證對錶文件有訪問權限。
myisamchk的一些選項能夠查看: Section 4.6.3, 「myisamchk — MyISAM Table-Maintenance Utility」
myisamchk內存的使用,會影響myisamchk性能能夠查看: Section 4.6.3.6, 「myisamchk Memory Usage」.
若是在命令行上修復表,最好先把服務停掉,若是在遠程使用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> mysql db_name
mysql> SET autocommit=1;
mysql> TRUNCATE TABLE tbl_name;
mysql> quit
3.把老的數據文件複製過來,替換新的數據文件,而後進入第二階段,直接運行簡單修復應該就能夠正常了。
注意:若是有複製,那麼須要先中止,由於涉及到文件系統操做。
除了使用myisamchk –r –q,還可使用REPAIR TABLE tbl_name USE_FRM 語句
階段4:很是困難修復
進入到這個階段說明frm文件出錯。
1.從備份中恢復放入frm文件,而後返回到階段3
2.若是沒有備份,可是記得表結構,能夠直接建立一個表,刪除新的數據文件,而後複製frm,myi文件到你crash的數據庫裏面,而後到階段2從新建立索引文件。
爲了合併碎片行,清理由刪除或者update形成的浪費的空間,使用myisamchk的恢復模式,從新建立索引:
shell> 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> myisamchk -r -s --sort-index --myisam_sort_buffer_size=16M */*.MYI