CONTEND
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。
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備份表結構,恢復時先恢復表結構。