MySQL備份是咱們運維過程當中再正常不過的事情了,這裏總結一下之前備份的方法,使用的是xtrabackup,固然這裏的備份方法還有mysqldump這個是mysql本身的備份工具,不過它支持的比較簡單,僅支持全量+binlog進行恢復,對於數據量大的企業,你總不能每週兩三次的全量備份+二進制日誌作時間點還原吧,顯然這裏咱們須要增量備份的支持;mysql
簡單說一下全量,增量,二進制日誌分別的意思:sql
好比A數據庫 週一這天數據一共10g 週二這天數據一共12g
全量:也就是對週一這天數據庫當前的10g數據,進行所有備份,也叫完整備份,但數據比較大恢復比較慢數據庫
增量:增量也就是週二這天數據一共12g,和上次差別相比+2g數據,因爲咱們昨天作了一次全量備份,今天只須要備份今天的2g就能夠了(mysqldump不能這樣,他只能昨天10g,今天再備個12g)緩存
注:差別和增量概念有點模糊,能夠自行百科安全
二進制日誌:用於記錄引發數據改變或存在引發數據改變的潛在可能性的語句(STATEMENT)或改變後的結果(ROW),也多是兩者混合;bash
(也就是說你的但凡可以引發數據變化的增刪改都會在這有記錄,咱們通常作時間點還原用,由於好比你晚上2點剛增量完成,3點時候後數據庫崩潰了,那麼2點到3點之間咱們是沒有任何備份策略的,好在數據庫的變化都在二進制中有記錄,咱們能夠將二進制日誌中2-3點的記錄提取出來,當作備份使用)服務器
在數據庫日誌中,分爲6類(*表示重點,建議開啓):session
查詢日誌:general_log 記錄信息: 記錄查詢語句,日誌存儲位置: 文件:file 表:table (mysql.general_log) 打開方法: general_log={ON|OFF} general_log_file=HOSTNAME.log log_output={FILE|TABLE|NONE} *慢查詢日誌:log_slow_queries 慢查詢:運行時間超出指定時長的查詢; long_query_time 存儲位置: 文件:FILE 表:TABLE,mysql.slog_log log_slow_queries={ON|OFF} slow_query_log={ON|OFF} slow_query_log_file= log_output={FILE|TABLE|NONE} log_slow_filter=admin,filesort,filesort_on_disk,full_join,full_scan,query_cache,query_cache_miss,tmp_table,tmp_table_on_disk log_slow_rate_limit log_slow_verbosity *錯誤日誌:log_error, log_warnings 記錄信息: (1) mysqld啓動和關閉過程 輸出的信息; (2) mysqld運行中產生的錯誤信息; (3) event scheduler運行時產生的信息; (4) 主從複製架構中,從服務器複製線程啓動時產生的日誌; 打開方法: log_error=/var/log/mariadb/mariadb.log|OFF log_warnings={ON|OFF} *二進制日誌:binlog 但凡可以引發數據變化的增刪改都會在這 打開方法: log_bin=/PATH/TO/BIN_LOG_FILE 只讀變量; session.sql_log_bin={ON|OFF} 控制某會話中的「寫」操做語句是否會被記錄於binlog日誌文件中; max_binlog_size=1073741824 單位爲字節,這裏爲1G,binlog單個最大 sync_binlog={1|0} 控制數據庫的binlog刷到磁盤上去,1是每次事務提交,MySQL都會把binlog刷下到磁盤,是最安全可是性能損耗最大的設置,0是由文件系統本身控制它的緩存的刷新。這時候的性能是最好的,可是風險也是最大的。由於一旦系統Crash,在binlog_cache中的全部binlog信息都會被丟失爲,0和設置爲1的系統寫入性能差距可能高達5倍甚至更多。 中繼日誌:relay_log 從服務器上記錄下來從主服務器的二進制日誌文件同步過來的事件,主從模式纔會用到; 事務日誌:innodb_log innodb事務日誌包括redo log和undo log。 redo log是重作日誌,提供前滾操做, undo log是回滾日誌,提供回滾操做。
備份時應該注意事項: 能容忍最多丟失多少數據; 恢復數據須要在多長時間內完成; 須要恢復哪些數據; 備份須要考慮因素: 鎖定資源多長時間? 備份過程的時長? 備份時的服務器負載? 恢復過程的時長?
上面是一些簡單的敘述,這裏也捎帶着提一下mysqldump的備份參數,但不作細細分析架構
mysqldump: mysqldump是一個單進程的備份工具,同一時刻內只能備份一個表 mysqldump的備份原理是查詢當前要備份的數據庫表的全部數據,所有轉換成插入語句 不一樣的引擎備份參數: MyISAM存儲引擎:支持溫備,備份時要鎖定表; -x, --lock-all-tables:鎖定全部庫的全部表,讀鎖; -l, --lock-tables:鎖定指定庫全部表; InnoDB存儲引擎:支持溫備和熱備; --single-transaction:建立一個事務,基於此快照執行備份; 其它選項(建議必選): -R, --routines:存儲過程和存儲函數; --triggers 觸發器 -E, --events 事件 --master-data[=#] 1:記錄爲CHANGE MASTER TO語句,此語句不被註釋; 2:記錄爲CHANGE MASTER TO語句,此語句被註釋;用於查看下次binlog恢復時,應基於哪一個位置開始恢復 --flush-logs:備份時鎖定表完成後,即進行日誌新文件滾動刷新;方便binlog恢復時,咱們基於上次備份sql和一個新的binlog文件恢復
mysqldump的備份示例:app
備份hellodb數據庫,myisam引擎,因爲不支持事務和表空間序列號,只能溫備(只讀不能寫)或冷備 MyISAM: 備份hellodb庫中的new表: mysqldump -uroot -proot -R -E --triggers --master-data=2 --flush-logs -l hellodb new > /data1/hellodb-fullback-$(%data +%F).sql ##表恢復時,若原始庫不存在,不會自動建立庫,須要本身先建立庫 備份一個庫: mysqldump -uroot -proot -R -E --triggers --master-data=2 --flush-logs -l hellodb > /data1/hellodb-fullback-$(%data +%F).sql 備份全部庫: mysqldump -uroot -proot -R -E --triggers --master-data=2 --flush-logs -x --all-databases > /data1/alldb-fullback-$(%data +%F).sql 備份hellodb數據庫,INNODB引擎,支持事務和表空間序列號,這裏作熱備(熱備的選擇根據是否會影響當前業務,由於會對服務器形成負載,對業務影響先評估)MyISAM的參數-x/-l仍然支持 InnoDB: 備份hellodb庫中的new表: mysqldump -uroot -proot -R -E --triggers --master-data=2 --flush-logs --single-transaction hellodb new > /data1/hellodb-fullback-$(%data +%F).sql 備份一個庫: mysqldump -uroot -proot -R -E --triggers --master-data=2 --flush-logs --single-transaction hellodb > /data1/hellodb-fullback-$(%data +%F).sql 備份全部庫: mysqldump -uroot -proot -R -E --triggers --master-data=2 --flush-logs --single-transaction --all-databases > /data1/alldb-fullback-$(%data +%F).sql 還原數據時: 進入mysql先關閉binlog的記錄:set @@session.sql_log_bin=OFF; 當還原完成時應及時立刻作一次全量備份,若業務緊急上線,也應作熱備全備 binlog恢復: mysqlbinlog master-01.00005 > binlog.sql
Xtrabackup是一個對InnoDB作數據備份的工具,支持在線熱備份(備份時不影響數據讀寫),是商業備份工具InnoDB Hotbackup的一個很好的替代品。
默認安裝xtrabackup會有innobackupex命令和xtrabackup,咱們通常使用innobackupex,但其實innobackupex也是軟鏈接的xtrabackup
軟件包提供:連接:https://pan.baidu.com/s/1Ay42kAecCgJhyqAClKM0CA 密碼:w7fe
或者去官網下載最新版:https://www.percona.com/
完整備份:
innobackupex --defaults-file=/etc/my.cnf --user=root --password=root ~/ ##完整備份 MariaDB [(none)]> INSERT INTO hellodb.students values (26,'ifan',19,'M',6,1); ##插入數據
模擬故障:
systemctl stop mariadb cp /var/lib/mysql/DB-bin.* /data/ rm -rf /var/lib/mysql/*
數據恢復:
cd 2019-03-05_22-22-19/ ##進入全備 innobackupex --apply-log ./ ##因爲這是全備沒有差別備份和增量備份,因此不考慮未完成的事務,進行合併lsn,並回滾未完成事務 innobackupex --copy-back ./ ##lsn合併和事務回滾後,進行還原數據 chown -R mysql.mysql /var/lib/mysql ##從新設置屬主屬組權限 systemctl start mariadb ##啓動數據庫便可
根據binlog增量恢復:
[root@localhost 2019-03-05_22-22-19]# cat xtrabackup_binlog_info ##查看全備完成的位置 DB-bin.000003 9116 [root@localhost 2019-03-05_22-22-19]# mysqlbinlog -j 9116 /data/DB-bin.000003 > binlog.sql [root@localhost 2019-03-05_22-22-19]# mysql -uroot -proot MariaDB [(none)]> set @@session.sql_log_bin=OFF; MariaDB [(none)]> source binlog.sql ##還原binlog.sql,恢復第26條內容 MariaDB [(none)]> select * from hellodb.students; +-------+---------------+-----+--------+---------+-----------+ | StuID | Name | Age | Gender | ClassID | TeacherID | +-------+---------------+-----+--------+---------+-----------+ | 1 | Shi Zhongyu | 22 | M | 2 | 3 | | 2 | Shi Potian | 22 | M | 1 | 7 | ......... | 24 | Xu Xian | 27 | M | NULL | NULL | | 25 | Sun Dasheng | 100 | M | NULL | NULL | | 26 | ifan | 19 | M | 6 | 1 | +-------+---------------+-----+--------+---------+-----------+ 26 rows in set (0.00 sec) [root@localhost ~]# innobackupex --defaults-file=/etc/my.cnf --user=root --password=root ~/ ##還原完成後,立刻基於本次當即作全備 [root@localhost ~]# ls 2019-03-05_23-19-54
咱們先作一次全量備份: [root@localhost ~]# innobackupex --defaults-file=/etc/my.cnf --user=root --password=root ~/ [root@localhost ~]# ls 2019-03-06_00-04-44 刪除一部分數據 [root@localhost ~]# mysql -uroot -proot MariaDB [hellodb]> delete from students where StuID='10'; Query OK, 1 row affected (0.00 sec) [root@localhost ~]# innobackupex --defaults-file=/etc/my.cnf --user=root --password=root --incremental ~/ --incremental-basedir=~/2019-03-06_00-04-44/ ##進行增量備份 [root@localhost ~]# ls 2019-03-06_00-04-44 2019-03-06_00-09-25 查看全量的xtrabackup_checkpoints文件記錄的lsn值: [root@localhost ~]# cat 2019-03-06_00-04-44/xtrabackup_checkpoints backup_type = full-backuped ##全量備份 from_lsn = 0 ##因爲我這個是新還原的數據庫,因此起始位置爲0 to_lsn = 1634678 last_lsn = 1634678 compact = 0 recover_binlog_info = 0 [root@localhost ~]# cat 2019-03-06_00-09-25/xtrabackup_checkpoints backup_type = incremental ##增量備份 from_lsn = 1634678 ##增量備份的起始位置應該是繼承上次備份的位置 to_lsn = 1635829 ##這裏是本次備份的最後備份位置1635829,下次增量起始位置將緊接着這個位置 last_lsn = 1635829 compact = 0 recover_binlog_info = 0 緊接着咱們再刪除一個ID爲20的同窗,再作一次增量備份: MariaDB [(none)]> delete from hellodb.students where StuID='20'; Query OK, 1 row affected (0.00 sec) [root@localhost ~]# innobackupex --defaults-file=/etc/my.cnf --user=root --password=root --incremental ~/ --incremental-basedir=~/2019-03-06_00-09-25/ ##此次增量要基於上次增量的位置 [root@localhost ~]# ls 2019-03-06_00-04-44 2019-03-06_00-09-25 2019-03-06_00-16-41 ##查看新備份的增量的xtrabackup_checkpoints [root@localhost ~]# cat 2019-03-06_00-16-41/xtrabackup_checkpoints backup_type = incremental from_lsn = 1635829 ##這裏的起始位置是上次增量的位置以此類推 to_lsn = 1637002 last_lsn = 1637002 compact = 0 recover_binlog_info = 0 緊接着咱們再插入一個值,用binlog恢復: MariaDB [(none)]> INSERT INTO hellodb.students values (30,'xiaopingfan',19,'M',6,1); Query OK, 1 row affected (0.00 sec) 爲了咱們binlog恢復: 咱們要將最近一次增量備份最後的binlog位置找到,這樣咱們才能恢復最近一次增量到數據庫崩潰時之間的數據: 首先查看最近一次binlog備份的最後位置: [root@localhost ~]# cat 2019-03-06_00-16-41/xtrabackup_binlog_info DB-bin.000001 8132 [root@localhost ~]# cp /var/lib/mysql/DB-bin.000001 /root/ ##將這段二進制日誌備份出來 [root@localhost ~]# mysqlbinlog -j 8132 DB-bin.000001 > binlog.sql ##轉化成sql
開始恢復:
systemctl stop mariadb rm -rf /var/lib/mysql/* 這裏咱們一共產生一次全量備份和兩次增量備份,咱們要先將全量備份的事務合併(已完成的事務進行合併,未完成的事務不處理,等待後續的增量備份事務進行合併),而後將兩次增量(有順序)的備份進行依次合併到全量備份上,最後再合併一次全量備份(已完成的事務進行合併,未完成的事務因爲後續沒有了增量備份,未完成的事務就進行回滾,不能讓其生效) 記住,在合併的時候就像三堆土,既然要並在一次,確定是兩小堆依次合併在那一堆大的土堆上面 增量開始恢復: [root@localhost ~]# innobackupex --defaults-file=/etc/my.cnf --apply-log --redo-only 2019-03-06_00-04-44/ ##已完成的事務進行合併,未完成的事務不處理,等待後續的增量備份事務進行合併 [root@localhost ~]# innobackupex --defaults-file=/etc/my.cnf --apply-log --redo-only 2019-03-06_00-04-44/ --incremental-dir=2019-03-06_00-09-25/ ##將第一次增量合併到全量上 [root@localhost ~]# innobackupex --defaults-file=/etc/my.cnf --apply-log --redo-only 2019-03-06_00-04-44/ --incremental-dir=2019-03-06_00-16-41/ ##將第二次增量合併到全量上 [root@localhost ~]# innobackupex --defaults-file=/etc/my.cnf --apply-log 2019-03-06_00-04-44/ ##全部的增量恢復完,最後對全備已完成的事務進行合併,未完成的事務回滾 [root@localhost ~]# innobackupex --defaults-file=/etc/my.cnf --copy-back 2019-03-06_00-04-44/ [root@localhost ~]# chown -R mysql.mysql /var/lib/mysql [root@localhost ~]# systemctl start mariadb [root@localhost ~]# mysql -uroot -proot MariaDB [(none)]> set @@session.sql_log_bin=OFF; Query OK, 0 rows affected (0.00 sec) MariaDB [(none)]> show binary logs; +---------------+-----------+ | Log_name | File_size | +---------------+-----------+ | DB-bin.000001 | 245 | +---------------+-----------+ 1 row in set (0.00 sec) MariaDB [(none)]> source binlog.sql Query OK, 0 rows affected (0.00 sec) ... Query OK, 0 rows affected (0.00 sec) 查看xiaopingfan是否存在: MariaDB [(none)]> select * from hellodb.students; +-------+---------------+-----+--------+---------+-----------+ | StuID | Name | Age | Gender | ClassID | TeacherID | +-------+---------------+-----+--------+---------+-----------+ | 1 | Shi Zhongyu | 22 | M | 2 | 3 | | 2 | Shi Potian | 22 | M | 1 | 7 | | 3 | Xie Yanke | 53 | M | 2 | 16 | | 4 | Ding Dian | 32 | M | 4 | 4 | | 5 | Yu Yutong | 26 | M | 3 | 1 | | 6 | Shi Qing | 46 | M | 5 | NULL | | 7 | Xi Ren | 19 | F | 3 | NULL | | 8 | Lin Daiyu | 17 | F | 7 | NULL | | 9 | Ren Yingying | 20 | F | 6 | NULL | | 11 | Yuan Chengzhi | 23 | M | 6 | NULL | | 12 | Wen Qingqing | 19 | F | 1 | NULL | | 13 | Tian Boguang | 33 | M | 2 | NULL | | 14 | Lu Wushuang | 17 | F | 3 | NULL | | 15 | Duan Yu | 19 | M | 4 | NULL | | 16 | Xu Zhu | 21 | M | 1 | NULL | | 17 | Lin Chong | 25 | M | 4 | NULL | | 18 | Hua Rong | 23 | M | 7 | NULL | | 19 | Xue Baochai | 18 | F | 6 | NULL | | 21 | Huang Yueying | 22 | F | 6 | NULL | | 22 | Xiao Qiao | 20 | F | 1 | NULL | | 23 | Ma Chao | 23 | M | 4 | NULL | | 24 | Xu Xian | 27 | M | NULL | NULL | | 25 | Sun Dasheng | 100 | M | NULL | NULL | | 30 | xiaopingfan | 19 | M | 6 | 1 | +-------+---------------+-----+--------+---------+-----------+ 24 rows in set (0.00 sec) 數據恢復完成,立刻對這次回覆完成的數據庫作一次全量備份: [root@localhost ~]# innobackupex --defaults-file=/etc/my.cnf --user=root --password=root ~/ --apply-log ##分析獲取binary log文件生成backup_binlog_info文件 --redo-only ##只提交已完成事務 --copy-back ##還原數據庫
注:若是庫中有MyISAM引擎的表,庫中若是有innodb和myisam和innodb並存,xtrabackup方法下按照innodb備份便可,因爲innodb引擎的增量備份是基於LSN來實現的,myisam不支持事務和lsn因此對於myisam表每次都是全量備份,對於innodb表則是增量備份
查看數據庫內全部表引擎腳本:
#!/bin/bash myuser='root' mypass='root' myport=3306 base_list=`mysql -u${myuser} -p${mypass} -P${myport} -e "show databases;"|egrep -v 'mysql|Database|information_schema|performance_schema'` ##獲得庫列表 for k in ${base_list}; do table_list=`mysql -u${myuser} -p${mypass} -P${myport} -e "use ${k};show tables;"|egrep -v 'Tables_in'` ##獲得表列表 for g in ${table_list}; do ccmd=`mysql -u${myuser} -p${mypass} -P${myport} -e "show table status from ${k} where name='${g}'\G"|egrep -w Engine|awk -F ':' '{print $2}'` echo -e "數據庫:${k} 下 ${g}表的引擎爲: ${ccmd}" done done