二進制日誌文件
二進制日誌(bin_log)
二進制日誌文件是用來記錄所有用戶對數據庫的操作,即記錄用戶對數據庫操作的sql語句。當數據庫發生意外時,可以通過該日誌查看到用戶對數據庫的操作,在和數據庫備份配合使用,可以將損失最小化。
mysql啓用和查看二進制文件
- 二進制日誌的開啓
二進制日誌的開啓由 sql_log_bin 和 log_bin 一起來決定。sql_log_bin 決定了二進制日誌是否開啓;log_bin 決定了二進制日誌的存儲路徑。 只有當sql_log_bin=on 並且在/etc/my.cnf 中指定了log_bin 的路徑,二進制日誌記錄纔會開啓。如下圖所示: - 二進制日誌的查看
show binary logs 查看二進制日誌 show master logs 查看所有的二進制日誌 show master status 查看當前的二進制日誌
- 二進制日誌的預覽和導出
mysqlbinlog [ --start-position= 位置 --stop-positon=位置 ] mysql-log.000001 預覽指定位置的二進制日誌記錄 mysqlbinlog [ --start-position= 位置 --stop-positon=位置 ] mysql-log.000001 > a.sql 導出指定位置的二進制日誌記錄到 a.sql 中
基與LVM的熱備
lvm的熱備是通過利用lvm快照進行備份,即爲了保持系統的一致性,我們先做一個快照凍結當前系統狀態,這樣快照裏面的內容可暫時保持不變,系統本身繼續運行,通過備份快照來實現不中斷服務的的備份。
以下通過具體操作來展示LVM熱備的過程:
- 環境準備(創建基於lvm的數據庫)
我們需要搭建好數據庫,在這裏我們把數據庫做在邏輯捲上,並且指定了數據庫中的數據的存儲路徑以及開啓二進制日誌記錄。 還有準備了備份目錄(生產環境中,備份與數據是分開的),如下:
準備一個新的分區/dev/sda6pvcreate /dev/sda6 vgcreate vgdata /dev/sda6 lvcreate -L 5G -n lvdata vgdata lvcreate -L 3G -n lvlogbin vgdata mkfs.xfs /dev/vgdata/lvdata mkfs.xfs /dev/vgdata/lvlogbin mkdir -pv /mysql/{data,logbin} mount /dev/vgdata/lvdata /mysql/data mount /dev/vgdata/lvlogbin /mysql/logbin chown -R mysql.mysql /mysql vim /etc/my.cnf datadir=/mysql/data log_bin=/mysql/logbin systemctl start mariadb.service mysql < hellodb_innodb.sql
就緒環境如下:
- 備份
鎖定表flush tables with read lock;
切換日誌flush logs;
查看當前二進制日誌位置並記錄show master status;
創建lvm快照 (實際場景中,創建快照的過程在鎖表之後應迅速完成)lvcreate -n lvdata_snap -L 1G -s -p r /dev/vgdata/lvdata
解鎖unlock tables;
- 增加新數據
向表中隨意更改一些數據,來模擬現實中新產生的還未來得及備份的新數據,這裏我們向hellodb庫中的students表中添加一行新數據insert into hellodb.students values (26,'lishuyang',23,'m',null,null);
注:這條新增的數據只存在於日誌中,並不存在於備份中 - 掛載lvm快照
lvcreate -n lvdata_snap -L 1G -s -p r /dev/vgdata/lvdata
將快照數據拷貝到備份目錄中cp -a /mysql/lvmbackup/* /mysql/backup/
- 卸載並刪除快照
umount /mysql/lvmbackup lvremove /dev/vgdata/lvdata_snap
直到這一步,我們的備份就完全完成了,備份數據存放在了/mysql/back中
- 模擬崩潰
在這裏我們直接進行比較暴力的破壞,直接刪除庫數據rm /mysql/data/* -rf ls /mysql/data/
可以看到我們的數據庫丟失了全部數據 - 恢復
恢復備份數據cp -a /mysql/back/* /mysql/data/ ls data/
此時,我們已經將備份過數據完全恢復到數據庫中了,但是未被備份的新數據不在其中,我們後來新加的一條數據,現在的數據庫中是沒有的
接下來我們需要把最新的數據恢復,就要用到我們的二進制日誌的記錄,由上面的記錄我們知道,新數據在日誌mysql-bin.000005 245之後的記錄中,所以我們需要將日誌mysql-bin.000005 245之後的日誌記錄全部恢復
首先我們需要關閉遠程客戶訪問:vim /etc/my.cnf skip_networking systemctl restart mariadb.service 或 iptables -A INPUT -p tcp --dport 3306 -j DROP
查看全部日誌記錄
ls /mysql/logbin
恢復二進制日誌記錄的未備份的數據,mysqlbinlog --start-position=245 /mysql/logbin.000005 > /root/bin.sql mysql < /root/bin.sql
查看數據庫
可以看到我們後來的新數據也恢復回來,這樣我們整個基於lvm的熱備與恢復就完成了。
mysqldump的邏輯備份
mysqldump備份數據庫相比較lvm快照備份要更加簡單,方便,而且可以靈活的備份某個表,指定庫,當然也可以備份整個庫。
備份命令:
mysqldump [OPTIONS] database [tables] 備份指定的表
mysqldump [OPTIONS] -B DB1 [DB2 DB3.....] 備份指定的庫
mysqldump [OPTIONS] -A [OPTIONS] 備份所有的庫
在這裏,我們最基本需要了解五個選項
-A --all-databases 備份所有的數據庫,含create database
-B --database db_name...... 指定備份的數據庫,含create database語句
--F --flush-logs 備份前滾動日誌,鎖表完成後,執行flush logs命令,生成新的二進制日誌文件,配合-A或-B 選項時,會導致刷新多次數據庫。建議在同一時刻執行轉儲和日誌刷新,可通知和--single-transaction 或-x,--master-data 一起使用實現,此時只刷新一次日誌
--master-data[=1/2] 此選項須啓用二進制日誌 1:所備份的數據之前加一條CHANGE MASTER TO語句,非註釋,不指定#,默認爲1
--single-transaction 通過在單個事務中轉儲所有表來創建一致的快照。僅適用於存儲在支持多版本控制的存儲引擎中的表;轉儲不保證與其他存儲引擎保持一致。在進行事務轉儲時,要確保有效的轉儲文件(正確的表內容和二進制日誌的位置),沒有其他連接應該使用以下語句:ALTER TABLE,DROP TABLE,RENAME TABLE,TRUNCATE TABLE
綜合以上選項,備份所有數據庫操作:
musqldump -A -F --single-transaction --master-data=2 > /mysql/backup/fullbak_$(date +%F_%T)
備份數據的還原
mysql < /mysql/backup/fullbak_2018-10-11_+20\:00\:20
未備份的數據同上面的還原一樣,利用二進制日誌記錄進行還原。