1. 程式人生 > 其它 >|NO.Z.00071|——————————|BigDataEnd|——|Java&集合類庫.V07|----------------------------------------------|Java.v07|file類|file類|概念檔案操作|操作遍歷|以及子目錄遍歷|

|NO.Z.00071|——————————|BigDataEnd|——|Java&集合類庫.V07|----------------------------------------------|Java.v07|file類|file類|概念檔案操作|操作遍歷|以及子目錄遍歷|

MySQL資料庫備份與恢復

資料備份介紹

在生產環境中我們資料庫可能會遭遇各種各樣的不測從而導致資料丟失, 大概分為以下幾種.

  • 硬體故障

  • 軟體故障

  • 自然災害

  • 黑客攻擊

  • 誤操作 (佔比最大)

須知在生產環境中,伺服器的硬體壞了可以維修或者換新,軟體崩潰可以修復或重新安裝, 但是如果資料沒了那可就毀了,生產環境中最重要的應該就是資料了。所以, 為了在資料丟失之後能夠恢復資料, 我們就需要定期的備份資料。

備份什麼

一般情況下, 我們需要備份的資料分為以下幾種

  • 二進位制日誌, InnoDB事務日誌

  • 程式碼(儲存過程、儲存函式、觸發器、事件排程器)

  • 伺服器配置檔案

備份的型別

按照備份時資料庫的執行狀態,可以分為三種,分別是:冷備、溫備、熱備。、

  • 冷備:停庫、停服務來備份,即當資料庫進行備份時, 資料庫不能進行讀寫操作, 即資料庫要下線。

  • 溫備:不停庫、不停服務來備份,會(鎖表)阻止使用者的寫入,即當資料庫進行備份時, 資料庫的讀操作可以執行, 但是不能執行寫操作 。

  • 熱備:不停庫、不停服務來備份,也不會(鎖表)阻止使用者的寫入 即當資料庫進行備份時, 資料庫的讀寫操作均不是受影響 。

MySQL中進行不同型別的備份還要考慮儲存引擎是否支援?

儲存引擎 冷備 溫備 熱備
InnoDB 支援 支援 支援
MyISAM 支援 支援 不支援

邏輯備份與物理備份

按照備份的內容分,可以分為兩種,分別是邏輯備份與物理備份

  • 1、物理備份:直接將底層物理檔案備份
  • 2、邏輯備份:通過特定的工具從資料庫中匯出sql語句或者資料,可能會丟失資料精度

備份方式之全量、差異、增量

按照每次備份的資料量,可以分為全量備份、差異備份以及增量備份。

  • 全量備份/完全備份(Full Backup):備份整個資料集( 即整個資料庫 )

  • 部分備份:備份部分資料集(例如: 只備份一個表的變化)

    • 差異備份
      • 增量備份
 
# 1、差異備份(Differential Backup)
每次備份時,都是基於第一次完全備份的內容,只備份有差異的資料(新增的、修改的、刪除的),例如

第一次備份:完全備份
第二次備份:以當前時間節點的資料為基礎,備份與第一次備份內容的差異
第三次備份:以當前時間節點的資料為基礎,備份與第一次備份內容的差異
第四次備份:以當前時間節點的資料為基礎,備份與第一次備份內容的差異
第五次備份:以當前時間節點的資料為基礎,備份與第一次備份內容的差異
。。。

# 2、增量備份(Incremental Backup )
每次備份時,都是基於上一次備份的內容(注意是上一次,而不是第一次),只備份有差異的資料(新增的、修改的、刪除的),所以增量備份的結果是一條鏈,例如

第一次備份:完全備份
第二次備份:以當前時間節點的資料為基礎,備份與第一次備份內容的差異
第三次備份:以當前時間節點的資料為基礎,備份與第二次備份內容的差異
第四次備份:以當前時間節點的資料為基礎,備份與第三次備份內容的差異
第五次備份:以當前時間節點的資料為基礎,備份與第四次備份內容的差異
。。。

針對上述三種備份方案,如何恢復資料呢?

 
# 1、全量備份的資料恢復
只需找出指定時間點的那一個備份檔案即可,即只需要找到一個檔案即可

# 2、差異備份的資料恢復
需要先恢復第一次備份的結果,然後再恢復最近一次差異備份的結果,即需要找到兩個檔案

# 3、增量備份的資料恢復
需要先恢復第一次備份的結果,然後再依次恢復每次增量備份,直到恢復到當前位置,即需要找到一條備份鏈

綜上,對比三種備份方案
1、佔用空間:全量 > 差異 > 增量
2、恢復資料過程的複雜程度:增量 > 差異 > 全量

備份的工具

備份工具 備份速度 恢復速度 便捷性 適用儲存引擎 支援的備份型別 功能 應用場景
cp、tar等(物理) 一般 所有 冷備、全量、差異、增量 很弱 少量資料備份
lvm2快照(物理) 一般 所有 支援幾乎熱備(即差不多是熱備,哈哈),是藉助檔案系統管理工具進行的備份 一般 中小型資料量的備份
xtrabackup(物理) 較快 較快 是一款非常強大的熱備工具 由percona提供,只支援InnoDB/XtraDB 熱備、全量、差異、增量 強大 較大規模的備份
mysqldump(邏輯) 一般 所有 支援溫備、完全備份、部分備份、對於InnoDB儲存引擎支援熱備 一般 中小型資料量的備份

此外,如果考慮到增量備份,還需要結合binlog日誌(binlog只屬於增量恢復),需要用到工具mysqlbinlog,相當於邏輯備份的一種。

備份實戰

下面我們採用多種方法實戰MySQL資料備份實戰。

使用cp進行備份

 
mysql> FLUSH TABLES WITH READ LOCK; 
Query OK, 0 rows affected (0.00 sec)

[root@localhost ~]# mkdir /data
[root@localhost ~]# cp -a /usr/local/mysql-5.7.34/data/* /data/

模擬資料丟失

 
[root@localhost ~]# mv /usr/local/mysql-5.7.34/data .

資料恢復

 
[root@localhost ~]# mkdir /usr/local/mysql-5.7.34/data
[root@localhost ~]# chown mysql.mysql /usr/local/mysql-5.7.34/data
[root@localhost ~]# cp -a /data/* /usr/local/mysql-5.7.34/data/
[root@localhost ~]# systemctl restart mysqld
[root@localhost ~]# mysql -uroot -p123456
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.34-log Source distribution

Copyright (c) 2000, 2021, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> 

使用mysqldump

MySQL資料庫自帶的一個很好用的備份命令。是邏輯備份,匯出 的是SQL語句。也就是把資料MySQL庫中以邏輯的SQL語句的形式直接輸出或生成備份的檔案的過程。

語法

 
mysqldump  -h 伺服器  -u使用者名稱  -p密碼  選項與引數 > 備份檔案.sql

引數

引數 解釋
-A --all-databases 匯出全部資料庫
-Y --all-tablespaces 匯出全部表空間
--add-drop-database 每個資料庫建立之前新增drop資料庫語句。
--add-drop-table 每個資料表建立之前新增drop資料表語句。(預設為開啟狀態,使用--skip-add-drop-table取消選項)
--add-locks 在每個表匯出之前增加LOCK TABLES並且之後UNLOCK TABLE。(預設為開啟狀態,使用--skip-add-locks取消選項)
--comments 附加註釋資訊。預設為開啟,可以用--skip-comments取消
--compact 匯出更少的輸出資訊(用於除錯)。去掉註釋和頭尾等結構。可以使用選項:--skip-add-drop-table --skip-add-locks --skip-comments --skip-disable-keys
-c --complete-insert 使用完整的insert語句(包含列名稱)。這麼做能提高插入效率,但是可能會受到max_allowed_packet引數的影響而導致插入失敗。
-C --compress 在客戶端和伺服器之間啟用壓縮傳遞所有資訊
-B --databases 匯出幾個資料庫。引數後面所有名字參量都被看作資料庫名。
--debug 輸出debug資訊,用於除錯。
--debug-info 輸出除錯資訊並退出
--default-character-set 設定預設字符集,預設值為utf8
--delayed-insert 採用延時插入方式(INSERT DELAYED)匯出資料
-E --events 匯出事件。
--master-data 在備份檔案中寫入備份時的binlog檔案。值為1時,binlog檔名和位置沒有註釋,為2時,則在備份檔案中將binlog的檔名和位置進行註釋。
--flush-logs 開始匯出之前重新整理日誌。請注意:假如一次匯出多個數據庫(使用選項--databases或者--all-databases),將會逐個資料庫重新整理日誌。除使用--lock-all-tables或者--master-data外。在這種情況下,日誌將會被重新整理一次,相應的所以表同時被鎖定。因此,如果打算同時匯出和重新整理日誌應該使用--lock-all-tables 或者--master-data 和--flush-logs。
--flush-privileges 在匯出mysql資料庫之後,發出一條FLUSH PRIVILEGES 語句。為了正確恢復,該選項應該用於匯出mysql資料庫和依賴mysql資料庫資料的任何時候。
--force 在匯出過程中忽略出現的SQL錯誤。
-h --host 需要匯出的主機資訊
--ignore-table 不匯出指定表。指定忽略多個表時,需要重複多次,每次一個表。每個表必須同時指定資料庫和表名。例如:--ignore-table=database.table1 --ignore-table=database.table2 ……
-x --lock-all-tables 提交請求鎖定所有資料庫中的所有表,以保證資料的一致性。這是一個全域性讀鎖,並且自動關閉--single-transaction 和--lock-tables 選項。
-l --lock-tables 開始匯出前,鎖定所有表。用READ LOCAL鎖定表以允許MyISAM表並行插入。對於支援事務的表例如InnoDB和BDB,--single-transaction是一個更好的選擇,因為它根本不需要鎖定表。請注意當匯出多個數據庫時,--lock-tables分別為每個資料庫鎖定表。因此,該選項不能保證匯出檔案中的表在資料庫之間的邏輯一致性。不同資料庫表的匯出狀態可以完全不同。
--single-transaction 適合innodb事務資料庫的備份。保證備份的一致性,原理是設定本次會話的隔離級別為Repeatable read,來保證本次會話(也就是dump)時,不會看到其它會話已經提交了的資料。
-F 重新整理binlog,如果binlog打開了,-F引數會在備份時自動重新整理binlog進行切換。
-n --no-create-db 只匯出資料,而不新增CREATE DATABASE 語句。
-t --no-create-info 只匯出資料,而不新增CREATE TABLE 語句。
-d --no-data 不匯出任何資料,只匯出資料庫表結構。
-p --password 連線資料庫密碼
-P --port 連線資料庫埠號
-u --user 指定連線的使用者名稱。
-R 備份儲存過程和函式資料(如果開發寫了函式和儲存過程,就備,沒寫就不備)
--triggers 備份觸發器資料(現在都是開發寫觸發器)

案例

 
# 在命令列執行命令,進行全量備份
[root@localhost mysql]# mysqldump -uroot -p123456 -A -R --triggers --master-data=2 --single-transaction | gzip > /tmp/full.sql.gz
mysqldump: [Warning] Using a password on the command line interface can be insecure.
[root@localhost mysql]# ll /tmp/full.sql.gz 
-rw-r--r--. 1 root root 191963 Oct 14 00:01 /tmp/full.sql.gz

# 在命令列執行命令,重新整理binlog,便於日後查詢
[root@localhost mysql]# mysql -uroot -p123456 -e "flush logs"
mysql: [Warning] Using a password on the command line interface can be insecure.

# 登入資料庫,再插入一些資料,模擬增量,這些資料寫入了新的binlog
mysql> insert t1 values(4),(5),(6);
Query OK, 3 rows affected (0.01 sec)
Records: 3  Duplicates: 0  Warnings: 0


# 案例2:要求每天凌晨3點半的時候,做資料庫備份

1、編寫指令碼
[root@localhost ~]# cat mysqldump.sh 
#!/bin/bash

USERNAME=root
PASSWORD=123456
DATABASE=linux14

/usr/local/mysql/bin/mysqldump -u${USERNAME} -p${PASSWORD} -R --triggers -B ${DATABASE} --master-data=2 --single-transaction  | gzip > /tmp/MySQL_`date +"%F".sql.gz`


2、加入定時任務
30 03 * * *  /root/mysqldump.sh

模擬資料丟失

 
# 模擬資料丟失
mysql> drop database db1;

# 恢復資料
# 1、mysql資料匯入時,臨時關閉binlog,不要將恢復資料的寫操作也記入
mysql> set sql_log_bin=0;

# 2、先恢復全量
mysql> source /tmp/MySQL_2021-10-15.sql

如果是壓縮包呢,那就這麼做
mysql> system zcat /tmp/MySQL_2021-10-15.sql.gz | mysql -uroot -p123456

# 3、模擬恢復資料
mysql> drop database db01;
Query OK, 1 row affected (0.01 sec)

mysql> set sql_log_bin=0;
Query OK, 0 rows affected (0.00 sec)

mysql> system zcat /tmp/MySQL_2021-10-15.sql.gz | mysql -uroot -p123456
mysql: [Warning] Using a password on the command line interface can be insecure.
mysql> use db01;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> select * from t1;
+------+
| id   |
+------+
|    1 |
|    2 |
|    3 |
+------+
3 rows in set (0.00 sec)

測試線上熱備份

可以先準備一個儲存過程,一直保持寫入操作,然後驗證熱備。

 
#1. 準備庫與表
create database if not exists db01;
use db01;
create table s1(
  id int,
  name varchar(20),
  gender char(6),
  email varchar(50)
);

#2. 建立儲存過程,每隔3秒插入一條
delimiter $$
create procedure auto_insert1()
BEGIN
    declare i int default 1;
    while(i<3000000)do
        insert into s1 values(i,'shanhe','male',concat('shanhe',i,'@oldboy'));
     select concat('shanhe',i,'_ok') as name,sleep(3);
  set i=i+1;
    end while;
END$$
delimiter ;

#3. 檢視儲存過程
show create procedure auto_insert1\G 

備份

 
# 1、先開啟binlog日誌
mysql> SET sql_log_bin=ON; 
Query OK, 0 rows affected (0.00 sec)

# 2、登入資料庫,執行儲存過程
mysql> use db01;
mysql> call auto_insert1();

若想殺死儲存過程
mysql> show processlist; -- 查出id
mysql> kill id號;


# 3、在命令列執行下述命令,進行全量備份
[root@localhost mysql]# mysqldump -uroot -p123456  -A -R --triggers --master-data=2 --single-transaction | gzip > /tmp/full.sql.gz 
mysqldump: [Warning] Using a password on the command line interface can be insecure.

# 4、全量備份完畢後的一段時間裡,資料依然插入,寫入了mybinlog.000001中
#    然後我們在命令列重新整理binlog,產生了新的mybinlog.000002
[root@localhost mysql]# mysql -uroot -p123456 -e "flush logs"
mysql: [Warning] Using a password on the command line interface can be insecure.

# 5、此時資料依然在插入,但都寫入了最新的mybinlog.000002中,所以需要知道的是,增量的資料在mysqlbinlog.000001與mybinlog.000002中都有
我們登入資料庫,殺掉儲存過程,觀察到最新的資料插到了id=55的行
mysql> show processlist; -- 查出id
mysql> kill id號;

刪除資料

 
mysql> drop database db01;
Query OK, 1 row affected (0.12 sec)

恢復資料

 
# 登入資料庫,先恢復全量
mysql> set sql_log_bin=0;
mysql> system zcat /tmp/full.sql.gz | mysql -uroot -p123456
mysql: [Warning] Using a password on the command line interface can be insecure.

-- 檢視恢復到了id = 16
mysql> select * from db01.s1;
+------+--------+--------+-----------------+
| id   | name   | gender | email           |
+------+--------+--------+-----------------+
|    1 | shanhe | male   | shanhe1@oldboy  |
|    2 | shanhe | male   | shanhe2@oldboy  |
|    3 | shanhe | male   | shanhe3@oldboy  |
|    4 | shanhe | male   | shanhe4@oldboy  |
|    5 | shanhe | male   | shanhe5@oldboy  |
|    6 | shanhe | male   | shanhe6@oldboy  |
|    7 | shanhe | male   | shanhe7@oldboy  |
|    8 | shanhe | male   | shanhe8@oldboy  |
|    9 | shanhe | male   | shanhe9@oldboy  |
|   10 | shanhe | male   | shanhe10@oldboy |
|   11 | shanhe | male   | shanhe11@oldboy |
|   12 | shanhe | male   | shanhe12@oldboy |
|   13 | shanhe | male   | shanhe13@oldboy |
|   14 | shanhe | male   | shanhe14@oldboy |
|   15 | shanhe | male   | shanhe15@oldboy |
|   16 | shanhe | male   | shanhe16@oldboy |
+------+--------+--------+-----------------+
16 rows in set (0.00 sec)

物理備份之Xtrabackup

Xtrabackup 是一個對 InnoDB 做資料備份的工具,據官方介紹,這也是世界上惟一一款開源的能夠對innodb和xtradb資料庫進行熱備的工具;支援線上熱備份(備份時不影響資料讀寫),是商業備份工具 InnoDB Hotbackup 的一個很好的替代品。

官方文件:http://www.percona.com/doc/percona-xtrabackup/2.1/

Xtrabackup有兩個主要的工具:

    1. xtrabackup只能備份InnoDB和XtraDB兩種資料表,而不能備份MyISAM資料表。
    2. innobackupex 是參考了 InnoDB Hotbackup 的 innoback 指令碼修改而來的.innobackupex 是一個 perl 指令碼封裝,封裝了 xtrabackup。主要 是為了方便的同時備份InnoDB和MyISAM引擎的表,但在處理myisam時需要加一個讀鎖。並且加入了一些使用的選項。如slave-info可以記錄備份 恢復後,作為slave需要的一些資訊,根據這些資訊,可以很方便的利用備份來重做slave。

Xtrabackup可以做些做什麼?

線上(熱)備份整個庫的InnoDB、 XtraDB表 。

 
在xtrabackup的上一次整庫備份基礎上做增量備份(innodb only) ,以流的形式產生備份,可以直接儲存到遠端機器上(本機硬碟空間不足時很有用) 。

MySQL資料庫本身提供的工具並不支援真正的增量備份,二進位制日誌恢復是point-in-time(時間點)的恢復而不是增量備份。

Xtrabackup工具支援

對InnoDB儲存引擎的增量備份,工作原理如下:

    1. 首先完成一個完全備份,並記錄下此時檢查點的LSN(Log Sequence Number)。
    2. 在程序增量備份時,比較表空間中每個頁的LSN是否大於上次備份時的LSN,如果是,則備份該頁,同時記錄當前檢查點的LSN。

首先,在 logfile 中找到並記錄最後一個 checkpoint(“last checkpoint LSN”),然後開始從 LSN 的位置開始拷貝 InnoDB 的 logfile 到xtrabackup_logfile;接著,開始拷貝全部的資料檔案.ibd;在拷貝全部資料檔案結束之後,才停止拷貝logfile。 因為logfile裡面記錄全部的資料修改情況,所以,即時在備份過程中資料檔案被修改過了,恢復時仍然能夠通過解析xtrabackup_logfile保持資料的一致。

XtraBackup備份的優點

個人理解

    1. 無需停止資料庫進行InnoDB熱備,快速、可靠的完成備份
    2. 備份期間不間斷事務處理
    1. 節省磁碟空間和網路頻寬
    2. 自動對備份檔案進行驗證
    1. 快速恢復,保障線上執行時間永續性

官方說明

  1. 在不停庫的情況下,對InnoDB資料庫進行熱備
  2. 支援增量備份MySQL資料庫
  3. 通過流壓縮備份MySQL資料到另外一臺伺服器
  4. 線上MySQL伺服器之間進行表空間遷移

Xtrabackup的備份原理圖

  1. innobackupex啟動後,會先fork一個程序,用於啟動xtrabackup,然後等待xtrabackup備份ibd資料檔案

  2. xtrabackup在備份innoDB資料是,有2種執行緒:redo拷貝執行緒和ibd資料拷貝執行緒。xtrabackup程序開始執行後,會啟動一個redo拷貝的執行緒,用於從最新的checkpoint點開始順序拷貝redo.log

  3. 再啟動ibd資料拷貝執行緒,進行拷貝ibd資料。這裡是先啟動redo拷貝執行緒的。在此階段,innobackupex進行處於等待狀態(等待檔案被建立)

  4. xtrabackup拷貝完成ibd資料檔案後,會通知innobackupex(通過建立檔案),同時xtrabackup進入等待狀態(redo執行緒依舊在拷貝redo.log)

  5. innobackupex收到xtrabackup通知後哦,執行FLUSH TABLES WITH READ LOCK(FTWRL),取得一致性位點,然後開始備份非InnoDB檔案(如frm、MYD、MYI、CSV、opt、par等格式的檔案),在拷貝非InnoDB檔案的過程當中,資料庫處於全域性只讀狀態。

  6. 當innobackup拷貝完所有的非InnoDB檔案後,會通知xtrabackup,通知完成後,進入等待狀態

  7. xtrabackup收到innobackupex備份完成的通知後,會停止redo拷貝執行緒,然後通知innobackupex,redo.log檔案拷貝完成

  8. innobackupex收到redo.log備份完成後,就進行解鎖操作,執行:UNLOCK TABLES

  9. 最後innbackupex和xtrabackup程序各自釋放資源,寫備份元資料資訊等,innobackupex等xtrabackup子程序結束後退出。

Xtrabackup 安裝

mysql 5.7以下版本,可以採用percona xtrabackup 2.4版本。

mysql 8.0以上版本,可以採用percona xtrabackup 8.0版本,xtrabackup8.0也只支援mysql8.0以上的版本。

比如,接觸過一些金融行業,mysql版本還是多采用mysql 5.7,當然oracle官方對於mysql 8.0的開發支援力度日益加大,新功能新特性迭代不止。生產環境採用mysql 8.0的版本比例會日益增加。

下載地址:https://www.percona.com/downloads/

 
# 安裝方式一

# 安裝yum倉庫
[root@localhost ~]# yum install https://repo.percona.com/yum/percona-release-latest.noarch.rpm -y

# 安裝XtraBackup命令
[root@localhost ~]# yum install percona-xtrabackup-24 -y


# 安裝方式二
#下載epel源
[root@localhost ~]# wget -O /etc/yum.repos.d/epel.repo  https://mirrors.aliyun.com/repo/epel-7.repo

#安裝依賴
[root@localhost ~]# yum -y install perl perl-devel libaio libaio-devel perl-Time-HiRes perl-DBD-MySQL

#下載Xtrabackup
[root@localhost ~]# wget https://downloads.percona.com/downloads/Percona-XtraBackup-2.4/Percona-XtraBackup-2.4.24/binary/redhat/7/x86_64/percona-xtrabackup-24-2.4.24-1.el7.x86_64.rpm

# 安裝
[root@localhost ~]# yum localinstall -y percona-xtrabackup-24-2.4.24-1.el7.x86_64.rpm

安裝完後會生成命令

 
xtrabackup      以前使用該命令
innobackupex    現在使用該命令

innobackupex是xtrabackup的前端配置工具,使用innobackupex備份時, 會呼叫xtrabackup備份所有的InnoDB表, 複製所有關於表結構定義的相關檔案(.frm)、以及MyISAM、MERGE、CSV和ARCHIVE表的相關檔案, 同時還會備份觸發器和資料庫配置檔案資訊相關的檔案, 這些檔案會被儲存至一個以時間命名的目錄。

Xtrabackup 備份方式(物理備份)

 
1.對於非innodb表(比如myisam)是直接鎖表cp資料檔案,屬於一種溫備。

2.對於innodb的表(支援事務),不鎖表,cp資料頁最終以資料檔案方式儲存下來,並且把redo和undo一併備走,屬於熱備方式。

3.備份時讀取配置檔案/etc/my.cnf

Xtrabackup 引數說明

 
--host     								指定主機
--user     								指定使用者名稱
--password    						指定密碼
--port    								指定埠
--databases     					指定資料庫
--incremental    					建立增量備份
--incremental-basedir   	指定包含完全備份的目錄
--incremental-dir      		指定包含增量備份的目錄   
--apply-log        				對備份進行預處理操作。一般情況下,在備份完成後,資料尚且不能用於恢復操作,因為備份的資料中可能會包含尚未提交的事務或已經提交但尚未同步至資料檔案中的事務。因此,此時資料檔案仍處理不一致狀態。“準備”的主要作用正是通過回滾未提交的事務及同步已經提交的事務至資料檔案也使得資料檔案處於一致性狀態。
--redo-only      					不回滾未提交事務
--copy-back     					恢復備份目錄

Xtrabackup全量備份與恢復

使用innobackupex備份時,其會呼叫xtrabackup備份所有的InnoDB表,複製所有關於表結構定義的相關檔案(.frm)、以及MyISAM、MERGE、CSV和ARCHIVE表的相關檔案,同時還會備份觸發器和資料庫配置資訊相關的檔案,這些檔案會被儲存到一個以時間命名的目錄當中。

 
#1、建立備份目錄,會把mysql的datadir中的內容備份到改目錄中
[root@localhost ~]# mkdir /backup

#2、全備
#2.1 在本地執行下述命令,輸入登入資料的本地賬號與密碼
#2.2 指定備份目錄為/backup下的full目錄
[root@localhost ~]# innobackupex --user=root  --password=123456 /backup/full

#3、檢視:預設會在備份目錄下生成一個以時間戳命名的資料夾
[root@localhost ~]# cd /backup/full/
[root@localhost full]# ls
2021-10-14_22-39-02
[root@localhost full]# ls 2021-10-14_22-39-02 #備份目錄
。。。
[root@localhost full]# ls /var/lib/mysql # 資料目錄
。。。

# 4、去掉時間戳,讓備份資料直接放在備份目錄下
我們在寫備份指令碼和恢復指令碼,恢復的時候必須指定上一次備份的目錄,如果備份目錄帶著時間戳,該時間戳我們很難在指令碼中確定,無為了讓指令碼編寫更加方便,我們可以使用選項--no-timestamp去掉時間戳,讓備份內容直接放置於我們指定的目錄下(ps:金融公司喜歡每天全備,每小時增備,如果備份目錄帶著時間戳,看似合理,但確實會很讓頭疼)
[root@localhost full]# rm -rf 2021-10-14_22-39-02
[root@localhost backup]# innobackupex --user=root --password=123456 --no-timestamp /backup/full

[root@localhost backup]# ll /backup/full/
total 12340
-rw-r-----. 1 root root      487 Oct 14 22:42 backup-my.cnf
drwxr-x---. 2 root root       48 Oct 14 22:42 db01
drwxr-x---. 2 root root       48 Oct 14 22:42 db02
-rw-r-----. 1 root root      646 Oct 14 22:42 ib_buffer_pool
-rw-r-----. 1 root root 12582912 Oct 14 22:42 ibdata1
drwxr-x---. 2 root root     4096 Oct 14 22:42 mysql
drwxr-x---. 2 root root     8192 Oct 14 22:42 performance_schema
drwxr-x---. 2 root root     8192 Oct 14 22:42 sys
-rw-r-----. 1 root root       20 Oct 14 22:42 xtrabackup_binlog_info
-rw-r-----. 1 root root      135 Oct 14 22:42 xtrabackup_checkpoints
-rw-r-----. 1 root root      484 Oct 14 22:42 xtrabackup_info
-rw-r-----. 1 root root     2560 Oct 14 22:42 xtrabackup_logfile


# 如果要使用一個最小許可權的使用者進行備份,則可基於如下命令建立此類使用者:
mysql> CREATE USER 'bkpuser'@'localhost' IDENTIFIED BY '123456';  #建立使用者
mysql> REVOKE ALL PRIVILEGES,GRANT OPTION FROM 'bkpuser';  #回收此使用者所有許可權
mysql> GRANT RELOAD,LOCK TABLES,RELICATION CLIENT ON *.* TO 'bkpuser'@'localhost';  #授權重新整理、鎖定表、使用者檢視伺服器狀態
mysql> FLUSH PRIVILEGES;  #重新整理授權表

實戰

 
1、全量備份
[root@master backups]# innobackupex --user=root --password=123456 --host=127.0.0.1 /backups/  
#在master上進行全庫備份#語法解釋說明:
#--user=root 指定備份使用者
#--password=123456  指定備份使用者密碼
#--host  指定主機
#/backups  指定備份目錄

2、恢復
[root@slave tools]# innobackupex --apply-log /backups/2021-10-14_11-01-37/   #合併資料,使資料檔案處於一致性的狀態
[root@slave ~]# rm -rf /usr/local/mysql/data/  #在slave上刪除原有的資料
[root@slave ~]# vim /etc/my.cnf  #配置my.cnf的資料目錄路徑,否則會報錯,要和master一致
datadir=/usr/local/mysql/data
[root@slave ~]# innobackupex --copy-back /backups/2021-10-14_11-01-37/  #在slave上資料恢復
[root@slave ~]# ll /usr/local/mysql/data/  #slave上檢視資料目錄,可以看到資料已經恢復,但是屬主會有問題,需要進行修改,所以一般使用mysql的執行使用者進行恢復,否則需要進行修改屬主和屬組資訊
[root@slave ~]# chown -R mysql.mysql /usr/local/mysql/data/  #修改屬主屬組
[root@slave ~]# mysql -uroot -p -e "show databases;"  #檢視資料,是否恢復

總結全庫備份與恢復三步曲:

  1. innobackupex全量備份,並指定備份目錄路徑。

  2. 在恢復前,需要使用--apply-log引數先進行合併資料檔案,確保資料的一致性要求。

  3. 恢復時,直接使用--copy-back引數進行恢復,需要注意的是,在my.cnf中要指定資料檔案目錄的路徑。

Xtrabackup增量備份與恢復

使用innobackupex進行增量備份,每個InnoDB的頁面都會包含一個LSN資訊,每當相關的資料發生改變,相關的頁面的LSN就會自動增長。這正是InnoDB表可以進行增量備份的基礎,即innobackupex通過備份上次完全備份之後發生改變的頁面來實現。在進行增量備份時,首先要進行一次全量備份,第一次增量備份是基於全備的,之後的增量備份都是基於上一次的增量備份的,以此類推。

要實現第一次增量備份,可以使用下面的命令進行:

 
基於全量備份的增量備份與恢復,做一次增量備份(基於當前最新的全量備份)

--incremental    					建立增量備份
--incremental-basedir   	指定包含完全備份的目錄
--incremental-dir      		指定包含增量備份的目錄 



innobackupex --user=root --password=root --defaults-file=/etc/my.cnf --incremental /backups/ --incremental-basedir=/backups/2021-10-14_22-39-02

1. 準備基於全量
innobackupex --user=root --password=root --defaults-file=/etc/my.cnf --apply-log --redo-only /backups/2021-10-14_22-39-02

2. 準備基於增量
innobackupex --user=root --password=root --defaults-file=/etc/my.cnf --apply-log --redo-only /backups/2018-07-30_11-01-37 --incremental-dir=/backups/2021-10-14_22-39-02

3. 恢復
innobackupex --copy-back --defaults-file=/etc/my.cnf /opt/2021-10-14_22-39-02

需要注意的是,增量備份僅能應用於InnoDB或XtraDB表,對於MyISAM表而言,執行增量備份時其實進行的是完全備份。

案例

 
1、備份資料
[root@master backups]# innobackupex --user=root --password=123456 --host=127.0.0.1 /backups/   #全備資料
[root@master ~]# mysql -uroot -p  #在master上建立student庫並建立testtb表插入若干資料
Enter password: 
mysql> create database student;
Query OK, 1 row affected (0.03 sec)

mysql> use student;
Database changed
mysql> create table testtb(id int);
Query OK, 0 rows affected (0.07 sec)

mysql> insert into testtb values(1),(10),(99);
Query OK, 3 rows affected (0.04 sec)
Records: 3  Duplicates: 0  Warnings: 0

mysql> select * from testtb;
+------+
| id   |
+------+
|    1 |
|   10 |
|   99 |
+------+
3 rows in set (0.00 sec)

mysql> quit;



#使用innobackupex進行增量備份
[root@master backups]# innobackupex --user=root --password=123456 --host=127.0.0.1 --incremental /backups/ --incremental-basedir=/backups/2021-10-15_11-01-37/
[root@localhost 2021-10-15_17-10-01]# cat xtrabackup_info 
innodb_from_lsn = 0							# 備份開始的ID
innodb_to_lsn = 998385358				# 全量備份結束的ID
[root@localhost 2021-10-15_17-10-01]# cat /backup/full3/2021-10-15_17-14-04/xtrabackup_info 
innodb_from_lsn = 998385358		# 增量備份開始的ID
innodb_to_lsn = 998388146			# 增量備份結束的ID

2、增量備份後資料恢復演示
(1)模擬mysql故障,刪除資料目錄所有資料
[root@master ~]# /etc/init.d/mysqld stop  #模擬mysql故障,停止mysql
Shutting down MySQL.. SUCCESS! 
[root@master ~]# rm -rf /usr/local/mysql/data/*  #刪除資料目錄中的所有資料
(2)合併全備資料目錄,確保資料的一致性
[root@master ~]# innobackupex --apply-log --redo-only /backups/2021-10-15_11-01-37/
(3)將增量備份資料合併到全備資料目錄當中
[root@master ~]# innobackupex --apply-log --redo-only /backups/2021-10-15_11-01-37/ --incremental-dir=/backups/2021-10-15_13-51-47/
(4)恢復資料
[root@master ~]# innobackupex --copy-back /backups/2021-10-15_11-01-37/

[root@master ~]# chown -R mysql.mysql /usr/local/mysql/data  #更改資料的屬主屬組
[root@master ~]# /etc/init.d/mysqld start  #啟動mysql
Starting MySQL.Logging to '/usr/local/mysql/data/master.err'.
.. SUCCESS! 
[root@master ~]# mysql -uroot -p -e "show databases;"  #檢視資料是否恢復
Enter password: 
+--------------------+
| Database           |
+--------------------+
| information_schema |
| kim                |
| mysql              |
| performance_schema |
| repppp             |
| student            |
| wordpress          |
+--------------------+

總結

  1. 增量備份需要使用引數--incremental指定需要備份到哪個目錄,使用incremental-dir指定全備目錄。

  2. 進行資料備份時,需要使用引數--apply-log redo-only先合併全備資料目錄資料,確保全備資料目錄資料的一致性。

  3. 再將增量備份資料使用引數--incremental-dir合併到全備資料當中

  4. 最後通過最後的全備資料進行恢復資料。

注意:如果有多個增量備份,需要逐一合併到全備資料當中,再進行恢復。

資料的快速匯入與匯出

在公司中,如果運營或者產品手裡有幾千萬甚至幾億條資料,要求你將其匯入資料中,請問如何做?

如果你依據運營或產品交給你的資料檔案直接使用insert語句,一行一行地批量插入,那至少需要1-2天時間才能插入完畢,顯然是不可行的。

此時我們可以用LOAD DATA INFILE語句。LOAD DATA INFILE語句可以從一個文字檔案中,將資料以很高的速度讀入一個表中。MySQL官方文件也說明了,該方法比一次性插入一條資料效能快20倍。

此外,mysql也支援快速匯出語句SELECT INTO OUTFILE,使用MySQL的SELECT INTO OUTFILE 、LOAD DATA INFILE快速匯出匯入資料,12G的資料匯出用時3分鐘左右,匯入用時4分鐘左右(執行時間根據機器的配置會有所不同,不具有參考價值)。

快速匯入與匯出的語法

  • 快速匯出
 
語法:
SELECT... INTO OUTFILE 匯出文字檔案

要想匯出成功,需要設定安全目錄才行
vim /etc/my.cnf
[mysqld]
secure-file-priv=/tmp

示例:
SELECT * FROM db1.t1
    INTO OUTFILE '/tmp/db1_t1.txt'
    FIELDS TERMINATED BY ','      -- 定義欄位分隔符
    OPTIONALLY ENCLOSED BY '"'    -- 定義字串使用什麼符號括起來
    LINES TERMINATED BY '\n';     -- 定義換行符
  • 快速匯入
 
語法
LOAD DATA INFILE 匯入的文字檔案路徑

示例
mysql> DELETE FROM student1;
mysql> create table new_t1(表結構與檔案中資料保持一致);
mysql> LOAD DATA INFILE '/tmp/db1_t1.txt'
            INTO TABLE new_db.new_t1
            FIELDS TERMINATED BY ','
            OPTIONALLY ENCLOSED BY '"'
            LINES TERMINATED BY '\n';

資料庫遷移

資料庫遷移是我們經常可遇到的問題,對於少量的資料,遷移基本上不會有什麼問題。生產環境中,有以下情況需要做遷移工作:

  1. 磁碟空間不夠比如一些老專案,選用的機型並不一定適用於資料庫。隨著時間的推移,硬碟很有可能出現短缺。

  2. 業務出現瓶頸比如專案中採用單機承擔所有的讀寫業務,業務壓力增大,不堪重負。如果 IO 壓力在可接受的範圍,會採用讀寫分離方案。

  3. 機器出現瓶頸機器出現瓶頸主要在磁碟 IO 能力、記憶體、CPU,此時除了針對瓶頸做一些優化以外,選擇遷移是不錯的方案。

  4. 專案改造某些專案的資料庫存在跨機房的情況,可能會在不同機房中增加節點,或者把機器從一個機房遷移到另一個機房。再比如,不同業務共用同一臺伺服器,為了緩解伺服器壓力以及方便維護,也會做遷移。

附錄:引數

 
--compress:該選項表示壓縮innodb資料檔案的備份。
--compress-threads:該選項表示並行壓縮worker執行緒的數量。
--compress-chunk-size:該選項表示每個壓縮執行緒worker buffer的大小,單位是位元組,預設是64K。
--encrypt:該選項表示通過ENCRYPTION_ALGORITHM的演算法加密innodb資料檔案的備份,目前支援的演算法有ASE128,AES192,AES256。
--encrypt-threads:該選項表示並行加密的worker執行緒數量。
--encrypt-chunk-size:該選項表示每個加密執行緒worker buffer的大小,單位是位元組,預設是64K。
--encrypt-key:該選項使用合適長度加密key,因為會記錄到命令列,所以不推薦使用。
--encryption-key-file:該選項表示檔案必須是一個簡單二進位制或者文字檔案,加密key可通過以下命令列命令生成:openssl rand -base64 24。
--include:該選項表示使用正則表示式匹配表的名字[db.tb],要求為其指定匹配要備份的表的完整名稱,即databasename.tablename。
--user:該選項表示備份賬號。
--password:該選項表示備份的密碼。
--port:該選項表示備份資料庫的埠。
--host:該選項表示備份資料庫的地址。
--databases:該選項接受的引數為資料名,如果要指定多個數據庫,彼此間需要以空格隔開;如:"xtra_test dba_test",同時,在指定某資料庫時,也可以只指定其中的某張表。如:"mydatabase.mytable"。該選項對innodb引擎表無效,還是會備份所有innodb表。此外,此選項也可以接受一個檔案為引數,檔案中每一行為一個要備份的物件。
--tables-file:該選項表示指定含有表列表的檔案,格式為database.table,該選項直接傳給--tables-file。
--socket:該選項表示mysql.sock所在位置,以便備份程序登入mysql。
--no-timestamp:該選項可以表示不要建立一個時間戳目錄來儲存備份,指定到自己想要的備份資料夾。
--ibbackup:該選項指定了使用哪個xtrabackup二進位制程式。IBBACKUP-BINARY是執行percona xtrabackup的命令。這個選項適用於xtrbackup二進位制不在你是搜尋和工作目錄,如果指定了該選項,innoabackupex自動決定用的二進位制程式。
--slave-info:該選項表示對slave進行備份的時候使用,打印出master的名字和binlog pos,同樣將這些資訊以change master的命令寫入xtrabackup_slave_info檔案。可以通過基於這份備份啟動一個從庫。
--safe-slave-backup:該選項表示為保證一致性複製狀態,這個選項停止SQL執行緒並且等到show status中的slave_open_temp_tables為0的時候開始備份,如果沒有開啟臨時表,bakcup會立刻開始,否則SQL執行緒啟動或者關閉知道沒有開啟的臨時表。如果slave_open_temp_tables在--safe-slave-backup-timeount(預設300秒)秒之後不為0,從庫sql執行緒會在備份完成的時候重啟。
--rsync:該選項表示通過rsync工具優化本地傳輸,當指定這個選項,innobackupex使用rsync拷貝非Innodb檔案而替換cp,當有很多DB和表的時候會快很多,不能--stream一起使用。
--kill-long-queries-timeout:該選項表示從開始執行FLUSH TABLES WITH READ LOCK到kill掉阻塞它的這些查詢之間等待的秒數。預設值為0,不會kill任何查詢,使用這個選項xtrabackup需要有Process和super許可權。
--kill-long-query-type:該選項表示kill的型別,預設是all,可選select。
--ftwrl-wait-threshold:該選項表示檢測到長查詢,單位是秒,表示長查詢的閾值。
--ftwrl-wait-query-type:該選項表示獲得全域性鎖之前允許那種查詢完成,預設是ALL,可選update。
--galera-info:該選項表示生成了包含建立備份時候本地節點狀態的檔案xtrabackup_galera_info檔案,該選項只適用於備份PXC。
--stream:該選項表示流式備份的格式,backup完成之後以指定格式到STDOUT,目前只支援tar和xbstream。
--defaults-file:該選項指定了從哪個檔案讀取MySQL配置,必須放在命令列第一個選項的位置。
--defaults-extra-file:該選項指定了在標準defaults-file之前從哪個額外的檔案讀取MySQL配置,必須在命令列的第一個選項的位置。一般用於存備份使用者的使用者名稱和密碼的配置檔案。
----defaults-group:該選項表示從配置檔案讀取的組,innobakcupex多個例項部署時使用。
--no-lock:該選項表示關閉FTWRL的表鎖,只有在所有表都是Innodb表並且不關心backup的binlog pos點,如果有任何DDL語句正在執行或者非InnoDB正在更新時(包括mysql庫下的表),都不應該使用這個選項,後果是導致備份資料不一致,如果考慮備份因為獲得鎖失敗,可以考慮--safe-slave-backup立刻停止複製執行緒。
--tmpdir:該選項表示指定--stream的時候,指定臨時檔案存在哪裡,在streaming和拷貝到遠端server之前,事務日誌首先存在臨時檔案裡。在 使用引數stream=tar備份的時候,你的xtrabackup_logfile可能會臨時放在/tmp目錄下,如果你備份的時候併發寫入較大的話 xtrabackup_logfile可能會很大(5G+),很可能會撐滿你的/tmp目錄,可以通過引數--tmpdir指定目錄來解決這個問題。
--history:該選項表示percona server 的備份歷史記錄在percona_schema.xtrabackup_history表。
--incremental:該選項表示建立一個增量備份,需要指定--incremental-basedir。
--incremental-basedir:該選項表示接受了一個字串引數指定含有full backup的目錄為增量備份的base目錄,與--incremental同時使用。
--incremental-dir:該選項表示增量備份的目錄。
--incremental-force-scan:該選項表示建立一份增量備份時,強制掃描所有增量備份中的資料頁。
--incremental-lsn:該選項表示指定增量備份的LSN,與--incremental選項一起使用。
--incremental-history-name:該選項表示儲存在PERCONA_SCHEMA.xtrabackup_history基於增量備份的歷史記錄的名字。Percona Xtrabackup搜尋歷史表查詢最近(innodb_to_lsn)成功備份並且將to_lsn值作為增量備份啟動出事lsn.與innobackupex--incremental-history-uuid互斥。如果沒有檢測到有效的lsn,xtrabackup會返回error。
--incremental-history-uuid:該選項表示儲存在percona_schema.xtrabackup_history基於增量備份的特定歷史記錄的UUID。
--close-files:該選項表示關閉不再訪問的檔案控制代碼,當xtrabackup開啟表空間通常並不關閉檔案控制代碼目的是正確的處理DDL操作。如果表空間數量巨大,這是一種可以關閉不再訪問的檔案控制代碼的方法。使用該選項有風險,會有產生不一致備份的可能。
--compact:該選項表示建立一份沒有輔助索引的緊湊的備份。
--throttle:該選項表示每秒IO操作的次數,只作用於bakcup階段有效。apply-log和--copy-back不生效不要一起用。

--apply-log:該選項表示同xtrabackup的--prepare引數,一般情況下,在備份完成後,資料尚且不能用於恢復操作,因為備份的資料中可能會包含尚未提交的事務或已經提交但尚未同步至資料檔案中的事務。因此,此時資料 檔案仍處理不一致狀態。--apply-log的作用是通過回滾未提交的事務及同步已經提交的事務至資料檔案使資料檔案處於一致性狀態。
--use-memory:該選項表示和--apply-log選項一起使用,prepare 備份的時候,xtrabackup做crash recovery分配的記憶體大小,單位位元組。也可(1MB,1M,1G,1GB),推薦1G。
--defaults-file:該選項指定了從哪個檔案讀取MySQL配置,必須放在命令列第一個選項的位置。
--export:這個選項表示開啟可匯出單獨的表之後再匯入其他Mysql中。
--redo-only:這個選項在prepare base full backup,往其中merge增量備份(但不包括最後一個)時候使用。