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