--------數據庫備份--------
1、數據備份的重要性
- 備份的主要目的是災難恢復
- 在生產環境中,數據的安全性至關重要
- 任何數據的丟失都可能產生嚴重的后果
造成數據丟失的原因:
- 程序錯誤
- 人為操作錯誤
- 運算錯誤
- 磁盤故障
- 不可控因素
2、從物理與邏輯的角度,備份分為:
- 物理備份: 對數據庫操作系統的物理文件(如數據文件、日志文件等)的備份
- 物理備份方法:
- 冷備份(脫機備份):是在關閉數據庫的時候進行的
- 熱備份(聯機備份):數據庫處於運行狀態,依賴於數據庫的日志文件
- 溫備份:數據庫鎖定表格(不可寫入但可讀)的狀態下進行備份操作
- 物理備份方法:
- 邏輯備份:對數據庫邏輯組件(如:表等數據庫對象)的備份
3、從數據庫的備份策略角度,備份可分為:
- 完全備份:每次對數據庫進行完整的備份
- 差異備份:備份自從上次完全備份之后被修改過的文件
- 增量備份:只有在上次完全備份或者增量備份后被修改的文件才會被備份
常見的備份方法
物理冷備
備份時數據庫處於關閉狀態,直接打包數據庫文件
備份速度快,恢復時也是最簡單的
專用備份工具mydump或mysqlhotcopy
myaqldump常用的邏輯備份工具
mysqlhotcopy僅擁有備份MyISM和ARCHIVE表
啟用二進制日志進行增量備份
進行增量備份,需要刷新二進制日志
第三方工具備份
免費MySQL熱備份軟件Percona XtraBackup
--------MySQL完全備份與恢復--------
完全備份的概念
是對整個數據庫,數據庫結構和文件結構的備份
保存的是備份完成時刻的數據庫
是差異備份與增量備份的基礎
優點
- 備份與恢復操作簡單方便
缺點
- 數據存在大量的重復
- 占用大量的備份空間
- 備份與恢復時間長
數據庫完全備份分類
物理冷備份與恢復
- 關閉MySQL數據庫
- 使用tar命令直接打包數據庫文件夾
- 直接替換現有MySQL目錄即可
mysqldump備份與恢復
- Mysql自帶的備份工具,可方便實現對MySQL的備份
- 可以將指定的庫、表導出為SQL腳本
- 使用命令mysql導入備份的數據
--------MySQL 完全備份--------
InnoDB存儲引擎的數據庫在磁盤上存儲成三個文件:
- db.opt(表屬性文件)
- 表名.frm(表結構文件)
- 表名.ibd(表數據文件)
1、物理冷備份與恢復
systemctl stop mysqld yum -y install xz cd /usr/local/mysql #壓縮備份 tar Jcvf /opt/mysql_all_$(date +%F).tar.xz /usr/local/mysql/data #解壓恢復 tar Jxvf /opt/mysql_all_2021-8-30.tar.xz /usr/local/mysql/data
2、mysqldump 備份與恢復
1)完全備份一個或多個完整的庫(包括其中所有的表)
mysqldump -u root -p[密碼] --databases 庫名1 [庫名2] … > /備份路徑/備份文件名.sql #導出的就是數據庫腳本文件
例:
mysqldump -u root -p --databases def > /opt/def.sql mysqldump -u root -p --databases mysql def > /opt/mysql-def.sql
2)完全備份 MySQL 服務器中所有的庫
mysqldump -u root -p[密碼] --all-databases > /備份路徑/備份文件名.sql
例:
mysqldump -u root -p --all-databases > /opt/all.sql
3)完全備份指定庫中的部分表
mysqldump -u root -p[密碼] 庫名 [表名1] [表名2] … > /備份路徑/備份文件名.sql
例:
mysqldump -u root -p [-d] def mysql > /opt/def_mysql.sql
#使用“-d”選項,說明只保存數據庫的表結構
#不使用“-d”選項,說明表數據也進行備份
4)查看備份文件
grep -v "^--" /opt/def_test1.sql | grep -v "^/" | grep -v "^$"
--------MySQL 完全恢復--------
systemctl start mysqld
1、恢復數據庫
mysql -u root -p -e 'drop database def;' #“-e”選項,用於指定連接 MySQL 后執行的命令,命令執行完后自動退出 mysql -u root -p -e 'SHOW DATABASES;' mysql -u root -p < /opt/def.sql mysql -u root -p -e 'SHOW DATABASES;'
2、恢復數據表
當備份文件中只包含表的備份,而不包含創建的庫的語句時,執行導入操作時必須指定庫名,且目標庫必須存在。
mysqldump -u root -p def test1 > /opt/def_test1.sql mysql -u root -p -e 'drop table def.test1;' mysql -u root -p -e 'show tables from def;' mysql -u root -p def < /opt/def_test1.sql mysql -u root -p -e 'show tables from def;'
--------MySQL增量備份與恢復--------
使用mysqldump進行完全備份存在的問題
備份數據中有重復數據
備份時間與恢復時間過長
增量備份的概念
是自上一次備份后增加/變化的文件或者內容
增量備份的特點
沒有重復數據,備份不大,時間短
恢復需要上次完全備份及完全備份之后所有的增量備份才能恢復,而且要對所有增備份進行逐個反推恢復
增量備份的方法
MySQL沒有提供直接的增量備份方法
可通過MySQL提供的二進制日志間接實現增量備份
MySQL二進制日志對備份的意義
二進制日志保存了所有更新或者可能更新數據庫的操作
二進制日志在啟動MySQL服務器后開始記錄,並在文件達到max_ binlog_ size所設 置的大小或者接收到flush logs命令后重新創建新的日志文件
只需定時執行flush logs方法重新創建新的日志,生成二進制文件序列,並及時把這些日志保存到安全的地方就完成了-一個時間段的增量備份
MySQL數據庫增量恢復
一般恢復
將所有備份的二進制日志內容全部恢復
基於位置恢復
數據庫在某一時間點可能既有錯誤的操作也有正確的操作
可以基於精准的位置跳過錯誤的操作
基於時間點恢復
跳過某個發生錯誤的時間點實現數據恢復
--------MySQL 增量備份--------
1、開啟二進制日志功能
vim /etc/my.cnf [mysqld] log-bin=mysql-bin binlog_format = MIXED 指定二進制日志(binlog)的記錄格式為 MIXED server-id = 1
#二進制日志(binlog)有3種不同的記錄格式:STATEMENT(基於SQL語句)、ROW(基於行)、MIXED(混合模式),默認格式是STATEMENT
#只要重啟服務就會生成二進制文件
systemctl restart mysqld ls -l /usr/local/mysql/data/mysql-bin.*
2、可每周對數據庫或表進行完全備份
mysqldump -u root -p def test1 > /opt/def_test1_$(date +%F).sql mysqldump -u root -p --all-databases> /opt/all_$(date +%F).sql
3、可每天進行增量備份操作,生成新的二進制日志文件(例如 mysql-bin.000002)
mysqladmin -u root -p flush-logs
4、插入新數據,以模擬數據的增加或變更
use def; insert into test1 values(4,'rose','female',23); insert into test1 values(5,'jack','male',26);
5、再次生成新的二進制日志文件(例如 mysql-bin.000003)
mysqladmin -u root -p flush-logs
#之前的步驟4的數據庫操作會保存到mysql-bin.000002文件中,之后數據庫數據再發生變化則保存在mysql-bin.000003文件中
6、查看二進制日志文件的內容
cp /usr/local/mysql/data/mysql-bin.000002 /opt/ mysqlbinlog --no-defaults --base64-output=decode-rows -v /opt/mysql-bin.000002
#--base64-output=decode-rows:使用64位編碼機制去解碼並按行讀取
#-v:顯示詳細內容
--------MySQL 增量恢復--------
1、一般恢復
1)模擬丟失更改的數據的恢復步驟
use def; delete from test01 where id=4; delete from test01 where id=5; mysqlbinlog --no-defaults /opt/mysql-bin.000005 | mysql -u root -p
2)模擬丟失所有數據的恢復步驟
use def; drop table test01; mysql -u root -p def < /opt/def_test1_2021-8-31.sql mysqlbinlog --no-defaults /opt/mysql-bin.000005| mysql -u root -p
2、斷點恢復
mysqlbinlog --no-defaults --base64-output=decode-rows -v /opt/mysql-bin.000009 #查看二進制日志文件
例:
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/; /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; DELIMITER /*!*/; # at 4 #210902 11:00:41 server id 1 end_log_pos 123 CRC32 0x4c5a25b0 Start: binlog v 4, server v 5.7.20-log created 210902 11:00:41 at startup ROLLBACK/*!*/; # at 123 #210902 11:00:41 server id 1 end_log_pos 154 CRC32 0xdec225a7 Previous-GTIDs # [empty] # at 154 #210902 11:02:51 server id 1 end_log_pos 219 CRC32 0x165d0c2a Anonymous_GTID last_committed=0 sequence_number=1 rbr_only=no SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/; # at 219 #210902 11:02:51 server id 1 end_log_pos 344 CRC32 0x39c1648b Query thread_id=3 exec_time=0 error_code=0 use `def`/*!*/; SET TIMESTAMP=1630551771/*!*/; SET @@session.pseudo_thread_id=3/*!*/; SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/; SET @@session.sql_mode=1437073414/*!*/; SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/; /*!\C utf8 *//*!*/; SET @@session.character_set_client=33,@@session.collation_connection=33,@@session.collation_server=33/*!*/; SET @@session.lc_time_names=0/*!*/; SET @@session.collation_database=DEFAULT/*!*/; create table Total_Sales (Name char(10),Sales int(5)) /*!*/; # at 344 #210902 11:03:41 server id 1 end_log_pos 409 CRC32 0x640746ee Anonymous_GTID last_committed=1 sequence_number=2 rbr_only=yes /*!50718 SET TRANSACTION ISOLATION LEVEL READ COMMITTED*//*!*/; SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/; # at 409 #210902 11:03:41 server id 1 end_log_pos 480 CRC32 0x1198d876 Query thread_id=3 exec_time=0 error_code=0 SET TIMESTAMP=1630551821/*!*/; BEGIN /*!*/;
(1)基於位置恢復
#僅恢復到操作 ID 為“219”之前的數據,即不恢復“219”的數據
mysqlbinlog --no-defaults --stop-position='219' /opt/mysql-bin.00002 | mysql -uroot -p
#僅恢復“344”的數據,跳過“219”的數據恢復
mysqlbinlog --no-defaults --start-position='219' /opt/mysql-bin.000002 | mysql -uroot -p
(2)基於時間點恢復
#僅恢復到 11∶03∶41 之前的數據,即不恢復“344”的數據
mysqlbinlog --no-defaults --stop-datetime='2021-09-02 11:03:41'/opt/mysql-bin.000002 |mysql -uroot -p
#僅恢復“11∶03∶41”的數據,跳過“219”的數據恢復
mysqlbinlog --no-defaults--start-datetime='2021-09-02 11:03:41' /opt/mysql-bin.000002 |mysql -uroot -p