Mysql備份系列(4)--lvm-snapshot備份mysql資料(全量+增量)操作記錄

散盡浮華發表於2016-12-03

 

Mysql最常用的三種備份工具分別是mysqldump、Xtrabackup(innobackupex工具)、lvm-snapshot快照。
前面分別介紹了:
Mysql備份系列(1)--備份方案總結性梳理
Mysql備份系列(2)--mysqldump備份(全量+增量)方案操作記錄
Mysql備份系列(3)--innobackupex備份mysql大資料(全量+增量)操作記錄

lvm-snapshot:基於LVM快照的備份
1.關於快照:
1)事務日誌跟資料檔案必須在同一個捲上;
2)剛剛創立的快照卷,裡面沒有任何資料,所有資料均來源於原卷
3)一旦原卷資料發生修改,修改的資料將複製到快照卷中,此時訪問資料一部分來自於快照卷,一部分來自於原卷
4)當快照使用過程中,如果修改的資料量大於快照卷容量,則會導致快照卷崩潰。
5)快照卷本身不是備份,只是提供一個時間一致性的訪問目錄。

2.基於快照備份幾乎為熱備:
1)建立快照卷之前,要請求MySQL的全域性鎖;在快照建立完成之後釋放鎖;
2)如果是Inoodb引擎, 當flush tables 後會有一部分儲存在事務日誌中,卻不在檔案中。 因此恢復時候,需要事務日誌和資料檔案
但釋放鎖以後,事務日誌的內容會同步資料檔案中,因此備份內容並不絕對是鎖釋放時刻的內容,由於有些為完成的事務已經完成,但在備份資料中因為沒完成而回滾。 因此需要藉助二進位制日誌往後走一段

3.基於快照備份注意事項:
1)事務日誌跟資料檔案必須在同一個捲上;
2)建立快照卷之前,要請求MySQL的全域性鎖;在快照建立完成之後釋放鎖;
3)請求全域性鎖完成之後,做一次日誌滾動;做二進位制日誌檔案及位置標記(手動進行);

4.為什麼基於MySQL快照的備份很好?
原因如下幾點:
1)幾乎是熱備 在大多數情況下,可以在應用程式仍在執行的時候執行備份。無需關機,只需設定為只讀或者類似只讀的限制。
2)支援所有基於本地磁碟的儲存引擎 它支援MyISAM, Innodb, BDB,還支援 Solid, PrimeXT 和 Falcon。
3)快速備份 只需拷貝二進位制格式的檔案,在速度方面無以匹敵。
4)低開銷 只是檔案拷貝,因此對伺服器的開銷很細微。
5)容易保持完整性 想要壓縮備份檔案嗎?把它們備份到磁帶上,FTP或者網路備份軟體 -- 十分簡單,因為只需要拷貝檔案即可。
6)快速恢復 恢復的時間和標準的MySQL崩潰恢復或資料拷貝回去那麼快,甚至可能更快,將來會更快。
7)免費 無需額外的商業軟體,只需Innodb熱備工具來執行備份。

快照備份mysql的缺點:
1)需要相容快照 -- 這是明顯的。
2)需要超級使用者(root) 在某些組織,DBA和系統管理員來自不同部門不同的人,因此許可權各不一樣。
3)停工時間無法預計,這個方法通常指熱備,但是誰也無法預料到底是不是熱備 -- FLUSH TABLES WITH READ LOCK 可能會需要執行很長時間才能完成。
4)多捲上的資料問題 如果你把日誌放在獨立的裝置上或者你的資料庫分佈在多個捲上,這就比較麻煩了,因為無法得到全部資料庫的一致性快照。不過有些系統可能能自動做到多卷快照。

下面即是使用lvm-snapshot快照方式備份mysql的操作記錄,僅依據本人實驗中使用而述.

操作記錄:
如下環境,本機是在openstack上開的雲主機,在openstack上建立一個30G的雲硬碟掛載到本機,然後製作lvm邏輯卷。

一、準備LVM卷,並將mysql資料恢復(或者說遷移)到LVM捲上:
1) 建立一個分割槽或儲存到另一塊硬碟上面
2) 建立PV、VG、LVM
3) 格式化 LV0
4) 掛載LV到臨時目錄
5) 確認服務處於stop狀態
6) 將資料遷移到LV0
7) 重新掛載LV0到mysql資料庫的主目錄/data/mysql/data
8) 稽核許可權並啟動服務
[root@test-huanqiu ~]# fdisk -l
.........
Disk /dev/vdc: 32.2 GB, 32212254720 bytes
16 heads, 63 sectors/track, 62415 cylinders
Units = cylinders of 1008 * 512 = 516096 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00000000

[root@test-huanqiu ~]# fdisk /dev/vdc                            //依次輸入p->n->p->1->回車->回車->w
.........
Command (m for help): p

Disk /dev/vdc: 32.2 GB, 32212254720 bytes
16 heads, 63 sectors/track, 62415 cylinders
Units = cylinders of 1008 * 512 = 516096 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x343250e4

Device Boot Start End Blocks Id System

Command (m for help): n
Command action
e extended
p primary partition (1-4)
p
Partition number (1-4): 1
First cylinder (1-62415, default 1):
Using default value 1
Last cylinder, +cylinders or +size{K,M,G} (1-62415, default 62415):
Using default value 62415

Command (m for help): w
The partition table has been altered!

Calling ioctl() to re-read partition table.
Syncing disks.

[root@test-huanqiu ~]# fdisk /dev/vdc

WARNING: DOS-compatible mode is deprecated. It's strongly recommended to
switch off the mode (command 'c') and change display units to
sectors (command 'u').

Command (m for help): p

Disk /dev/vdc: 32.2 GB, 32212254720 bytes
16 heads, 63 sectors/track, 62415 cylinders
Units = cylinders of 1008 * 512 = 516096 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x343250e4

Device Boot Start End Blocks Id System
/dev/vdc1 1 62415 31457128+ 5 Extended

Command (m for help):

[root@test-huanqiu ~]# pvcreate /dev/vdc1
Device /dev/vdc1 not found (or ignored by filtering).
[root@test-huanqiu ~]# vgcreate vg0 /dev/vdc1
Volume group "vg0" successfully created
[root@test-huanqiu ~]# lvcreate -L +3G -n lv0 vg0
Logical volume "lv0" created.
[root@test-huanqiu ~]# mkfs.ext4 /dev/vg0/lv0
[root@test-huanqiu ~]# mkdir /var/lv0/
[root@test-huanqiu ~]# mount /dev/vg0/lv0 /var/lv0/
[root@test-huanqiu ~]# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/VolGroup00-LogVol00
8.1G 6.0G 1.7G 79% /
tmpfs 1.9G 0 1.9G 0% /dev/shm
/dev/vda1 190M 37M 143M 21% /boot
/dev/mapper/vg0-lv0 2.9G 4.5M 2.8G 1% /var/lv0

[root@test-huanqiu ~]# lvs
LV VG Attr LSize Pool Origin Data% Meta% Move Log Cpy%Sync Convert
LogVol00 VolGroup00 -wi-ao---- 8.28g
LogVol01 VolGroup00 -wi-ao---- 1.50g
lv0 vg0 -wi-a----- 3.00g

----------------------------------------------------------------------------------------------------
如果要想刪除這個lvs,操作如下:
[root@test-huanqiu ~]# umount /data/mysql/data/            //先解除安裝掉這個lvs的掛載關係
[root@test-huanqiu ~]# lvremove /dev/vg0/lv0
[root@test-huanqiu ~]# vgremove vg0
[root@test-huanqiu ~]# pvremove /dev/vdc1
[root@test-huanqiu ~]# lvs
LV VG Attr LSize Pool Origin Data% Meta% Move Log Cpy%Sync Convert
LogVol00 VolGroup00 -wi-ao---- 8.28g
LogVol01 VolGroup00 -wi-ao---- 1.50g
----------------------------------------------------------------------------------------------------

mysql的資料目錄是/data/mysql/data,密碼是123456
[root@test-huanqiu ~]# ps -ef|grep mysql
mysql 2066 1286 0 07:33 ? 00:00:06 /usr/local/mysql/bin/mysqld --basedir=/usr/local/mysql/ --datadir=/data/mysql/data --plugin-dir=/usr/local/mysql//lib/plugin --user=mysql --log-error=/data/mysql/data/mysql-error.log --pid-file=/data/mysql/data/mysql.pid --socket=/usr/local/mysql/var/mysql.sock --port=3306
root 2523 2471 0 07:55 pts/1 00:00:00 grep mysql
[root@test-huanqiu ~]# /etc/init.d/mysql stop
Shutting down MySQL.... SUCCESS!

[root@test-huanqiu ~]# cd /data/mysql/data/
[root@test-huanqiu data]# tar -cf - . | tar xf - -C /var/lv0/

[root@test-huanqiu data]# umount /var/lv0/

[root@test-huanqiu data]# mount /dev/vg0/lv0 /data/mysql/data
[root@test-huanqiu data]# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/VolGroup00-LogVol00
8.1G 6.0G 1.7G 79% /
tmpfs 1.9G 0 1.9G 0% /dev/shm
/dev/vda1 190M 37M 143M 21% /boot
/dev/mapper/vg0-lv0 2.9G 164M 2.6G 6% /data/mysql/data

刪除掛載後產生的lost+found目錄
[root@test-huanqiu data]# rm -rf lost+found

[root@test-huanqiu data]# ll -d /data/mysql/data
[root@test-huanqiu data]# ll -Z /data/mysql/data
[root@test-huanqiu data]# ll -Zd /data/mysql/data

需要注意的是:
當SElinux功能開啟情況下,mysql資料庫重啟會失敗,所以必須執行下面命令,恢復SElinux安全上下文.
[root@test-huanqiu data]# restorecon -R /data/mysql/data/
[root@test-huanqiu data]# /etc/init.d/mysql start
Starting MySQL... SUCCESS!

二、備份: (生產環境下一般都是整個資料庫備份)
1)鎖表
2)檢視position號並記錄,便於後期恢復
3)建立snapshot快照
4)解表
5)掛載snapshot
6)拷貝snapshot資料,進行備份。備份整個資料庫之前,要關閉mysql服務(保護ibdata1檔案)
7)移除快照

設定此變數為1,讓每個事件儘可能同步到二進位制日誌檔案裡,以消耗IO來儘可能確保資料一致性。
mysql> SET GLOBAL sync_binlog=1;

檢視二進位制日誌和position,以備後續進行binlog日誌恢復增量資料(記住這個position節點記錄,對後面的增量資料備份很重要) 
mysql> SHOW MASTER STATUS;
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000004 | 1434 | | | |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

建立存放binlog日誌的position節點記錄的目錄
所有的position節點記錄都放在這同一個binlog.pos檔案下(後面就使用>>符號追加到這個檔案下
[root@test-huanqiu ~]# mkdir /backup/mysql/binlog
[root@test-huanqiu ~]# mysql -p123456 -e "SHOW MASTER STATUS;" > /backup/mysql/binlog/binlog.pos
[root@test-huanqiu snap1]# cat /backup/mysql/binlog/binlog.pos
File Position Binlog_Do_DB Binlog_Ignore_DB Executed_Gtid_Set
mysql-bin.000004 1434

重新整理日誌,產生新的binlog日誌,保證日誌資訊不會再寫入到上面的mysql-bin.000004日誌內。
mysql> FLUSH LOGS;

全域性讀鎖,讀鎖請求到後不要關閉此mysql互動介面
mysql> FLUSH TABLES WITH READ LOCK;

在innodb表中,即使是請求到了讀鎖,但InnoDB在後臺依然可能會有事務在進行讀寫操作,
可用"mysql> SHOW ENGINE INNODB STATUS;"檢視後臺程式的狀態,等沒有寫請求後再做備份。

建立快照,以只讀的方式(--permission r)建立一個3GB大小的快照卷snap1
-s:相當於--snapshot
[root@test-huanqiu ~]# mkdir /var/snap1
[root@test-huanqiu ~]# lvcreate -s -L 2G -n snap1 /dev/vg0/lv0 --permission r
Logical volume "snap1" created.

檢視快照卷的詳情(快照卷也是LV):
[root@test-huanqiu ~]# lvdisplay

解除鎖定
回到鎖定表的mysql互動式介面,解鎖:
mysql> UNLOCK TABLES;

此引數可以根據伺服器磁碟IO的負載來調整
mysql> SET GLOBAL sync_binlog=0;

[root@test-huanqiu ~]# mount /dev/vg0/snap1 /var/snap1                //掛載快照卷
[root@test-huanqiu snap1]# df -h
Filesystem             Size   Used  Avail  Use%  Mounted on
/dev/mapper/VolGroup00-LogVol00
                            8.1G  5.8G  1.9G  76%    /
tmpfs                    1.9G  0       1.9G  0%      /dev/shm
/dev/vda1              190M 37M   143M 21%    /boot
/dev/mapper/vg0-lv0 2.9G 115M 2.7G 5% /data/mysql/data
/dev/mapper/vg0-snap1
                               2.9G 115M 2.7G 5% /var/snap1

[root@test-huanqiu ~]# cd /var/snap1/ && ll /var/snap1
[root@test-huanqiu snap1]# mkdir -p /backup/mysql/data/               //建立備份目錄
total 0

對本機的資料庫進行備份,備份整個資料庫。

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| test               |
+--------------------+
4 rows in set (0.01 sec)

mysql> create database beijing;
Query OK, 1 row affected (0.00 sec)

mysql> use beijing;
Database changed

mysql> create table people(id int(5),name varchar(20));
Query OK, 0 rows affected (0.03 sec)

mysql> insert into people values("1","wangshibo");
Query OK, 1 row affected (0.00 sec)

mysql> insert into people values("2","guohuihui");
Query OK, 1 row affected (0.01 sec)

mysql> insert into people values("3","wuxiang");
Query OK, 1 row affected (0.01 sec)

mysql> select * from people;
+------+-----------+
| id   | name      |
+------+-----------+
|    1 | wangshibo |
|    2 | guohuihui |
|    3 | wuxiang   |
+------+-----------+
3 rows in set (0.00 sec)
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| beijing            |
| mysql              |
| performance_schema |
| test               |
+--------------------+
5 rows in set (0.01 sec)

--------------------------------------------------------------------------------------------------------------------------
需要注意的是:
innodb表,一般會開啟獨立表空間模式(innodb_file_per_table)。
由於InnoDB預設會將所有的資料庫InnoDB引擎的表資料儲存在一個共享空間中:ibdata1檔案。
增刪資料庫的時候,ibdata1檔案不會自動收縮,這對單個或部分資料庫的備份也將成為問題(如果不是整個資料庫備份的情況下,ibdata1檔案就不能備份,否則會影響全部資料庫的資料)
所以若是對單個資料庫或部分資料庫進行快照備份
1)若是直接誤刪除mysql資料目錄下備份庫目錄,可以直接將快照備份資料解壓就能恢復
2)若是使用drop或delete誤刪除的資料,那麼在使用快照備份資料恢復時,就會出問題!因為單庫備份時ibdata1檔案不能單獨備份,恢復時會導致這個檔案損壞!

所以正確的做法是:
要對整個資料庫進行備份,並且一定要在mysql服務關閉的情況下(這樣是為了保護ibdata1檔案)。
因為mysql是採用緩衝方式來將資料寫入到ibdata1檔案中的,這正是fflush()函式存在的理由。當mysql在執行時,對ibdata1進行拷貝肯定會導致ibdata1檔案中的資料出錯,這樣在資料恢復時,也就肯定會出現“ERROR 1146 (42S02): Table '****' doesn't exist“的報錯!

在對啟用innodb引擎的mysql資料庫進行遷移的時候也是同理:
在對innodb資料庫進行資料遷移的時候,即將msyql(innodb引擎)服務從一臺伺服器遷移到另一臺伺服器時,在對資料庫目錄進行整體拷貝的時候(當然就包括了對ibdata1檔案拷貝),一定要在關閉對方mysql服務的情況下進行拷貝!

ibdata1用來儲存檔案的資料,而庫名的資料夾裡面的那些表檔案只是結構而已,由於新版的mysql預設試innodb,所以ibdata1檔案預設就存在了,少了這個檔案有的資料表就會出錯。要知道:資料庫目錄下的.frm檔案是資料庫中很多的表的結構描述檔案;而ibdata1檔案才是資料庫的真實資料存放檔案。

-------------------------------------------innodb_file_per_table引數說明------------------------------------------
線上環境的話,一般都建議開啟這個獨立表空間模式。
因為ibdata1檔案會不斷的增大,不會減少,無法向OS回收空間,容易導致線上出現過大的共享表空間檔案,致使當前空間爆滿。
並且ibdata1檔案大到一定程式會影響insert、update的速度;並且
另外如果刪表頻繁的話,共享表空間產生的碎片會比較多。開啟獨立表空間,方便進行innodb表的碎片整理

使用MyISAM表引擎的資料庫會分別建立三個檔案:表結構、表索引、表資料空間。
可以將某個資料庫目錄直接遷移到其他資料庫也可以正常工作。

然而當使用InnoDB的時候,一切都變了。
InnoDB預設會將所有的資料庫InnoDB引擎的表資料儲存在一個共享空間中:ibdata1檔案。
增刪資料庫的時候,ibdata1檔案不會自動收縮,單個資料庫的備份也將成為問題。
通常只能將資料使用mysqldump 匯出,然後再匯入解決這個問題。

在MySQL的配置檔案[mysqld]部分,增加innodb_file_per_table引數。
可以修改InnoDB為獨立表空間模式,每個資料庫的每個表都會生成一個資料空間。

它的優點:
1)每個表都有自已獨立的表空間。
2)每個表的資料和索引都會存在自已的表空間中。
3)可以實現單表在不同的資料庫中移動。
4)空間可以回收(除drop table操作處,表空不能自已回收)

Drop table操作自動回收表空間,如果對於統計分析或是日值表,刪除大量資料後可以通過:alter table TableName engine=innodb;回縮不用的空間。
對於使innodb-plugin的Innodb使用turncate table也會使空間收縮。
對於使用獨立表空間的表,不管怎麼刪除,表空間的碎片不會太嚴重的影響效能,而且還有機會處理。

它的缺點:
單表增加過大,如超過100個G。

結論:
共享表空間在Insert操作上少有優勢。其它都沒獨立表空間表現好。當啟用獨立表空間時,請合理調整一下:innodb_open_files。
InnoDB Hot Backup(冷備)的表空間cp不會面對很多無用的copy了。而且利用innodb hot backup及表空間的管理命令可以實。

1)innodb_file_per_table設定.設定為1,表示開啟了獨立的表空間模式。 如果設定為0,表示關閉獨立表空間模式,開啟方法如下:
在my.cnf中[mysqld]下設定
innodb_file_per_table=1

2)檢視是否開啟:
mysql> show variables like "%per_table%";
+-----------------------+-------+
| Variable_name | Value |
+-----------------------+-------+
| innodb_file_per_table | ON |
+-----------------------+-------+
1 row in set (0.00 sec)

3)關閉獨享表空間
innodb_file_per_table=0關閉獨立的表空間
mysql> show variables like ‘%per_table%’;
-------------------------------------------innodb_file_per_table引數說明------------------------------------------
--------------------------------------------------------------------------------------------------------------------------

備份前,一定要關閉mysql資料庫!因為裡面會涉及到ibdata1檔案備份,不關閉mysql的話,ibdata1檔案備份後會損壞,從而導致恢復資料失敗!
[root@test-huanqiu snap1]# /etc/init.d/mysql stop
Shutting down MySQL.... SUCCESS!
[root@test-huanqiu data]# lsof -i:3306
[root@test-huanqiu data]#

現在備份整個資料庫
[root@test-huanqiu snap1]# tar -zvcf /backup/mysql/data/`date +%Y-%m-%d`dbbackup.tar.gz ./
[root@test-huanqiu snap1]# ll /backup/mysql/data/
total 384
-rw-r--r--. 1 root root 392328 Dec 5 22:15 2016-12-05dbbackup.tar.gz

釋放快照卷,每次備份之後,應該刪除快照,減少IO操作
先解除安裝,再刪除
[root@test-huanqiu ~]# umount /var/snap1/
[root@test-huanqiu ~]# df -h                //確認上面的掛載關係已經沒了
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/VolGroup00-LogVol00
8.1G 5.8G 1.9G 76% /
tmpfs 1.9G 0 1.9G 0% /dev/shm
/dev/vda1 190M 37M 143M 21% /boot
/dev/mapper/vg0-lv0 2.9G 115M 2.7G 5% /data/mysql/data
[root@test-huanqiu ~]# lvremove /dev/vg0/snap1
Do you really want to remove active logical volume snap1? [y/n]: y
Logical volume "snap1" successfully removed


資料被快照備份後,可以啟動資料庫
[root@test-huanqiu ~]# /etc/init.d/mysql start
Starting MySQL.. SUCCESS!
[root@test-huanqiu ~]# lsof -i:3306
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
mysqld 15943 mysql 16u IPv4 93348 0t0 TCP *:mysql (LISTEN)
[root@test-huanqiu ~]#

現在再進行新的資料寫入:

mysql> use beijing;
Database changed
mysql> insert into people values("4","liumengnan");
Query OK, 1 row affected (0.02 sec)

mysql> insert into people values("5","zhangjuanjuan");
Query OK, 1 row affected (0.00 sec)

mysql> select * from people;
+------+---------------+
| id   | name          |
+------+---------------+
|    1 | wangshibo     |
|    2 | guohuihui     |
|    3 | wuxiang       |
|    4 | liumengnan    |
|    5 | zhangjuanjuan |
+------+---------------+
5 rows in set (0.00 sec)

mysql> create table heihei(name varchar(20),age varchar(20));
Query OK, 0 rows affected (0.02 sec)

mysql> insert into heihei values("jiujiujiu","nan");
Query OK, 1 row affected (0.00 sec)

mysql> select * from heihei;
+-----------+------+
| name      | age  |
+-----------+------+
| jiujiujiu | nan  |
+-----------+------+
1 row in set (0.00 sec)

mysql> create database shanghai;
Query OK, 1 row affected (0.01 sec)

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| beijing            |
| mysql              |
| performance_schema |
| shanghai           |
| test               |
+--------------------+
6 rows in set (0.00 sec)

假設一不小心誤操作刪除beijing和shanghai庫

mysql> drop database beijing;
Query OK, 2 rows affected (0.03 sec)

mysql> drop database shanghai;
Query OK, 0 rows affected (0.00 sec)

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| test               |
+--------------------+
4 rows in set (0.00 sec)

莫慌!接下來就說下資料恢復操作~~
三、恢復流程如下:
0)由於涉及到增量資料備份,所以提前將最近一次的binlog日誌從mysql資料目錄複製到別的路徑下
1)在mysql資料庫中執行flush logs命令,產生新的binlog日誌,讓日誌資訊寫入到新的這個binlog日誌中
1)關閉資料庫,一定要關閉
2)刪除資料目錄下的檔案
3)快照資料拷貝回來,position節點記錄回放
4)增量資料就利用mysqlbinlog命令將上面提前拷貝的binlog日誌檔案匯出為sql檔案,並剔除其中的drop語句,然後進行恢復。
5)重啟資料

先將最新一次的binlog日誌備份到別處,用作增量資料備份。
比如mysql-bin.000006是最新一次的binlog日誌
[root@test-huanqiu data]# cp mysql-bin.000006 /backup/mysql/data/

產生新的binlog日誌,確保日誌寫入到這個新的binlog日誌內,而不再寫入到上面備份的binlog日誌裡。
mysql> flush logs;

[root@test-huanqiu data]# ll mysql-bin.000007
-rw-rw----. 1 mysql mysql 120 Dec 5 23:19 mysql-bin.000007

[root@test-huanqiu data]# /etc/init.d/mysql stop
Shutting down MySQL.... SUCCESS!
[root@test-huanqiu data]# lsof -i:3306
[root@test-huanqiu data]# pwd
/data/mysql/data
[root@test-huanqiu data]# rm -rf ./*
[root@test-huanqiu data]# tar -zvxf /backup/mysql/data/2016-12-05dbbackup.tar.gz ./

[root@test-huanqiu data]# /etc/init.d/mysql start
Starting MySQL SUCCESS!
[root@test-huanqiu data]# cat /backup/mysql/binlog/binlog.pos
File Position Binlog_Do_DB Binlog_Ignore_DB Executed_Gtid_Set
mysql-bin.000004 1434
[root@test-huanqiu data]# mysqlbinlog --start-position=1434 /data/mysql/data/mysql-bin.000004 | mysql -p123456

登陸資料庫檢視,發現這只是恢復到快照備份階段的資料:

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| beijing            |
| mysql              |
| performance_schema |
| test               |
+--------------------+
5 rows in set (0.00 sec)

mysql> select * from beijing.people;
+------+-----------+
| id   | name      |
+------+-----------+
|    1 | wangshibo |
|    2 | guohuihui |
|    3 | wuxiang   |
+------+-----------+
3 rows in set (0.00 sec)

mysql> 

快照備份之後寫入的資料要利用mysqlbinlog命令將上面拷貝的mysql-bin000006檔案匯出為sql檔案,並剔除其中的drop語句,然後進行恢復。
[root@test-huanqiu ~]# cd /backup/mysql/data/
[root@test-huanqiu data]# ll
total 388
-rw-r--r--. 1 root root 392328 Dec 5 22:15 2016-12-05dbbackup.tar.gz
-rw-r-----. 1 root root 1274 Dec 5 23:19 mysql-bin.000006
[root@test-huanqiu data]# mysqlbinlog mysql-bin.000006 >000006bin.sql

剔除其中的drop語句
[root@test-huanqiu data]# vim 000006bin.sql          //手動刪除sql語句中的drop語句

然後在mysql中使用source命令恢復資料
mysql> source /backup/mysql/data/000006bin.sql;

再次檢視下,發現增量部分的資料也已經恢復回來了

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| beijing            |
| mysql              |
| performance_schema |
| shanghai           |
| test               |
+--------------------+
6 rows in set (0.00 sec)

mysql> use beijing;
Database changed
mysql> show tables;
+-------------------+
| Tables_in_beijing |
+-------------------+
| heihei            |
| people            |
+-------------------+
2 rows in set (0.00 sec)

mysql> select * from people;
+------+---------------+
| id   | name          |
+------+---------------+
|    1 | wangshibo     |
|    2 | guohuihui     |
|    3 | wuxiang       |
|    4 | liumengnan    |
|    5 | zhangjuanjuan |
+------+---------------+
5 rows in set (0.00 sec)

mysql> select * from heihei;
+-----------+------+
| name      | age  |
+-----------+------+
| jiujiujiu | nan  |
+-----------+------+
1 row in set (0.00 sec)

-----------------------------------------------------------------------------------------------------------------
思路:
1)全庫的快照備份只需要在開始時備份一份即可,這相當於全量備份。
2)後續只需要每天備份一次最新的binlog日誌(備份後立即flush logs產生新的binlog日誌),這相當於增量備份了。
3)利用快照備份恢復全量資料,利用備份的binlog日誌進行增量資料恢復
4)crontab計劃任務,每天定時備份最近一次的binlog日誌即可。
----------------------------------------------------------------------------------------------------------------

相關文章