1. 程式人生 > >mysql備份和恢復

mysql備份和恢復

       對於DBA來說,資料的備份和恢復是一項很基本的操作。在意外的情況下(伺服器宕機,磁碟損壞,RAID卡損壞等),要保證資料不丟失,或者是最小程度的丟失,是每個DBA每時每刻應該關心資料庫的備份了。本來說明下備份的工具,原理以及使用。

一、備份與恢復的概述

按照是否能夠繼續提供服務,將資料庫備份型別劃分為:
熱備份:(線上備份)在資料庫執行的過程中進行備份,並且不影響資料庫的任何操作
溫備份:能讀不能寫,在資料執行的過程中進行備份,但是對資料有影響,如需要加全域性鎖保證資料的一致性。
冷備份:(離線備份)在停止資料庫的情況下,複製備份資料庫的物理檔案。

按照備份後文件的內容分類:
邏輯備份:備份檔案時可讀的文字檔案,比如sql語句,適合資料庫的遷移和升級,但是恢復時間比較長。
裸檔案備份:複製資料庫的物理檔案

按照備份資料庫的內容分類:
完全備份:對資料庫進行一個完整的備份
增量備份:在完全備份的基礎上,對資料庫的增量進行備份
日誌備份:只要是對binlog的備份

二、冷備

      只需要備份mysql資料庫的frm檔案,共享表空間檔案,獨立表空間檔案(*.ibd),重做日誌檔案,以及msyql的配置檔案my.cnf。

優點:
備份簡單,只需要複製檔案就可以
恢復簡單,只需要把檔案恢復到指定位置
恢復速度快,

缺點:
備份檔案較大,因為表空間存在大量的其他資料,比如undo段,插入緩衝等
不能總是輕易跨平臺

三、邏輯備份

3.1、mysqldump

語法:

mysqldump [OPTIONS] database [tables]
mysqldump [OPTIONS] --databases [OPTIONS] DB1 [DB2 DB3...]
mysqldump [OPTIONS] --all-databases [OPTIONS]

選項:

-u, --user=name        #指定使用者名稱
-S, --socket=name      #指定套接字路徑
-p, --password[=name]  #指定密碼
-P, --port=3306        #指定埠
-h, --host=name        #指定主機名
-r, --result-file=name #將匯出結果儲存到指定的檔案中,在Linux中等同於覆蓋重定向。
--all-databases, -A    #指定dump所有資料庫。等價於使用--databases選定所有庫
--databases, -B        #指定需要dump的庫。該選項後的所有內容都被當成資料庫名;在輸出檔案中的每個資料庫前會加上建庫語句和use語句
--ignore-table=db_name.tbl_name   #匯出時忽略指定資料庫中的指定表,同樣可用於忽略檢視,要忽略多個則多次寫該選項
-d, --no-data          #不匯出表資料,可以用在僅匯出表結構的情況。
--events, -E           #匯出事件排程器
--routines, -R         #匯出儲存過程和函式。但不會匯出它們的屬性值,若要匯出它們的屬性,可以匯出mysql.proc表然後reload
--triggers             #匯出觸發器,預設已開啟
--tables               #覆蓋--databases選項,匯出指定的表。但這樣只能匯出一個庫中的表。格式為--tables database_name tab_list
--where='where_condition', -w 'where_condition'   #指定篩選條件並匯出表中符合篩選的資料,如--where="user='jim'"
--add-drop-database    #在輸出中的create database語句前加上drop database語句先刪除資料庫
--add-drop-table       #在輸出的create table語句前加上drop table語句先刪除表,預設是已開啟的
--add-drop-trigger     #在輸出中的create trigger語句前加上drop trigger語句先刪除觸發器
-n, --no-create-db     #指定了--databases或者--all-databases選項時預設會加上資料庫建立語句,該選項抑制建庫語句的輸出
-t, --no-create-info   #不在輸出中包含建表語句
--replace              #使用replace代替insert語句
--default-character-set=charset_name  #在匯出資料的過程中,指定匯出的字符集。很重要,客戶端服務端字符集不同匯出時可能亂碼,預設使用utf8
--set-charset          #在匯出結果中加上set names charset_name語句。預設啟用。
--compact              #簡化輸出匯出的內容,幾乎所有註釋都不會輸出
--complete-insert, -c  #在insert語句中加上插入的列資訊
--create-options       #在匯出的建表語句中,加上所有的建表選項
--tab=dir_name, -T dir_name #將每個表的結構定義和資料分別匯出到指定目錄下檔名同表名的.sql和txt檔案中,其中.txt
                            #檔案中的欄位分隔符是製表符。要求mysqldump必須和MySQL Server在同一主機,且mysql用
                            #戶對指定的目錄有寫許可權,並且連線資料庫的使用者必須有file許可權。且指定要dump的表,不能和
                            #--databases或--all-databases一起使用。它的實質是執行select into outfile。
--fields-terminated-by=name #指定輸出檔案中的欄位分隔符
--fields-enclosed-by=name   #指定輸出檔案中的欄位值的包圍符,如使用引號將字串包圍起來引用
--fields-optionally-enclosed-by=name   #指定輸出檔案中可選欄位引用符
--fields-escaped-by=name               #指定輸出檔案中的轉義符
--lines-terminated-by=name             #指定輸出檔案中的換行符   
-Q, --quote-names                      #引用表名和列名時使用的識別符號,預設使用反引號"`" 
--delayed-insert         #對於非事務表,在insert時支援delayed功能,但在MySQL5.6.6開始該選項已經廢棄
--disable-keys, -K       #在insert語句前後加上禁用和啟用索引語句,大量資料插入時該選項很適合。預設開啟
--insert-ignore          #使用insert ignore語句替代insert語句
--quick, -q              #快速匯出資料,該選項對於匯出大表非常好用。預設匯出資料時會一次性檢索表中所有資料並加入
                         #到記憶體中,而該選項是每次檢索一行並匯出一行
--add-locks              #在insert語句前後加上lock tables和unlock tables語句,預設已開啟。
--flush-logs, -F         #在開始dump前先flush logs,如果同時使用了--all-databases則依次在每個資料庫dump前flush,
                         #如果同時使用了--lock-all-tables,--master-data或者--single-transaction,則僅flush
                         #一次,等價於使用flush tables with read lock鎖定所有表,這樣可以讓dump和flush在完全精
                         #確的同一時刻執行。
--flush-privileges       #在dump完所有資料庫後在資料檔案的結尾加上flush privileges語句,在匯出的資料涉及mysql庫或
                         #者依賴於mysql庫時都應該使用該選項
--lock-all-tables, -x    #為所有表加上一個持續到dump結束的全域性讀鎖。該選項在dump階段僅加一次鎖,一鎖鎖永久且鎖所有。
                         #該選項自動禁用--lock-tables和--single-transaction選項
--lock-tables, -l        #在dump每個資料庫前依次對該資料庫中所有表加read local鎖(多次加鎖,lock tables...read local),
                         #這樣就允許對myisam表進行併發插入。對於innodb儲存引擎,使用--single-transaction比
--lock-tables            #更好,因為它不完全鎖定表。因為該選項是分別對資料庫加鎖的,所以只能保證每個數
                         #據庫的一致性而不能保證所有資料庫之間的一致性。該選項主要用於myisam表,如果既有myisam又有
                         #innodb,則只能使用--lock-tables,或者分開dump更好
--single-transaction     #該選項在dump前將設定事務隔離級別為repeatable read併發送一個start transaction語句給
                         #服務端。該選項對於匯出事務表如innodb表很有用,因為它在發出start transaction後能保證導
                         #出的資料庫的一致性時而不阻塞任何的程式。該選項只能保證innodb表的一致性,無法保證myisam表
                         #的一致性。在使用該選項的時候,一定要保證沒有任何其他連線在使用ALTER TABLE,CREATE TABLE,
                         #DROP TABLE,RENAME TABLE,TRUNCATE TABLE語句,因為一致性讀無法隔離這些語句。
                         #--single-transaction 選項和--lock-tables選項互斥,因為lock tables會隱式提交事務。
                         #要匯出大的innodb表,該選項結合--quick選項更好
--no-autocommit          #在insert語句前後加上SET autocommit = 0,並在需要提交的地方加上COMMIT語句
--order-by-primary       #如果表中存在主鍵或者唯一索引,則排序後按序匯出。對於myisam表遷移到innobd表時比較有用,但是
                         #這樣會讓事務變得很長很慢    

簡單使用(由於比較簡單,不具體闡述):

mysqldump -uroot -p123456 -A -r all.sql        #備份所有資料庫
mysqldump -uroot -p123456 -A > all.sql        #備份所有資料庫        
mysqldump -uroot -p123456 -B test test1 > db_test.sql #備份test和test1資料庫
mysqldump -uroot -p123456 --single-transaction -A > all.sql #innodb開始事務備份所有資料 
mysqldump -uroot -p123456 --default-character-set=latin1 -A > all.sql #指定字符集備份所有資料
mysqldump -uroot -p123456 --tables test gxt1 -r gxt.sql  #備份test庫的gxt1表

mysqldump工具使用建議:

1.從效能考慮:在需要匯出大量資料的時候,使用--quick選項可以加速匯出,但匯入速度不變。如果是innodb表,則可以同時加上--no-autocommit選項,這樣大量資料量匯入時將極大提升效能。

2.一致性考慮:對於innodb表,幾乎沒有理由不用--single-transaction選項。對於myisam表,使用--lock-all-tables選項要好於--lock-tables。既有innodb又有myisam表時,可以分開匯出,又能保證一致性,還能保證效率。

3.方便管理和維護性考慮:在匯出時flush log很有必要。加上--flush-logs選項即可。而且一般要配合--lock-all-tables選項或者--single-transaction選項一起使用,因為同時使用時,只需重新整理一次日誌即可,並且也能保證一致性。同時,還可以配合--master-data=2,這樣就可以方便地知道二進位制日誌中備份結束點的位置。

4.字符集考慮:如果有表涉及到了中文資料,在dump時,一定要將dump的字符集設定的和該表的字符集一樣。

5.雜項考慮:備份過程中會產生二進位制日誌,但是這是沒有必要的。所以在備份前可以關掉,備份完後開啟。set sql_log_bin=0關閉,set sql_log_bin=1開啟。

msyqldump結合binlog日誌實現增量備份
1、首先全備:mysqldump -uroot -p123456 -q --no-autocommit --flush-logs --single-transaction --master-data=2 --tables test gxt1 > gxt.sql
2、修改表中的資料:insert into test.gxt1 values(1,'王麻子');
3、備份二進位制日誌:mysqlbinlog mysql-bin.000002 >new_gxt.sql #這裡需要指定時間或者指定position對增量進行備份
4、模擬刪掉:drop table test.gxt1;
5、恢復:
mysql>use test;
mysql>source gxt.sql;
mysql>source new_gxt.sql;

總結

       msyqldump是屬於邏輯備份,備份sql語句,簡單,但是由於恢復時都是通過insert進行插入,所有恢復速度慢,mysqldump備份myisam表時因為要加--lock-all-tables,這時要備份的資料庫全部被上鎖,可讀不可寫,所以實現的是溫備。mysqldump備份innodb表時因為要加--single-transaction,會自動將隔離級別設定為repeatable read並開啟一個事務,這時mysqldump將獲取dump執行前一刻的行版本,並處於一個長事務中直到dump結束。所以不影響目標資料庫的使用,可讀也可寫,即實現的是熱備

3.2、select ... into outfile

load data infile和select into outfile語句是配套的。可以通過引數secure_file_priv對其進行控制是否可以使用:

 

 

常用自定義格式說明:

fields terminated by 'string'指定欄位分隔符;
enclosed by 'char'指定所有欄位都使用char符號包圍,如果指定了optionally則只用在字串和日期資料型別等欄位上,預設未指定;
escaped by 'char'指定轉義符。
lines starting by 'string'指定行開始符,如每行開始記錄前空一個製表符;
lines terminated by 'string'為行分隔符。
預設:
fileds terminated by '\t' enclosed by '' escaped by '\\'
lines terminated by '\n' starting by ''

簡單使用例子:

select * from test into outfile '/data/t_data.sql';
select *  into outfile '/data/t_data.sql' from test;
select id,name from test into outfile '/data/t_data.sql';
select * from t into outfile '/data/t_data1.sql' fields terminated by ',' enclosed by '\'' lines starting by '\t' terminated by '\n';

3.3、邏輯備份的恢復

語法很簡單:

mysql -uroot -p123456 < all_bak.sql
mysql>source /root/all_bak.sql #登入mysql

3.4、load data infile

選項同select into outfile是一樣的,增加了gnore N lines|rows表示忽略前N行資料不匯入,set col_name=expr表示對列進行一些表示式運算

基本使用:

load data infile '/home/data1.sql' into table test.gxt fields terminated by ',' (id,name)set is_enable=1; #指定欄位
load data infile '/home/data1.sql' into table test.gxt fields terminated by ',' enclosed by '\'' escaped by '\\' lines starting by '\t' terminated by '\n';
load data infile '/home/data1.sql' into table test.gxt fields terminated by ',' enclosed by '\'' escaped by '\\' lines starting by '\t' terminated by '\n' ignore 2 rows; #忽略前兩行
load data infile '/home/data1.sql' into table test.gxt fields terminated by ',' enclosed by '\'' escaped by '\\' lines starting by '\t' terminated by '\n' set id=id+5; #設定列,下同
load data infile '/home/data1.sql' into table test.gxt fields terminated by ',' enclosed by '\'' escaped by '\\' lines starting by '\t' terminated by '\n' set name=concat(name,'@qq.com');
load data infile '/home/data1.sql' into table test.gxt fields terminated by ',' enclosed by '\'' escaped by '\\' lines starting by '\t' terminated by '\n' set name=concat(name,'@qq.com'), id=id+5;

3.5、mysqldump匯出

本質和select into outfile一樣

mysql -uroot -p123456 -e "select * from test.gxt" > a.txt #雖然這樣也可以匯出資料,但是是沒有格式的
mysqldump -uroot -p123456 --tab /data/test test gxt1 #這裡指定的目錄mysql使用者需要有寫許可權,還需要設定引數secure-file-priv=/data/test

 

 

 如上的匯出方式,既有表結構的定義,又有表資料的匯出。

         mysqldump的"--tab"選項同樣可以指定各種分隔符。如"--fields-terminated-by=...,--fields-enclosed-by=...,--fields-optionally-enclosed-by=...,--fields-escaped-by=..."。以下是指定欄位分隔符為","

3.6、mysqlimport匯入

mysqlimport本質上就是load data infile的命令介面,而且大多數的語法與之相似,不同的是mysqlimport可以同時匯入多張表,通過引數--user-thread併發匯入不同的檔案

簡單使用例子:

mysqlimport -uroot -p123456 --fields-terminated-by=',' test '/home/t.txt'
mysqlimport -uroot -p123456 --fields-terminated-by=',' --user-thread test '/home/t.txt' 'home/gxt1.txt'  #併發匯入兩個表

 

四、熱備

4.1、xtrabackup安裝

官網地址:https://www.percona.com/downloads/Percona-XtraBackup-LATEST/

1、配置yum源:yum installhttps://repo.percona.com/yum/percona-release-latest.noarch.rpm (推薦)

2、安裝:yum install percona-xtrabackup-24

本來裝了個最新版yum install percona-xtrabackup-80,但是。。。有點尷尬(版本8.0不支援mysql5.x),新版本已經沒有innobackupex這個工具了

安裝完成之後會生成如下工具:

[root@lgh3 ~]# rpm -ql percona-xtrabackup-24 | grep bin |xargs ls -l
lrwxrwxrwx 1 root root 10 Sep 10 05:33 /usr/bin/innobackupex -> xtrabackup
-rwxr-xr-x 1 root root 3846952 Jul 5 03:59 /usr/bin/xbcloud
-rwxr-xr-x 1 root root 3020 Jul 5 03:53 /usr/bin/xbcloud_osenv
-rwxr-xr-x 1 root root 3603744 Jul 5 03:59 /usr/bin/xbcrypt
-rwxr-xr-x 1 root root 3612192 Jul 5 03:59 /usr/bin/xbstream
-rwxr-xr-x 1 root root 21730616 Jul 5 03:59 /usr/bin/xtrabackup

xbcloud和xbcloud_osenv是xtrabackup新的高階特性:雲備份;
xbcrypt也是新的特性,加密備份集;
xbstream是xtrabackup的流資料功能,通過流資料功能,可將備份內容打包並傳給管道後的壓縮工具進行壓縮;
xtrabackup是主程式
innobackupex在以前是一個perl指令碼,會呼叫xtrabackup這個二進位制工具,從xtrabackup 2.3開始,該工具使用C語言進行了重寫,當前它是xtabackup二進位制工具的一個軟連線,但是實際的使用方法卻不同,並且在以後的版本中會刪除該工具

未完。。。

4.2、xtrabackup備份原理

4.3、xtrabackup工具

五、快照備份

&n