MySQL 備份系列(1)-- 備份方案總結性梳理


 

mysql數據庫備份有多么重要已不需過多贅述了,廢話不多說!以下總結了mysql數據庫的幾種備份方案:

一、binlog二進制日志通常作為備份的重要資源,所以再說備份方案之前先總結一下binlog日志~~
1.binlog日志內容
1)引起mysql服務器改變的任何操作。
2)復制功能依賴於此日志。
3)slave服務器通過復制master服務器的二進制日志完成主從復制,在執行之前保存於中繼日志(relay log)中。
4)slave服務器通常可以關閉二進制日志以提升性能。

2.binlog日志文件的文件表現形式
1)默認在安裝目錄下,存在mysql-bin.00001, mysql-bin.00002的二進制文件(binlog日志文件名依據my.cnf配置中的log-bin參數后面的設置為准)
2)還有mysql-bin.index用來記錄被mysql管理的二進制文件列表
3)如果需要刪除二進制日志時,切勿直接刪除二進制文件,這樣會使得mysql管理混亂。

3.binlog日志文件查看相關mysql命令
1)SHOW MASTER STATUS ; 查看正在使用的二進制文件
MariaDB [(none)]> SHOW MASTER STATUS ;
+------------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000003 | 245 | | |
+------------------+----------+--------------+------------------+
2)FLUSH LOGS; 手動滾動二進制日志
MariaDB [(none)]> FLUSH LOGS;
MariaDB [(none)]> SHOW MASTER STATUS ;
+------------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000004 | 245 | | |
+------------------+----------+--------------+------------------+
滾動以后,mysql重新創建一個新的日志mysql-bin.000004
3)SHOW BINARY LOGS 顯示使用過的二進制日志文件
MariaDB [(none)]> SHOW BINARY LOGS ;
+------------------+-----------+
| Log_name | File_size |
+------------------+-----------+
| mysql-bin.000001 | 30373 |
| mysql-bin.000002 | 1038814 |
| mysql-bin.000003 | 288 |
| mysql-bin.000004 | 245 |
4)SHOW BINLOG EVENTS 以表的形式查看二進制文件
命令格式:SHOW BINLOG EVENTS [IN 'log_name'] [FROM pos] [LIMIT [offset,] row_count]
MariaDB [(none)]> SHOW BINLOG EVENTS IN 'mysql-bin.000001' \G;
*************************** 99. row ***************************
Log_name: mysql-bin.000001
Pos: 30225
Event_type: Query
Server_id: 1
End_log_pos: 30354
Info: use `mysql`; DROP TEMPORARY TABLE `tmp_proxies_priv` /* generated by server */

4.MySQL二進制文件讀取工具mysqlbinlog
命令格式:mysqlbinlog [參數] log-files
有以下四種參數選擇:
--start-datetime
--stop-datetime
--start-position
--stop-position
[root@test-huanqiu ~]# mysqlbinlog --start-position 30225 --stop-position 30254 mysql-bin.000001
截取一下結果:
# at 30225
#151130 12:43:35 server id 1 end_log_pos 30354 Querythread_id=1exec_time=0error_code=0
use `mysql`/*!*/;
SET TIMESTAMP=1448858615/*!*/;
SET @@session.pseudo_thread_id=1/*!*/

根據以上截取結果第二行,進行解釋二進制日志內容
1)時間點: 151130 12:43:35
2)服務器ID: server id 1
服務器ID主要用於標記日志產生的服務器,主要用於雙主模型中,互為主從,確保二進制文件不會被相互循環復制
3)記錄類型: Query
4) 線程號: thread_id = 1
5) 語句的時間戳和寫入二進制日志文件的時間差; exec_time=0
6) 事件內容
7)事件位置 #at 30225
8) 錯誤代碼 error_code=0
9) 事件結束位置 end_log_pos也就是下一事件開始的位置

5.二進制日志格式
由bin_log_format={statement|row|mixed}定義
1)statement: 基於語句,記錄生成數據的語句
缺點在於如果當時插入信息為函數生成,有可能不同時間點執行結果不一樣,
例如: INSERT INTO t1 VALUE (CURRENT_DATE());
2)row: 基於行數據
缺點在於,有時候數據量會過大
3)mixed: 混合模式,又mysql自行決定何時使用statement, 何時使用row 模式

6.二進制相關參數總結
1)log_bin = {ON|OFF}
還可以是個文件路徑,自定義binlog日志文件名使用“log_bin=“或“log-bin=“都可以,主要用於控制全局binlog的存放位置和是否開啟binlog日志功能。
比如:log_bin=mysql-bin 或者 log-bin=mysql-bin,這樣binlog日志默認會和mysql數據放在同一目錄下。
2) log_bin_trust_function_creators
是否記錄在
3) sql_log_bin = {ON|OFF}
會話級別是否關閉binlog, 如果關閉當前會話內的操作將不會記錄
4) sync_binlog 是否馬上同步事務類操作到二進制日志中
5) binlog_format = {statement|row|mixed} 二進制日志的格式,上面單獨提到了
6) max_binlog_cache_size =
二進制日志緩沖空間大小,僅用於緩沖事務類的語句;
7) max_binlog_stmt_cache_size =
語句緩沖,非事務類和事務類共用的空間大小
8) max_binlog_size =
二進制日志文件上限,超過上限后則滾動
9) 刪除二進制日志
命令格式:PURGE { BINARY | MASTER } LOGS { TO 'log_name' | BEFORE datetime_expr }
MariaDB> PURGE BINARY LOGS TO 'mysql-bin.010';
MariaDB> PURGE BINARY LOGS BEFORE '2016-11-02 22:46:26';
建議:切勿將二進制日志與數據文件放在一同設備;可以將binlog日志實時備份到遠程設備上,以防出現機器故障進行數據恢復;

二、接下來說下binlog二進制日志備份和恢復
1.為什么做備份:
(1)災難恢復
(2)審計,數據庫在過去某一個時間點是什么樣的
(3)測試

2.備份的目的:
(1)用於恢復數據
(2)備份結束后,需要周期性的做恢復測試

3.備份類型:
(1)根據備份時,服務器是否在線
1)冷備(cold backup): 服務器離線,讀寫操作都不能進行
2)溫備份: 全局施加共享鎖,只能讀不能寫
3)熱備(hot backup):數據庫在線,讀寫照樣進行
(2)根據備份時的數據集分類
1)完全備份(full backup)
2)部分備份(partial backup)
(3)根據備份時的接口
1)物理備份(physical backup):直接復制數據文件 ,打包歸檔
特點:
不需要額外工具,直接歸檔命令即可,但是跨平台能力比較差;如果數據量超過幾十個G,則適用於物理備份
2)邏輯備份(logical backup): 把數據抽取出來保存在sql腳本中
特點:
可以使用文本編輯器編輯;導入方便,直接讀取sql語句即可;邏輯備份恢復時間慢,占據空間大;無法保證浮點數的精度;恢復完數據庫后需要重建索引。
(4)根據備份整個數據還是變化數據
1) 全量備份 full backup
2) 增量備份 incremental backup
在不同時間點起始備份一段數據,比較節約空間;針對的是上一次備份后有變化的數據,備份數據少,備份快,恢復慢
3) 差異備份 differential backup
備份從每個時間點到上一次全部備份之間的數據,隨着時間增多二增多;比較容易恢復;對於很大的數據庫,可以考慮主從模型,備份從服務器的內容。針對的是上一次全量備份后有變化的數據,備份數據多,備份慢,恢復快。
(5)備份策略,需要考慮因素如下
備份方式
備份實踐
備份成本
鎖時間
時長
性能開銷
恢復成本
恢復時長
所能夠容忍丟失的數據量
(6)備份內容
1)數據庫中的數據
2)配置文件
3)mysql中的代碼: 存儲過程,存儲函數,觸發器
4)OS 相關的配置文件,chrontab 中的備份策略腳本
5)如果是主從復制的場景中: 跟復制相關的信息
6)二進制日志文件需要定期備份,一旦發現二進制文件出現問題,需馬上對數據進行完全備份

(7)Mysql最常用的三種備份工具:
1)mysqldump:
通常為小數據情況下的備份
innodb: 熱備,溫備
MyISAM, Aria: 溫備
單線程備份恢復比較慢
2)Xtrabackup(通常用innobackupex工具):
備份mysql大數據
InnoDB熱備,增量備份;
MyISAM溫備,不支持增量,只有完全備份
屬於物理備份,速度快;
3)lvm-snapshot:
接近於熱備的工具:因為要先請求全局鎖,而后創建快照,並在創建快照完成后釋放全局鎖;
使用cp、tar等工具進行物理備份;
備份和恢復速度較快;
很難實現增量備份,並且請求全局需要等待一段時間,在繁忙的服務器上尤其如此;


除此之外,還有其他的幾個備份工具:
-->mysqldumper: 多線程的mysqldump
-->SELECT clause INTO OUTFILE '/path/to/somefile' LOAD DATA INFILE '/path/from/somefile'
部分備份工具, 不會備份關系定義,僅備份表中的數據;
邏輯備份工具,快於mysqldump,因為不備份表格式信息
-->mysqlhotcopy: 接近冷備,基本沒用

 

mysqldump工具基本使用
1. mysqldump [OPTIONS] database [tables…]
還原時庫必須存在,不存在需要手動創建
    --all-databases: 備份所有庫
    --databases db1 db2 ...: 備份指定的多個庫,如果使用此命令,恢復時將不用手動創建庫。或者是-B db1 db2 db3 ....
    --lock-all-tables:請求鎖定所有表之后再備份,對MyISAM、InnoDB、Aria做溫備
    --lock-table: 對正在備份的表加鎖,但是不建議使用,如果其它表被修改,則備份后表與表之間將不同步
    --single-transaction: 能夠對InnoDB存儲引擎實現熱備;
啟動一個很大的大事物,基於MOCC可以保證在事物內的表版本一致
自動加鎖不需要,再加--lock-table, 可以實現熱備
備份代碼:
   --events: 備份事件調度器代碼
   --routines: 備份存儲過程和存儲函數
   --triggers:備份觸發器
備份時滾動日志:
   --flush-logs: 備份前、請求到鎖之后滾動日志;
方恢復備份時間點以后的內容
復制時的同步位置標記:主從架構中的,主服務器數據。效果相當於標記一個時間點。
   --master-data=[0|1|2]
   0: 不記錄
   1:記錄為CHANGE MASTER語句
   2:記錄為注釋的CHANGE MASTER語句

2. 使用mysqldump備份大體過程:
1) 請求鎖:--lock-all-tables或使用–singe-transaction進行innodb熱備;
2) 滾動日志:--flush-logs
3) 選定要備份的庫:--databases
4) 記錄二進制日志文件及位置:--master-data=
FLUSH TABLES5 WITH READ LOCK;

3. 恢復:
恢復過程無需寫到二進制日志中
建議:關閉二進制日志,關閉其它用戶連接;

4. 備份策略:基於mysqldump
備份:mysqldump+二進制日志文件;(“mysqldump >”)
周日做一次完全備份:備份的同時滾動日志
周一至周六:備份二進制日志;
恢復:(“mysql < ”)或在mysql數據庫中直接執行“source sql備份文件;”進行恢復。如果sql執行語句比較多,可以將sql語句放在一個文件內,將文件名命名為.sql結尾,然后在mysql數據庫中使用"source 文件.sql;"命令進行執行即可!
完全備份+各二進制日志文件中至此刻的事件

5. 實例說明:
參考:Mysql備份系列(2)--mysqldump備份(全量+增量)方案操作記錄

 

lvm-snapshot:基於LVM快照的備份
1.關於快照:
1)事務日志跟數據文件必須在同一個卷上;
2)剛剛創立的快照卷,里面沒有任何數據,所有數據均來源於原卷
3)一旦原卷數據發生修改,修改的數據將復制到快照卷中,此時訪問數據一部分來自於快照卷,一部分來自於原卷
4)當快照使用過程中,如果修改的數據量大於快照卷容量,則會導致快照卷崩潰。
5)快照卷本身不是備份,只是提供一個時間一致性的訪問目錄。

2.基於快照備份幾乎為熱備:
1)創建快照卷之前,要請求MySQL的全局鎖;在快照創建完成之后釋放鎖;
2)如果是Inoodb引擎, 當flush tables 后會有一部分保存在事務日志中,卻不在文件中。 因此恢復時候,需要事務日志和數據文件
但釋放鎖以后,事務日志的內容會同步數據文件中,因此備份內容並不絕對是鎖釋放時刻的內容,由於有些為完成的事務已經完成,但在備份數據中因為沒完成而回滾。 因此需要借助二進制日志往后走一段

3.基於快照備份注意事項:
1)事務日志跟數據文件必須在同一個卷上;
2)創建快照卷之前,要請求MySQL的全局鎖;在快照創建完成之后釋放鎖;
3)請求全局鎖完成之后,做一次日志滾動;做二進制日志文件及位置標記(手動進行);

4.為什么基於MySQL快照的備份很好?
原因如下幾點:
1)幾乎是熱備 在大多數情況下,可以在應用程序仍在運行的時候執行備份。無需關機,只需設置為只讀或者類似只讀的限制。
2)支持所有基於本地磁盤的存儲引擎 它支持MyISAM, Innodb, BDB,還支持 Solid, PrimeXT 和 Falcon。
3)快速備份 只需拷貝二進制格式的文件,在速度方面無以匹敵。
4)低開銷 只是文件拷貝,因此對服務器的開銷很細微。
5)容易保持完整性 想要壓縮備份文件嗎?把它們備份到磁帶上,FTP或者網絡備份軟件 -- 十分簡單,因為只需要拷貝文件即可。
6)快速恢復 恢復的時間和標准的MySQL崩潰恢復或數據拷貝回去那么快,甚至可能更快,將來會更快。
7)免費 無需額外的商業軟件,只需Innodb熱備工具來執行備份。

快照備份mysql的缺點:
1)需要兼容快照 -- 這是明顯的。
2)需要超級用戶(root) 在某些組織,DBA和系統管理員來自不同部門不同的人,因此權限各不一樣。
3)停工時間無法預計,這個方法通常指熱備,但是誰也無法預料到底是不是熱備 -- FLUSH TABLES WITH READ LOCK 可能會需要執行很長時間才能完成。
4)多卷上的數據問題 如果你把日志放在獨立的設備上或者你的數據庫分布在多個卷上,這就比較麻煩了,因為無法得到全部數據庫的一致性快照。不過有些系統可能能自動做到多卷快照。

5.備份與恢復的大體步驟
備份:
1)請求全局鎖,並滾動日志
mysql> FLUSH TABLES WITH READ LOCK;
mysql> FLUSH LOGS;
2)做二進制日志文件及位置標記(手動進行);
[root@test-huanqiu ~]# mysql -e 'show master status' > /path/to/orignal_volume
3)創建快照卷
[root@test-huanqiu ~]# lvcreate -L -s -n -p r /path/to/some_lv
4)釋放全局鎖
5)掛載快照卷並備份
6)備份完成之后,刪除快照卷

恢復:
1)二進制日志保存好;
提取備份之后的所有事件至某sql腳本中;
2)還原數據,修改權限及屬主屬組等,並啟動mysql
3)做即時點還原
4)生產環境下, 一次大型恢復后,需要馬上進行一次完全備份。

備份與恢復實例說明:
環境, 實現創建了一個test_vg卷組,里面有個mylv1用來裝mysql數據,掛載到/data/mysqldata

備份實例:
1. 創建備份專用的用戶,授予權限FLUSH LOGS 和 LOCK TABLES
MariaDB > GRANT RELOAD,LOCK TABLES,SUPER ON *.* TO 'lvm'@'192.168.1.%' IDENTIFIED BY 'lvm';
MariaDB > FLUSH PRIVILEGES;

2. 記錄備份點
[root@test-huanqiu ~]# mysql -ulvm -h192.168.1.10 -plvm -e 'SHOW MASTER STATUS' > /tmp/backup_point.txt

3. 創建快照卷並掛載快照卷
[root@test-huanqiu ~]# lvcreate -L 1G -s -n lvmbackup -p r /dev/test_vg/mylv1
[root@test-huanqiu ~]# mount -t ext4 /dev/test_vg/lvmbackup /mnt/

4. 釋放鎖
[root@test-huanqiu ~]# mysql -ulvm -h192.168.98.10 -plvm -e 'UNLOCK TABLES'
做一些模擬寫入工作
MariaDB [test]> create database testdb2

5. 復制文件
[root@test-huanqiu ~]# cp /data/mysqldata /tmp/backup_mysqldata -r

6. 備份完成卸載,刪除快照卷
[root@test-huanqiu ~]# umount /mnt
[root@test-huanqiu ~]# lvmremove /dev/test_vg/lvmbackup

還原實例:
假如整個mysql服務器崩潰,並且目錄全部被刪除

1. 數據文件復制回源目錄
[root@test-huanqiu ~]# cp -r /tmp/backup_mysqldata/* /data/mysqldata/
MariaDB [test]> show databases ;
+--------------------+
| Database |
+--------------------+
| information_schema |
| hellodb |
| mysql |
| mysqldata |
| openstack |
| performance_schema |
| test |
+--------------------+
此時還沒有testdb2, 因為這個是備份之后創建的,因此需要通過之前記錄的二進制日志

2. 查看之前記錄的記錄點。向后還原
[root@test-huanqiu ~]# cat /tmp/backup_point.txt
FilePositionBinlog_Do_DBBinlog_Ignore_DB
mysql-bin.000001245
[root@test-huanqiu ~]# mysqlbinlog /data/binlog/mysql-bin.000001 --start-position 245 > tmp.sql
MariaDB [test]> source /data/mysqldata/tmp.sql
MariaDB [test]> show databases ;
+--------------------+
| Database |
+--------------------+
| information_schema |
| hellodb |
| mysql |
| mysqldata |
| openstack |
| performance_schema |
| test |
| testdb2 |
+--------------------+
8 rows in set (0.00 sec)
testdb2 已經被還原回來。

具體實例說明,參考:Mysql備份系列(4)--lvm-snapshot備份mysql數據(全量+增量)操作記錄

 

使用Xtrabackup進行MySQL備份:

參考:Mysql備份系列(3)--innobackupex備份mysql大數據(全量+增量)操作記錄

 

--------------------------------------------------------------------------------------
關於備份和恢復的幾點經驗之談

備份注意:
1. 將數據和備份放在不同的磁盤設備上;異機或異地備份存儲較為理想;
2. 備份的數據應該周期性地進行還原測試;
3. 每次災難恢復后都應該立即做一次完全備份;
4. 針對不同規模或級別的數據量,要定制好備份策略;
5. 二進制日志應該跟數據文件在不同磁盤上,並周期性地備份好二進制日志文件;

從備份中恢復應該遵循步驟:
1. 停止MySQL服務器;
2. 記錄服務器的配置和文件權限;
3. 將數據從備份移到MySQL數據目錄;其執行方式依賴於工具;
4. 改變配置和文件權限;
5. 以限制訪問模式重啟服務器;mysqld的--skip-networking選項可跳過網絡功能;
方法:編輯my.cnf配置文件,添加如下項:
skip-networking
socket=/tmp/mysql-recovery.sock
6. 載入邏輯備份(如果有);而后檢查和重放二進制日志;
7. 檢查已經還原的數據;
8. 重新以完全訪問模式重啟服務器;
注釋前面第5步中在my.cnf中添加的選項,並重啟;


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM