(五)mysql數據備份—物理備份(完備+lvm快照+xtrabackup)+邏輯備份(mysqldump+導入導出)

CONTEND

 

5.1 MySQL數據備份技術概述

5.2 完全物理備份

5.3 LVM快照實現物理備份

5.3.1 手動配置

5.3.2 腳本+cron

5.4 mysql物理備份Xtrabackup

5.4.1 xtrabackup安裝

 5.4.2 全量備份和恢復

5.4.3 增量備份和恢復

5.4.4 差異備份和恢復

5.5 邏輯備份Mysqldump

5.5.1 瞭解mysqldump

5.5.2 備份恢復所有庫+binlog

5.6 表的導入和導出


5.1 MySQL數據備份技術概述

(1)所有備份數據都應放在非數據庫本地,而且建議有多份副本
         測試環境中做日常恢復演練,恢復較備份更爲重要。

(2)瞭解備份和冗餘的概念:

備份:能夠防止由於機械故障以及人爲誤操作帶來的數據丟失,例如將數據庫文件保存在了其它地方。
        冗條:數據有多份冗餘,但不等備份,只能防止機械故障還來的數據丟失,例如主備模式、數據庫集羣。


(3)備份過程中必須考慮因素(優先滿足數據的一致性):

  • 1.數據的一致性
  • 2.服務的可用性

(4)備份方式(邏輯備份和物理備份)

邏輯備份:備份的是建表、建庫、插入等操作所執行SQL語句( DDL DML DCL ),適用於中小型數據庫,效率相對較低。

  • mysqldump
  • mydumper

物理備份:直接複製數據庫文件,適用於大型數據庫環境,不受存儲引擎的限制,但不能恢復到不同的MySQL版本

  • tar,cp
  • xtrabackup
  • inbackup
  • Ivm snapshot

(5)備份還有完全備份、增量備份和差異備份

  • 完全備份當然就是全部都備份了
  • 增量備份只備份一次完整的,然後每天只增加新增的內容

  • 差異備份,還是製作一個完整的備份,後面每天只針對Sunday,做差異的備份。

 5.2 完全物理備份

備份很簡單直接tar一個命令就OK了,然後就開始還原(只還原到備份那一刻):

mkdir /backup
cd /var/lib/mysql
tar -cf /backup/`date +%F`.gz *
#開始還原
systemctl stop mysqld
rm -rf /var/lib/mysql/*
tar -xf /backup/2020-04-14.gz -C /var/lib/mysql
chown -R mysql:mysql /var/lib/mysql
systemctl start mysqld
#登錄測試數據庫是否還在
mysql -p'Root@321'
show databases;

5.3 LVM快照實現物理備份

數據一致,服務可用。
注: MySQL數據 lv 和將要創建的 snapshot 必須在同一VG,因此VG必須要有一定的剩於空間
優點:

  • 幾乎是熱備(創建快照前把表上鎖,創建完後立即釋放)
  • 支持所有存儲引擎
  • 備份速度快
  • 無需使用昂貴的商業軟件(它是操作系統級別的)

缺點:

  • 可能需要跨部門協調(使用操作系統級別的命令, DBA-般沒權限)
  • 無法預計服務停止時間
  • 數據如果分佈在多個捲上比較麻煩(針對存儲級別而言)
     

5.3.1 手動配置

一定要準備lvm的,如果剛開始裝mysql的時候,就可以準備了LVM了。但是mysql運行一段時間了,數據並沒有存儲LVM,下面我們先將現在的數據遷移到LVM。

一般步驟:加全局鎖——>創建快照——>釋放鎖——>從快照中恢復——>移除快照——>快照恢復mysql

而快照恢復的流程:停止數據庫——>清理環境——>導入數據——>修改權限——>啓動數據庫

#1、準備LVM及文件系統,我是虛擬機直接添加硬盤  
lsblk  #查看硬盤信息
vgcreate datavg /dev/sdb
vgs   #查看lvm容量
lvcreate -L 2G -n mysql datavg    #創建容量2G名爲mysql的lvm
mkfs.xfs /dev/datavg/mysql  #格式化

#2、數據遷移到lvm
systemctl stop mysqld   
mount /dev/datavg/mysql /mnt/  #臨時掛載點,注意mnt下不要有其他東西
cp /var/lib/mysql/* /mnt/ -a  #將mysql數據拷到這裏
umount /mnt/
vim /etc/fstab  #編輯這個文件添加如下一行內容
/dev/datavg/mysql       /var/lib/mysql          xfs        defaults    0 0 

chown -R mysql:mysql /var/lib/mysql  #最好設置下,免得有問題
systemctl start mysqld

#3、下面開始創建快照備份
echo 'flush tables with read lock;system lvcreate -L 500M -s -n lv-mysql-snap /dev/datavg/mysql;' |mysql -p'Root@321' #加全局鎖、創建快照和釋放鎖要在同一會話中完成,所以這邊釋放鎖就不需要了,自動釋放了

#4、從快照中備份
mount -o ro,nouuid /dev/datavg/lv-mysql-snap /mnt/  #因爲是xfs,要加上nouuid,只讀是爲了防止快照被破壞
cd /mnt/
ll
tar -cf /backup/`date +%F`-mysql-snap1.tar ./*

#5、移除快照
cd; umount /mnt/
ll /backup/
lvremove -f /dev/datavg/lv-mysql-snap 
vgscan

#6、下面利用快照恢復mysql
systemctl stop mysqld
rm -rf /var/lib/mysql/*
tar -xf /backup/2020-04-15-mysql-snap1.tar -C /var/lib/mysql/
chown -R mysql:mysql /var/lib/mysql 
systemctl start mysqld
mysql -p'Root@321'

5.3.2 腳本+cron

(一般我們利用腳本實現,更方便快捷)腳本如下,可根據需要改寫:


#!/bin/bash
#LVM backup mysql

echo 'flush tables with read lock;system lvcreate -L 500M -s -n lv-mysql-snap /dev/datavg/mysql;' |mysql -p'Root@321'
mount -o ro,nouuid /dev/datavg/lv-mysql-snap /mnt/
cd /mnt
tar -cf /backup/`date +%F`-mysql-snap.tar ./*
cd /root
if [ $? -eq 0 ];then
  umount /mnt/
  lvremove -f /dev/datavg/lv-mysql-snap
fi
~  

利用cron定期備份(每週每天凌晨2點定時備份):

crontab -e
0 2 * * * /root/mysql_bak.sh

5.4 mysql物理備份Xtrabackup

它是開源免費的支持MySQL數據庫熱備份的軟件,它能對InnoDB和XtraDB存儲引擎的數據庫非阻塞地備份。它不暫停服務創建Innodb熱備份。爲mysq|做增量備份;在mysq|服務器之間做在線表遷移;使創建replication更加容易;備份mysq|而不增加服務器的負載。
       percona是一家老牌的mysq|技術諮詢公司。它不僅提供mysql的技術支持、培訓、諮詢,還發布了mysql的分支版本percona-Server。並圍繞percona Server還發布了一系列的mysq|工具。

5.4.1 xtrabackup安裝

因爲我是mysql8,只能安裝xtrabackup8,其他版本不支持哦,大家根據自己mysql版本挑選相應的xtrabackup。

Xtrabackup8官網鏈接

wget https://www.percona.com/downloads/XtraBackup/Percona-XtraBackup-8.0.4/binary/redhat/7/x86_64/percona-xtrabackup-80-8.0.4-1.el7.x86_64.rpm
yum localinstall percona-xtrabackup-80-8.0.4-1.el7.x86_64.rpm
#查看版本號
xtrabackup -v
xtrabackup: recognized server arguments: --datadir=/var/lib/mysql --server-id=6 --log_bin=/var/log/binlog/mysql-bin 
xtrabackup version 8.0.4 based on MySQL server 8.0.13 Linux (x86_64) (revision id: c2c0777)

 5.4.2 全量備份和恢復

#1、備份
mkdir /xtrabackup/full -p  #創建備份存放的文件夾
xtrabackup --defaults-file=/etc/my.cnf --user=root --password=Root@321 --backup --target-dir=/xtrabackup/full  #開始備份
#查看下備份的文件
ls /xtrabackup/full/
backup-my.cnf   ibdata1    performance_schema  undo_001                xtrabackup_info
company         learning   shop                undo_002                xtrabackup_logfile
employment      mysql      student             xtrabackup_binlog_info  xtrabackup_tablespaces
ib_buffer_pool  mysql.ibd  sys                 xtrabackup_checkpoints

#2、恢復
systemctl stop mysqld
xtrabackup --defaults-file=/etc/my.cnf --copy-back --target-dir=/xtrabackup/full
chown -R mysql:mysql /var/lib/mysql
systemctl start mysqld
mysql -p'Root@321'
show databases;

5.4.3 增量備份和恢復

#1、先創建一個數據庫,插入一個數據,做週一的備份
mysql> create database testdb;
mysql> create table testdb.t1(id int);
mysql> insert into testdb.t1 values(1);

xtrabackup --defaults-file=/etc/my.cnf --user=root --password=Root@321 --backup --target-dir=/xtrabackup/2020-04-15

#2、插入第二個數據,模仿做週二的備份(基於週一做增量備份)
mysql -p'Root@321'
mysql> insert into testdb.t1 values(2);
xtrabackup --defaults-file=/etc/my.cnf --user=root --password=Root@321 --backup --target-dir=/xtrabackup/2020-04-16 --incremental-dir=/xtrabackup/2020-04-15

#3、週三的
mysql -p'Root@321'
mysql> insert into testdb.t1 values(3);
xtrabackup --defaults-file=/etc/my.cnf --user=root --password=Root@321 --backup --target-dir=/xtrabackup/2020-04-17 --incremental-dir=/xtrabackup/2020-04-16/
#週三以後類似,我就不一一列舉了


#開始恢復,根據需要恢復指定那天
systemctl stop mysqld
rm -rf /var/lib/mysql/*
xtrabackup --defaults-file=/etc/my.cnf --copy-back --target-dir=/xtrabackup/2020-04-16
chown -R mysql:mysql /var/lib/mysql
systemctl start mysqld
mysql -p'Root@321'

5.4.4 差異備份和恢復

這個實際操作與增量備份類似。

mysql> create table testdb.t2(id int);
mysql> insert into testdb.t2 value (1);
mysql> select * from testdb.t2;

xtrabackup --defaults-file=/etc/my.cnf --user=root --password=Root@321 --backup --target-dir=/xtrabackup/2020-04-15

#2、插入第二個數據,模仿做週二的備份(基於週一做差異備份,和增量備份一樣)
mysql -p'Root@321'
mysql> insert into testdb.t2 values(2);
xtrabackup --defaults-file=/etc/my.cnf --user=root --password=Root@321 --backup --target-dir=/xtrabackup/2020-04-16 --incremental-dir=/xtrabackup/2020-04-15/

#3、週三的(和增量備份只有一個不同,它是基於週一做差異備份的)
mysql -p'Root@321'
mysql> insert into testdb.t2 values(3);
xtrabackup --defaults-file=/etc/my.cnf --user=root --password=Root@321 --backup --target-dir=/xtrabackup/2020-04-17 --incremental-dir=/xtrabackup/2020-04-17/

#週三以後類似,我就不一一列舉了

#開始恢復,恢復指定那天就行
systemctl stop mysqld
rm -rf /var/lib/mysql/*
xtrabackup --defaults-file=/etc/my.cnf --copy-back --target-dir=/xtrabackup/2020-04-17
chown -R mysql:mysql /var/lib/mysql
systemctl start mysqld
mysql -p'Root@321'

5.5 邏輯備份Mysqldump

5.5.1 瞭解mysqldump

mysqldump工具備份:導出的是SQL語句文件

優點:不論是什麼存儲引擎,都可以用mysqldump備成SQL語句

缺點:速度較慢,導入時可能會出現格式不兼容的突發情況,無法做增量備份和累計增量備份,不是大型數據庫都推薦使用Mysqldump

語法:
# mysqldump -h 服務器 -u用戶名 -p密碼 數據庫名 > 備份文件.sql


      參數說明:

-A, --all-databases 所有庫
school 數據庫名
school stu_info t1 school數據庫的表stu_info. t1
-B, --databases bbs test mysql 多個數據庫
--single-transaction #InnoDB一致性服務可用性
x,--lock-all-tables #MyISAM一致性服務可用性
-E, --events #備份事件調度器代碼
--opt #同時啓動各種高級選項
-R, --routines #備份存儲過程和存儲函數
F, --flush-logs #備份之前刷新日誌
--triggers #備份觸發器
--master-data=1|2 #該選項將會記錄binlog的日誌位置與文件名並追加到文件中

5.5.2 備份恢復所有庫+binlog

(1)正常恢復+binlog

#備份所有數據庫 
mysqldump -p'Root@321' --all-databases --single-transaction --master-data=1 --flush-logs >/tmp/mysqldump_bak/`date +%F`-mysql-all.sql

#查看SQL文件,瞭解當時記錄的bin位置
vim /tmp/mysqldump_bak/2020-04-17-mysql-all.sql 
CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000020', MASTER_LOG_POS=155;

#下面我再隨便插入一些數據,利用binlog恢復
mysql> insert into t1 values (1),(2),(3);
mysql> insert into t2 values (1,'jack'),(2,'danie'),(3,'gawain');

#初始化數據庫,記得另外備份binlog文件,防止丟失
cp /var/log/binlog/mysql-bin.000020 ./
systemctl stop mysqld
rm -rf /var/lib/mysql/*
systemctl start mysqld

#修改密碼
grep password /var/log/mysqld.log 
mysqladmin -uroot -p'rntLcST2y9/j' password 'Root@123'

#這時登上去庫裏是空的
msyql -p'Root@123'

#開始恢復,這時登上去還沒有備份數據庫之後插入的數據
mysql -uroot -pRoot@123 < /tmp/mysqldump_bak/2020-04-17-mysql-all.sql 

#binlog恢復,之前SQL文件裏就有截斷的位置,從那恢復就可以了,如果有多個binlog可以依次恢復
mysqlbinlog mysql-bin.000020 --start-position=155 | mysql -uroot -pRoot@123

(2)當我們恢復的時候,binlog也會隨之產生,有時候數據太大,我不需要這binlog,所以可以選擇不產生binlog恢復。

#方法一,通過source恢復,數據庫初始化我就省略咯,恢復後記得改回來set sql_log_bin=1;
mysql> set sql_log_bin=0;
mysql> source /tmp/mysqldump_bak/2020-04-17-mysql-all.sql;

#方法二,直接在SQL文件中添加set sql_log_bin=0;
vim /tmp/mysqldump_bak/2020-04-17-mysql-all.sql 
set sql_log_bin=0;

(3)爲了防止恢復的過程還會誤刪數據,比如你只想恢復binlog那一刻,後面有個drop的語句不想恢復怎麼辦?

#可以找到這個文件重定向一個文件中,再進行修改,把不想要的SQL語句刪除
mysqlbinlog --start-position=154  mysql-bin.000020 > errorCorrect

#或者直接跳過你不想要的語句的位置,比如下面直接跳過slave2.000006中處於768到1045之間的語句
mysqlbinlog --start-position=154 slave2.000004 slave2.000005
mysqlbinlog --stop-position=768 slave2.000006
mysqlbinlog --start-position= 1045 slave2.000006

5.6 表的導入和導出

(1)導出文件select...into outfile 導出文件

#先修改下/etc/my.conf,添加如下一欄
secure-file-priv=/backup
#設置/backup權限
chown -R mysql:mysql /backup/

#開始導出文件
mysql> select * from testdb.t1 into outfile '/backup/t1';

#利用mysql命令導出文本文件
mysql -uroot -pRoot@123 -e 'select * from testdb.t1' > /backup/t1.txt
mysql -uroot -pRoot@123 --xml -e 'select * from testdb.t1' > /backup/t1.xml
mysql -uroot -pRoot@123 --html -e 'select * from testdb.t1' > /backup/t1.html

HTML文件可以通過瀏覽器訪問:

 

(2)load data infile導入文本文件

mysql> delete from testdb.t1;

mysql> load data infile '/backup/t1' into table testdb.t1;

mysql> select * from testdb.t1;
+------+--------+
| id   | name   |
+------+--------+
|    1 | jack   |
|    2 | tom    |
|    3 | jannie |
+------+--------+

注意:表的導出和導入只備份表記錄,不會備分表結構。因此需要通過mysqldump備份表結構,恢復時先恢復表結構。

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章