1. 程式人生 > >mysqldump工具實現mysql資料庫的備份還原

mysqldump工具實現mysql資料庫的備份還原

簡介

冷、溫、熱備份
冷備:讀寫操作均不可進行
溫備:讀操作可執行;但寫操作不可執行
熱備:讀寫操作均可執行
MyISAM:溫備,不支援熱備
InnoDB:都支援
不管是熱備還原還是冷備還原,還原時都需要停服務,禁止別人訪問

備份工具

mysqldump:邏輯備份工具,適用所有儲存引擎,溫備;支援完全或部分備份;對InnoDB儲存引擎支援熱備,結合binlog的增量備份
xtrabackup:由Percona提供支援對InnoDB做熱備(物理備份)的工具,支援完全備份、增量備份

mysqldump參考

https://dev.mysql.com/doc/refman/5.7/en/mysqldump.html

mysqldump通用選項用法

mysqldump需要通過mysql協議連線資料庫,所以需要資料的使用者名稱和密碼並且有一定的許可權
資料庫備份還原時,可以關閉二進位制日誌,還原資料庫的過程就是執行相關的sql語句

-B:可以備份多個數據庫或者備份某一個數據庫
-A:備份所有資料庫(排除information_schema和performance_schema這個兩個資料庫)
-E:備份相關的所有event scheduler事件排程(計劃任務)
-R:備份所有儲存過程和自定義函式(當有-A選項時,不用加此項)
--default-character-set=utf8:指定字符集
--master-data[=#]:此選項須啟用二進位制日誌(備份的時候記錄二進位制日誌的位置)
   當=1時:所備份的資料之前加一條記錄為CHANGE MASTER TO語句,非註釋,不指定#,預設為1(CHANGE MASTER TO用於主從複製)
   當=2時:有CHANGE MASTER TO語句,但是會被註釋掉;此選項會自動關閉--lock-tables功能,自動開啟-x | --lock-all-tables功能(除
           非開啟--single-transaction) 
-F:完成備份後生成新的二進位制日誌;配合-A或-B選項時,會導致重新整理多次資料庫。建議在同一時刻執行轉儲和日誌重新整理,可通過和--single-transaction或-x,
    --master-data一起使用實現,此時只重新整理一次日誌  
--compact:去掉註釋,適合除錯,生產不使用
-d:只備份表結構,不備份表資料
-t:只備份資料,不備份create table
-n:不備份create database,可被-A或-B覆蓋
--flush-privileges:備份mysql或相關時需要使用;重新整理許可權,讓許可權強制生效
-f:忽略SQL錯誤,繼續執行
--hex-blob:使用十六進位制符號轉儲二進位制列,當有包括BINARY,VARBINARY,BLOB,BIT的資料型別的列時使用,避免亂碼;備份時如果有二進位制資料,把二進位制轉
            換成十六進位制存放在文字中,避免造成資料破壞  
-q:不查詢快取,直接輸出,加快備份速度;mysqldump備份時是執行一條條的select命令,資料庫會預設以為是查詢資料庫,會走查詢快取
[root@centos7 ~]# mysqldump -B db2 |gzip > /data/mysql_`date +%F`.sql.gz   #備份預設只是在螢幕上列印,需要輸出到檔案中,備份檔案可以進行壓縮

mysqldump不同儲存引擎的不同選項用法

MyISAM備份選項:

支援溫備;不支援熱備,不支援事務,所以必須先鎖定要備份的庫,而後啟動備份操作鎖定方法如下:
-x:加全域性讀鎖,鎖定所有庫的所有表,同時加--singletransaction或--lock-tables選項會關閉此選項功能
-l:對於需要備份的每個資料庫,在啟動備份之前分別鎖定其所有表,預設為on,--skip-lock-tables選項可禁用,對備份MyISAM的多個庫,可能會造成資料不一致
注意:以上選項對InnoDB表一樣生效,實現溫備,但不推薦使用

InnoDB備份選項:

支援熱備,可用溫備但不建議用
--single-transaction:此選項Innodb中推薦使用,不適用MyISAM,此選項會開始備份前,先執行START TRANSACTION指令開啟事務;備份前開一個事務,以事務
                      的方式執行備份,配合可重複讀這個隔離級別(因為是可重複讀的隔離級別,所以在備份期間,雖然使用者有可能會更新資料,但系統備份的 
                      資料還是在使用者沒有更新資料時的樣子),以此保證備份在同一個時間點;事物可以撤銷一些DML語言(在開啟事務期間,別人對資料的更
                      新,事務會自動撤銷,保證資料還是在開始事務時的最初狀態),但撤銷不了DDL語言(drop、alter、create),隔離級別也一樣隔離不
                      了DDL語言,比如在別的事務中把表或者庫刪了,當前的事務中也看不到被刪除的表或者庫,所以要確保備份期間其他連線儘量不使用
                      DROP、RENAME、ALTER、TRUNCATE操作
                      此選項和--lock-tables(此選項隱含提交掛起的事務)選項是相互排斥
                      備份大型表時,建議將--single-transaction選項和--quick(-q)結合一起使用

InnoDB建議備份策略

mysqldump –uroot -pxxxx –A –F –E –R --single-transaction --master-data=1 --flush-privileges --triggers --default-character-set=utf8 --hex-blob > $BACKUP/fullbak_$BACKUP_TIME.sql       #-A包含了-E和-R,有-A可以不加-E、-R

MyISAM建議備份策略

mysqldump –uroot -pxxxx –A –F –E –R --single-transaction --master-data=1 --flush-privileges --triggers --default-character-set=utf8 --hex-blob > $BACKUP/fullbak_$BACKUP_TIME.sql

mysqldump選擇資料庫進行備份的簡單指令碼

方法一

[root@centos7 ~]# vim bakcup_database.sh    #一個數據庫做一個備份
#!/bin/bash
for db in `mysql -e 'show databases;'|egrep -v "^(Database|information_schema|performance_schema)$"`;do
   mysqldump -B $db | xz > /data/mysql-${db}-`date +%F`.sql.xz
done
[root@centos7 ~]# chmod +x  bakcup_database.sh
[root@centos7 ~]# ./bakcup_database.sh

方法二

[root@centos7 ~]# mysql -e 'show databases;'|egrep -v "^(Database|information_schema|performance_schema)$"|sed -rn "s#(.*)#myqsldump -B \1 | xz > /data/mysql-\1-`date +%F`.sql.xz#p"|bash      #sed是逐行進行處理的工具

增量備份

0表示週日,以此類推;週一在週日完全備份的基礎上做增量備份,相當於週一備份的是與週日資料發生變化的那部分資料;同理,週二備份的是與週一發生變化的資料;所以週一到週三的增量備份之前沒有對應關係;當週四發生資料庫故障,需要還原資料庫時,需要用到週日的完全備份和週一、二、三的增量備份,週三和週三之間的資料需要用二進位制日誌進行還原

差異備份

週日是完全備份,週一做與週日傳送資料變化的備份,週二的差異備份包含了週一的備份,週三的差異備份包含了週一、二的差異備份,所以差異備份是包含關係;當週四資料庫故障,需要備份還原時,需要用到週日的完全備份和週三的差異備份,週三和週四之間缺少的資料需要用二進位制日誌進行資料還原

實現mysqldump備份還原

備份

[root@centos7 ~]# mysql     #進入mysql
MariaDB [(none)]> create db3;    #建立庫
MariaDB [(none)]> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| db3                |
| mysql              |
| performance_schema |
+--------------------+
MariaDB [(none)]> use db3;
MariaDB [(none)]> create table t1(id int);      #建立表t1,表內容為空
[root@centos7 ~]# mysqldump -A -F --single-transaction --master-data=2 > /data/all.sql      #做完全備份並且記錄二進位制日誌位置
[root@centos7 ~]# mysql    #進入mysql
MariaDB [(none)]> use db3;
MariaDB [db3]> insert t1 value(1),(2),(3);    #往t1表裡面插入3條資料
MariaDB [db3]> drop table t1;    #刪除t1表,進行還原準備

還原

還原資料庫時,先停止mysql服務,防止別人訪問,避免產生資料衝突

[root@centos7 ~]# less /data/all.sql      #檢視完全備份
-- CHANGE MASTER TO MASTER_LOG_FILE='mariadb-bin.000001', MASTER_LOG_POS=411;   #找到這行,記錄了二進位制日誌的位置,411之前為做完的完全備份,411之後則是未做備份(二進位制日誌位置根據當時自身伺服器的二進位制日誌位置而定)
[root@centos7 ~]# mysqlbinlog --start-position=411 /var/lib/mysql/mariadb-bin.000001 > /data/logbin.sql   #從指定位置匯出二進位制日誌中的sql語句到一個.sql為字尾的檔案中(做二進位制日誌備份)
[root@centos7 ~]# vim /data/logbin.sql       #編輯匯出的檔案
DROP TABLE `t1` /* generated by server */   #找到刪除表的那一行,把這行必須刪除;用二進位制日誌備份還原資料庫必須刪除針對刪除表或者庫的sql語句,因為刪除表或庫的操作也會記錄到二進位制日誌中
[root@centos7 ~]# mysql   #進入mysql
MariaDB [(none)]> set sql_log_bin=off;     #臨時關閉二進位制日誌,避免還原過程產生大量的二進位制日誌
MariaDB [(none)]> use db3;
MariaDB [db3]> source /data/all.sql   #先還原完全備份;建立表是在完全備份前建立的,往表新增內容是在完全備份之後操作的,所以不能直接用二進位制日誌還原,二進位制日誌備份中沒有建立表的操作,需要配合完全備份
MariaDB [db3]> select * from t1;   #完全備份還原完表的內容是空的
Empty set (0.00 sec)
MariaDB [db3]> source /data/logbin.sql   #匯入二進位制日誌備份
MariaDB [db3]> select * from t1;  #匯入二進位制日誌備份之後,恢復
+------+
| id   |
+------+
|    1 |
|    2 |
|    3 |
+------+

備份還原完之後,恢復mysql服務訪