MySQL數據庫備份與恢復


--------數據庫備份--------

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

  

 


免責聲明!

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



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