MySQL系列之十二 備份與恢復

系列教程

MySQL系列之開篇 MySQL關系型數據庫基礎概念
MySQL系列之一 MariaDB-server安裝
MySQL系列之二 多實例配置
MySQL系列之三 基礎篇
MySQL系列之四 SQL語法
MySQL系列之五 視圖、存儲函數、存儲過程、觸發器
MySQL系列之六 用戶與授權
MySQL系列之七 MySQL存儲引擎
MySQL系列之八 MySQL服務器變量
MySQL系列之九 mysql查詢緩存及索引
MySQL系列之十 MySQL事務隔離實現並發控制
MySQL系列之十一 日志記錄
MySQL系列之十二 備份與恢復
MySQL系列之十三 MySQL的復制
MySQL系列之十四 MySQL的高可用實現
MySQL系列之十五 MySQL常用配置和性能壓力測試

一、備份策略贅述

1、備份的類型

類型1:

  • 熱備份:讀寫不受影響(MyISAM不支持熱備,InnoDB支持熱備)
  • 溫備份:僅可以執行讀操作
  • 冷備份:離線備份,讀寫操作均中止

類型2:

  • 物理備份:復制數據文件進行備份,占用較多的空間,速度快
  • 邏輯備份:將數據導出至文本文件中,占用空間少,速度慢,可能丟失精度

類型3:

  • 完全備份:備份全部數據
  • 增量備份:僅備份上次完全備份或增量備份以後變化的數據,備份較快,還原復雜
  • 差異備份:僅備份上次完全備份以來變化的數據,備份較慢,還原簡單

2、備份需要考慮的因素

  • 溫備的持鎖多久,在鎖狀態的情況下無法寫入數據
  • 備份產生的負載,要調空閑的時間備份
  • 備份過程的時長,數據量大的時候時間會很長,要選擇合適的方案
  • 恢復過程的時長,備份數據需要即時測試

3、備份的目標

  • 數據庫數據,每個表空間單獨存放
  • 二進制日志,需要和數據分開存儲
  • InnoDB的事務日志
  • 存儲過程、存儲函數、觸發器或事件調度器等
  • 服務器的配置文件:/etc/my.cnf

4、備份工具

  • mysqldump工具:邏輯備份工具,適用所有存儲引擎溫備;支持完全或部分備份;對InnoDB存儲引擎支持熱備;Schema(數據庫的定義)和數據存儲在一起。
用法:
           shell> mysqldump [options] db_name [tbl_name ...]
           shell> mysqldump [options] --databases db_name ...
           shell> mysqldump [options] --all-databases
選項:
	-A:備份所有庫
	-B db_name1,[db_name2,...]:備份指定庫
	-E:備份相關的所有event scheduler
	-R:備份所有存儲過程和存儲函數
	--triggers:備份表相關觸發器,默認啟用,用--skip-triggers,不備份觸發器
	--master-data={1|2}:
		 1:所備份的數據之前加一條記錄為CHANGE MASTER TO語句,非註釋,不指定默認為1
		 2:記錄為註釋的CHANGE MASTER TO語句,註意:此選項會自動關閉--lock-tables功能,自動打開--lock-all-tables功能(除非開啟--single-transaction)
	-F:備份前滾動日志,鎖定表完成後,執行flush logs命令,生成新的二進制日志文件,配合-A時,會導致刷新多次數據庫,在同一時刻執行轉儲和日志刷新,則應同時使用--flush-logs和-x,--master-data或-single-transaction,此時隻刷新一次;建議:和-x,--master-data或 --single-transaction一起使用
	--compact 去掉註釋,適合調試,生產不使用
	-d:隻備份表結構
	-t:隻備份數據,不備份create table
	-n:不備份create database,可被-A或-B覆蓋
	--flush-privileges:備份前刷新授權表,備份mysql庫或相關時需要使用
	-f:忽略SQL錯誤,繼續執行
	--hex-blob:使用十六進制符號轉儲二進制列(例如,“abc”變為0x616263),受影響的數據類型包括BINARY, VARBINARY,BLOB,BIT
	-q:不緩存查詢,直接輸出,加快備份速度

MyISAM備份選項:支持溫備;不支持熱備,所以必須先鎖定要備份的庫,而後啟動備份操作

-x,–lock-all-tables:加全局讀鎖,鎖定所有庫的所有表,同時加–single-transaction或–lock-tables選項會關閉此選項功能,註意:數據量大時,可能會導致長時間無法並發訪問數據庫

-l,–lock-tables:對於需要備份的每個數據庫,在啟動備份之前分別鎖定其所有表,默認為on,–skip-lock-tables選項可禁用,對備份MyISAM的多個庫,可能會造成數據不一致

InnoDB備份選項:支持熱備,可用溫備但不建議用

–single-transaction:此選項Innodb中推薦使用,不適用MyISAM,此選項會開始備份前,先執行START TRANSACTION指令開啟事務此選項通過在單個事務中轉儲所有表來創建一致的快照。僅適用於存儲在支持多版本控制的存儲引擎中的表(目前隻有InnoDB可以); 轉儲不保證與其他存儲引擎保持一致。

​在進行單事務轉儲時,要確保有效的轉儲文件(正確的表內容和二進制日志位置),需要保證沒有其他連接使用以下語句:ALTER TABLE,DROP TABLE,RENAME TABLE,TRUNCATE TABLE

​此選項和 –lock-tables(此選項隱含提交掛起的事務)選項是相互排斥備份大型表時,建議將–single-transaction選項和–quick結合一起使用

InnoDB建議備份策略:
	mysqldump –uroot –A –F –E –R  --single-transaction --master-data=1 --flush-privileges  --triggers --hex-blob >$BACKUP/fullbak_$BACKUP_TIME.sql

MyISAM建議備份策略:
	mysqldump –uroot –A –F –E –R –x --master-data=1 --flush-privileges  --triggers --hex-blob >$BACKUP/fullbak_$BACKUP_TIME.sql
  • xtrabackup工具:由Percona提供支持對InnoDB做熱備(物理備份)的工具,支持完全備份、增量備份

由Percona公司提供的mysql數據庫備份工具,開源的能夠對innodb和xtradb數據庫進行熱備的工具;

xtrabackup 是用來備份 InnoDB 表的,不能備份非 InnoDB 表;

innobackupex 腳本用來備份非 InnoDB 表,同時會調用 xtrabackup 命令來備份 InnoDB 表,還會和 MySQL Server 發送命令進行交互,如加全局讀鎖(FTWRL)、獲取位點(SHOW SLAVE STATUS)等。即innobackupex是在xtrabackup 之上做瞭一層封裝實現的;

雖然目前一般不用 MyISAM 表,隻是 MySQL 庫下的系統表是 MyISAM 的,因此備份基本都通過 innobackupex 命令進行;

xtrabackup版本升級到2.4後,相比之前的2.1有瞭比較大的變化:innobackupex 功能全部集成到 xtrabackup 裡面,隻有一個 binary程序,另外為瞭兼容考慮,innobackupex作為 xtrabackup 的軟鏈接,即xtrabackup現在支持非Innodb表備份,並且Innobackupex在下一版本中移除,建議通過xtrabackup替換innobackupex。

使用innobakupex備份時,其會調用xtrabackup備份所有的InnoDB表,復制所有關於表結構定義的相關文件(.frm)、以及MyISAM、MERGE、CSV和ARCHIVE表的相關文件,同時還會備份觸發器和數據庫配置信息相關的文件。這些文件會被保存至一個以時間命名的目錄中,在備份時,innobackupex還會在備份目錄中創建如下文件:

  • 1)xtrabackup_checkpoints:備份類型(如完全或增量)、備份狀態(如是否已經為prepared狀態)和LSN(日志序列號)范圍信息,每個InnoDB頁(通常為16k大小)都會包含一個日志序列號,即LSN。LSN是整個數據庫系統的系統版本號,每個頁面相關的LSN能夠表明此頁面最近是如何發生改變的;
  • 2)xtrabackup_binlog_info:MySQL服務器當前正在使用的二進制日志文件及至備份這一刻為止二進制日志事件的位置;
  • 3)xtrabackup_info:innobackupex工具執行時的相關信息;
  • 4)backup-my.cnf:備份命令用到的配置選項信息;
  • 5)xtrabackup_logfile:備份生成的日志文件。
用法:
	innobackupex --user=DBUSER --password=DBUSERPASS /path/to/BACKUP-DIR/
選項:
    --user:該選項表示備份賬號
    --password:該選項表示備份的密碼
    --host:該選項表示備份數據庫的地址
    --databases:該選項接受的參數為數據名,如果要指定多個數據庫,彼此間需要以空格隔開;如:"xtra_test dba_test",同時,在指定某數據庫時,也可以隻指定其中的某張表。如:"mydatabase.mytable"。該選項對innodb引擎表無效,還是會備份所有innodb表
    --defaults-file:該選項指定從哪個文件讀取MySQL配置,必須放在命令行第一個選項位置
    --incremental:該選項表示創建一個增量備份,需要指定--incremental-basedir
    --incremental-basedir:該選項指定為前一次全備份或增量備份的目錄,與--incremental同時使用
    --incremental-dir:該選項表示還原時增量備份的目錄
    --include=name:指定表名,格式:databasename.tablename
    --apply-log:一般情況下,在備份完成後,數據尚且不能用於恢復操作,因為備份的數據中可能會包含尚未提交的事務或已經提交但尚未同步至數據文件中的事務。因此,此時數據文件仍處理不一致狀態。此選項作用是通過回滾未提交的事務及同步已經提交的事務至數據文件使數據文件處於一致性狀態
	--use-memory:該選項表示和--apply-log選項一起使用,prepare 備份的時候,xtrabackup做crash recovery分配的內存大小,單位字節。也可(1MB,1M,1G,1GB),推薦1G
	--export:表示開啟可導出單獨的表之後再導入其他Mysql中
	--redo-only:此選項在prepare base full backup,往其中merge增量備份時候使用
	--copy-back:做數據恢復時將備份數據文件拷貝到MySQL服務器的datadir
	--move-back:這個選項與--copy-back相似,唯一的區別是它不拷貝文件,而是移動文件到目的地。這個選項移除backup文件,用時候必須小心。使用場景:沒有足夠的磁盤空間同事保留數據文件和Backup副本

註意:

1)datadir目錄必須為空。除非指定innobackupex –force-non-empty-directorires選項指定,否則–copy-backup選項不會覆蓋;

2)在restore之前,必須shutdown MySQL實例,不能將一個運行中的實例restore到datadir目錄中;

3)由於文件屬性會被保留,大部分情況下需要在啟動實例之前將文件的屬主改為mysql,chown -R mysql:mysql /data/mysqldb

  • mysqlbackup工具:熱備份,MySQL Enterprise Edition組件
  • mysqlhotcopy工具:幾乎冷備,僅適用於MyISAM存儲引擎
  • 基於lvm快照備份:幾乎熱備,需要在拍快照前鎖表
  • tar + cp 等歸檔復制工具備份:完全冷備

二、備份方案

1、cp + tar == 物理冷備

將數據目錄打包壓縮備份,需要停服務,不推薦

​1)備份:

~]# mkdir /backup
~]# systemctl stop mariadb #停止服務
~]# tar Jcf /backup/mariadb_all.tar.xz /var/lib/mysql/ #打包壓縮
backup]# systemctl start mariadb

​2)還原:

~]# systemctl stop mariadb
~]# rm /var/lib/mysql/ -rf  #將損壞的庫刪除
~]# cd /backup/
backup]# tar xf mariadb_all.tar.xz  #解壓打包的數據庫文件
backup]# cp -av var/lib/mysql/ /var/lib/ #還原
backup]# systemctl start mariadb #啟動服務,恢復成功

2、lvm快照 + binlog == 幾乎物理熱備 + 增量備份

​1)備份:需要將數據庫目錄存放到lvm邏輯卷上

~]# systemctl stop mariadb
~]# rm /var/lib/mysql/ -rf  #將損壞的庫刪除
~]# cd /backup/
backup]# tar xf mariadb_all.tar.xz  #解壓打包的數據庫文件
backup]# cp -av var/lib/mysql/ /var/lib/ #還原
backup]# systemctl start mariadb #啟動服務,恢復成功
準備lvm環境:
~]# pvcreate /dev/sda5
~]# vgcreate vg0 /dev/sda5
~]# lvcreate -n lv_data -L 10G vg0
~]# lvcreate -n lv_binlog -L 10G vg0
~]# mkfs.xfs /dev/vg0/lv_data
~]# mkfs.xfs /dev/vg0/lv_binlog
~]# mkdir -pv /data/{mysqldb,binlog}  #創建數據目錄和二進制日志存放目錄
~]# chown -R mysql:mysql /data/
~]# vim /etc/fstab
	UUID=4e3d726a-d420-4c1e-812b-da315012ba86 /data/mysqldb xfs defaults 0 0
	UUID=6dd98866-769f-4369-8738-291fbcc94ca1 /data/binlog xfs defaults 0 0 
配置數據庫,模擬生成大量數據:
~]# yum install mariadb-server -y
~]# vim /etc/my.cnf
    [mysqld]
    datadir = /data/mysqldb  #指定數據庫存放路徑
    log_bin = /data/binlog/mariadb-bin  #開啟二進制日志記錄,並且存放到指定路徑
    innodb_file_per_table = ON  #開啟每個表單獨的表空間
~]# systemctl start mariadb
~]# mysql  #連接數據庫,這裡省略瞭用戶名和密碼,以下都是如此
MariaDB [(none)]> CREATE DATABASE school;  #創建一個測試的庫
MariaDB [(none)]> use school
MariaDB [school]> CREATE TABLE testtb (id int auto_increment primary key,name char(30),age int default 20);  #創建一張數據表
MariaDB [school]> DELIMITER //  #修改語句結束符為“//”
MariaDB [school]> CREATE PROCEDURE pro_testtb()  #寫一個存儲過程,目的是生成十萬條記錄測試用
    -> BEGIN
    -> declare i int;
    -> set i = 1;
    -> while i < 100000
    -> do INSERT INTO testtb(name,age) VALUES (CONCAT('testuser',i),i);
    -> SET i = i + 1;
    -> END while;
    -> END//
MariaDB [school]> DELIMITER ;  #記得將語句結束符再改回來
MariaDB [school]> CALL pro_testtb;  #調用存儲過程來
MariaDB [school]> SELECT COUNT(*) FROM testtb;  #查看一下表中有十萬條記錄
+----------+
| COUNT(*) |
+----------+
|    99999 |
+----------+
開始備份:
MariaDB [school]> FLUSH TABLES WITH READ LOCK;  #備份前切記鎖表,防止用戶繼續寫入
MariaDB [school]> FLUSH LOGS;  #滾動一下二進制日志
MariaDB [school]> SHOW MASTER LOGS;  #查看二進制日志的位置
+--------------------+-----------+
| Log_name           | File_size |
+--------------------+-----------+
| mariadb-bin.000001 |     30334 |
| mariadb-bin.000002 |   1038814 |
| mariadb-bin.000003 |  29178309 |
| mariadb-bin.000004 |       528 |
| mariadb-bin.000005 |       245 |  #將此出記錄下來,我們後邊需要用到
+--------------------+-----------+
~]# lvcreate -L 5G -n lv_mysql_snap -s -p r /dev/vg0/lv_data  #需要再開一個終端創建快照,不要退出mysql終端
MariaDB [school]> UNLOCK TABLES;  #創建快照後第一時間解鎖,小心用戶投訴
~]# mount -o nouuid,norecovery /dev/vg0/lv_mysql_snap /mnt/  #將快照掛載到/mnt
~]# cp -av /mnt/ /backup  #拷貝數據到備份目錄
~]# umount /mnt/
~]# lvremove /dev/vg0/lv_mysql_snap  #拷貝完成後即時刪除快照,影響服務器性能,到此完全備份完成~
再加點數據:
MariaDB [school]> CALL pro_testtb;  #讓我們模擬再來插入十萬條數據
MariaDB [school]> SELECT COUNT(*) FROM testtb;
+----------+
| COUNT(*) |
+----------+
|   199998 |  #現在是二十萬條記錄數據瞭
+----------+

​2)還原:

模擬數據庫損壞:
~]# rm -rf /data/mysqldb/*  #服務器崩潰,不多BB,直接清空庫
~]# systemctl stop mariadb  #停服務
開始還原:
~]# cp -av /backup/* /data/mysqldb/  #將備份的文件cp到對應的庫目錄下
在/etc/my.cnf的[mysqld]下加上skip_networking,禁止用戶使用數據庫,防止恢復過程中的數據寫入
~]# systemctl start mariadb  #啟動服務
~]# ls -1 /data/binlog/  #查看二進制日記的文件個數
    mariadb-bin.000001
    mariadb-bin.000002
    mariadb-bin.000003
    mariadb-bin.000004
    mariadb-bin.000005
    mariadb-bin.000006
    mariadb-bin.index
~]# mysqlbinlog --start-position=245 /data/binlog/mariadb-bin.000005 > binlog.sql  #到出完全備份時間點以後的數據
~]# mysqlbinlog /data/binlog/mariadb-bin.000006 >> binlog.sql  #將之後的所有數據都追加到同一sql文件中
~]# mysql < binlog.sql  #利用二進制日志從我們之前完全備份的點開始增量還原
~]# mysql -e 'SELECT COUNT(*) FROM school.testtb'  #查看一下,二十萬條記錄都在,nice
+----------+
| COUNT(*) |
+----------+
|   199998 |
+----------+
到/etc/my.cnf的[mysqld]下刪除skip_networking,重啟服務,到此還原完成~

3、mysqldump + InnoDB + binlog= 完全邏輯熱備 + 增量備份

​1)備份:這裡我就不再生成數據瞭,就接著上邊的環境做瞭

~]# mysqldump -A -F -E -R --single-transaction --master-data=2 --flush-privileges  > /backup/full-`date +%F-%T`.sql  #全庫完全備份

​2)模擬故障:

MariaDB [(none)]> CREATE DATABASE db1;  #創建一個庫
MariaDB [(none)]> CREATE DATABASE db2;  #再創建一個庫
MariaDB [school]> use school;
MariaDB [school]> DROP TABLE testtb;  #誤操作,將我們二十萬條記錄的表刪掉瞭
MariaDB [school]> CREATE TABLE students (id INT(4) AUTO_INCREMENT PRIMARY KEY,name CHAR(30),age TINYINT);  #後續又有用戶創建瞭其他的表
MariaDB [school]> INSERT INTO students(name,age) VALUES ('user1',20);  #並且還加入瞭數據

​3)還原:

此時,我們發現瞭有一個表不見瞭,需要緊急恢復,開始吧
MariaDB [(none)]> FLUSH TABLES WITH READ LOCK;  #鎖表
MariaDB [(none)]> FLUSH LOGS;  #刷新滾動一次二進制日志文件
MariaDB [(none)]> SHOW MASTER LOGS;  #查看當前的日志狀態
+--------------------+-----------+
| Log_name           | File_size |
+--------------------+-----------+
| mariadb-bin.000001 |     30334 |
| mariadb-bin.000002 |   1038814 |
| mariadb-bin.000003 |  29178309 |
| mariadb-bin.000004 |       528 |
| mariadb-bin.000005 |  29177760 |
| mariadb-bin.000006 |  29177786 |
| mariadb-bin.000007 |       953 |
| mariadb-bin.000008 |       245 |
+--------------------+-----------+
~]# systemctl stop mariadb  #停止服務,準備修復
~]# head -30 /backup/full-2018-06-14-05\:33\:47.sql |grep "CHANGE MASTER"
-- CHANGE MASTER TO MASTER_LOG_FILE='mariadb-bin.000007', MASTER_LOG_POS=245;  #找到完全備份的日志點,在mariadb-bin.000007的245
~]# ls -1 /data/binlog/
mariadb-bin.000001
mariadb-bin.000002
mariadb-bin.000003
mariadb-bin.000004
mariadb-bin.000005
mariadb-bin.000006
mariadb-bin.000007
mariadb-bin.000008
mariadb-bin.index
~]# mysqlbinlog --start-position=245 /data/binlog/mariadb-bin.000007 > /backup/binlog.sql #將完全備份之後的二進制日志導出來
~]# mysqlbinlog /data/binlog/mariadb-bin.000008 >> /backup/binlog.sql
~]# vim /backup/binlog.sql  #修改導出的sql文件,把誤操作的SQL語句刪除
刪除"DROP TABLE `testtb` /* generated by server */"這行
導入備份:
~]# rm -rf /data/mysqldb/*  #先清空故障庫
~]# vim /etc/my.cnf  #編輯配置文件
	在[mysqld]加入skip_networking,防止用戶寫入數據
~]# systemctl start mariadb  #啟動服務
~]# mysql < /backup/full-2018-06-14-05\:33\:47.sql  #導入完全備份
~]# mysql < /backup/binlog.sql  #導入增量備份
MariaDB [(none)]> show databases;  #查看一下我們的數據是否成功恢復
+--------------------+
| Database           |
+--------------------+
| information_schema |
| db1                |  #已恢復
| db2                |  #已恢復
| mysql              |
| performance_schema |
| school             |
| test               |
+--------------------+
MariaDB [(none)]> SELECT COUNT(*) FROM school.testtb;
+----------+
| COUNT(*) |
+----------+
|   199999 | #已恢復
+----------+
MariaDB [(none)]> SELECT * FROM school.students;
+----+-------+------+
| id | name  | age  |
+----+-------+------+
|  1 | user1 |   20 | #已恢復
+----+-------+------+
到現在為止,已經完成恢復,把配置文件中的skip_networking刪除,重啟服務,大功告成~

4、Xtrabackup + InnoDB == 完全熱備 + 增量備份

​1)完全備份

~]# innobackupex --user=root /backup/  #這裡省略瞭密碼

​2)增刪數據

MariaDB [school]> CALL pro_testtb;  #增加一些數據
MariaDB [school]> SELECT COUNT(*) FROM testtb;  #現在有三十萬條記錄瞭
+----------+
| COUNT(*) |
+----------+
|   299998 |
+----------+
MariaDB [school]> INSERT INTO students VALUES (2,'user2',21);
MariaDB [school]> UPDATE students SET age=19 WHERE id=1;
MariaDB [school]> SELECT * FROM students;
+----+-------+------+
| id | name  | age  |
+----+-------+------+
|  1 | user1 |   19 |
|  2 | user2 |   21 |
+----+-------+------+

​3)增量備份

~]# mkdir /backup/inc{1,2}  #創建增量備份的目錄
~]# innobackupex --incremental /backup/inc1/ --incremental-basedir=/backup/2018-06-14_10-44-57/  #指定在完全備份的基礎上增量備份

​4)增刪數據

MariaDB [(none)]> CREATE DATABASE db3; 
MariaDB [(none)]> DROP TABLE school.students;  #誤操作刪除瞭表
MariaDB [(none)]> use school
MariaDB [school]> CALL pro_testtb;  #後續又有數據產生
MariaDB [school]> SELECT COUNT(*) FROM testtb;
+----------+
| COUNT(*) |
+----------+
|   399997 |
+----------+
MariaDB [school]> SELECT * FROM students;  #到此出發現students表不見瞭,怎麼辦?
ERROR 1146 (42S02): Table 'school.students' doesn't exist

​5)故障出現

~]# rm -rf /data/mysqldb/*  #還原前清空數據目錄
MariaDB [(none)]> show databases;  #此時數據庫已經沒瞭
+--------------------+
| Database           |
+--------------------+
| information_schema |
+--------------------+

​6)緊急還原

恢復完全備份和增量備份:
~]# systemctl stop mariadb  #停止服務
~]# innobackupex --apply-log --redo-only /backup/2018-06-14_10-44-57/  #整理完全備份的數據,因為需要保留沒有做完的事務日志所以一定要記得加"--redo-only"選項
~]# innobackupex --apply-log --redo-only /backup/2018-06-14_10-44-57/ --incremental-dir=/backup/inc1/2018-06-14_10-52-05/  #在完全備份的基礎上將增量備份導入到一塊,這裡是最新的增量備份,"--redo-only"選項可以不加,加上也可以,為瞭誤操作我就都加瞭
~]# ls /data/mysqldb/  #確認一下數據庫目錄是否為空
~]# innobackupex --copy-back /backup/2018-06-14_10-44-57/  #導入備份數據
~]# chown -R mysql:mysql /data/mysqldb/  #記得修改數據的所屬組和所屬者
~]# vim my.cnf 加入skip_networking,防止此時用戶操作數據
~]# systemctl start mariadb  #啟動服務,此時已經恢復到瞭最新的備份時的狀態瞭
依靠二進制日志,恢復最新增量備份到now的數據:
~]# cat /backup/2018-06-14_10-44-57/xtrabackup_binlog_info  #查看一下備份時的二進制日志記錄點
	mariadb-bin.000011      35740416
~]# ls -1 /data/binlog/  #看看我們的二進制日志文件記錄到哪裡瞭
mariadb-bin.000001
mariadb-bin.000002
mariadb-bin.000003
mariadb-bin.000004
mariadb-bin.000005
mariadb-bin.000006
mariadb-bin.000007
mariadb-bin.000008
mariadb-bin.000009
mariadb-bin.000010
mariadb-bin.000011
mariadb-bin.000012
mariadb-bin.000013
mariadb-bin.index
~]# mysqlbinlog --start-position=35740416 /data/binlog/mariadb-bin.000011 > /backup/binlog.sql  #將最新增量備份之後的二進制日志記錄的數據導出來
~]# mysqlbinlog /data/binlog/mariadb-bin.000012 >> /backup/binlog.sql
~]# mysqlbinlog /data/binlog/mariadb-bin.000013 >> /backup/binlog.sql
編輯 /backup/binlog.sql 文件,將 "DROP TABLE `school`.`students` /* generated by server */" 刪除,撤銷誤刪除操作
MariaDB [(none)]> SET sql_log_bin=0;  #先臨時關閉二進制日記記錄功能
MariaDB [(none)]> source /backup/binlog.sql  #導入增量備份之後的最新數據
查看確認一下數據有沒有恢復完整,把my.cnf中的skip_networking刪除,重啟服務
到此已經恢復到瞭最新的狀態~

5、使用Xtrabackup實現單表備份

​1)備份單表

~]# innobackupex --include="testdb.testlog" /backup  #備份表數據
~]# mysql -e 'SHOW CREATE TABLE testdb.testlog' > /backup/desc_testdb_testlog.sql  #備份表空間
~]# mysql -e 'DROP TABLE testdb.testlog'  #模擬故障,刪除testlog表

​2)還原單表

~]# innobackupex --apply-log --export /backup/2018-06-14_17-47-02/  #整理表數據
~]# vim /backup/desc_testdb_testlog.sql  #編輯創建表空間的語句,刪除以下字段
    Table   Create Table
    testlog
~]# mysql testdb < /backup/desc_testdb_testlog.sql  #導入表空間
~]# mysql testdb -e 'DESC testlog'  #查看是否導入成功
+-------+----------+------+-----+---------+----------------+
| Field | Type     | Null | Key | Default | Extra          |
+-------+----------+------+-----+---------+----------------+
| id    | int(11)  | NO   | PRI | NULL    | auto_increment |
| name  | char(30) | YES  |     | NULL    |                |
| age   | int(11)  | YES  |     | 20      |                |
+-------+----------+------+-----+---------+----------------+
~]# mysql -e 'ALTER TABLE testdb.testlog DISCARD TABLESPACE'  #清除表空間
~]# cd /backup/2018-06-14_17-47-02/testdb/
testdb]# cp testlog.cfg testlog.exp testlog.ibd /var/lib/mysql/testdb/  #將表數據復制到庫目錄
~]# chown -R mysql:mysql /var/lib/mysql/testdb/  #修改所屬者和所屬組
~]# mysql -e 'ALTER TABLE testdb.testlog IMPORT TABLESPACE'  #導入表空間

總結

本篇文章就到這裡瞭,希望可以給你帶來一些幫助,也希望您能夠多多關註WalkonNet的更多內容!

推薦閱讀: