歡迎您光臨本站 註冊首頁

[MySQL性能調優] MYSQL大容量庫的備份策略

←手機掃碼閱讀     火星人 @ 2014-03-03 , reply:0

[MySQL性能調優] MYSQL大容量庫的備份策略

MYSQL大容量庫的備份策略















這兩天看了有關LVM快照(snapshot)的一些資料,加上pczou的一些指導,對snapshot有一些理解,記錄如下,和大家共享:

Logical Volume Manager (LVM)提供了對任意一個Logical Volume(LV)做「快照」(snapshot)的功能,以此來獲得一個分區的狀態一致性備份。
在某一個狀態下做備份的時候,可能有應用正在訪問某一個文件或者資料庫,這就是使得備份的時候文件處於一個狀態,而備份完后,文件卻處於另外一個狀態,從而造成備份的非一致性,這種狀態恢復資料庫數據幾乎不會成功。

狀態的解決辦法是將其分區掛載為只讀,然後通過資料庫的表級別鎖定(table-level write locks)甚至停止資料庫來備份數據。所有這些方法無意嚴重影響了服務的可用性。使用LVM snapshot既可以獲得一致性備份,又不會影響伺服器的可用性。

要提醒一點是,snapshot這種方法僅對LVM有效,對於非LVM文件系統無效。

snapshot的實現有多種方式(參考文章最後的連接),這裡說說LVM中snapshot的「寫時複製」(copy on write) 的實現方法。

當 一個snapshot創建的時候,僅拷貝原始卷里數據的元數據(meta-data)。創建的時候,並不會有數據的物理拷貝,因此snapshot的創建 幾乎是實時的,當原始卷上有寫操作執行時,snapshot跟蹤原始卷塊的改變,這個時候原始卷上將要改變的數據在改變之前被拷貝到snapshot預留 的空間里,因此這個原理的實現叫做寫時複製(copy-on-write)。

在寫操作寫入塊之前,CoW講原始數據移動到 snapshot空間里,這樣就保證了所有的數據在snapshot創建時保持一致。而對於snapshot的讀操作,如果是讀取數據塊是沒有修改過的, 那麼會將讀操作直接重定向到原始卷上,如果是要讀取已經修改過的塊,那麼就讀取拷貝到snapshot中的塊。

這樣,通常的文件I/0流程有一個改變,那就是在文件系統和設備驅動之間增加了一個cow層,變成了下面這個樣子:

file I/0 ?> filesystem ? >CoW ?> block I /O

下面的圖也許可以比較容易了解CoW的原理:


采 取CoW實現方式時,snapshot的大小並不需要和原始卷一樣大,其大小僅僅只需要考慮兩個方面:從shapshot創建到釋放這段時間內,估計塊的 改變數有多大;數據更新的頻率。一旦 snapshot的空間記錄滿了原始卷塊變換的信息,那麼這個snapshot立刻被釋放,從而無法使用,從而導致這個snapshot無效。所以,非常 重要的一點,一定要在snapshot的生命周期里,做完你需要做得事情。當然,如果你的snapshot大小和原始卷一樣大,甚至還要大,那它的壽命就 是「與天齊壽」了。

snapshot其實除了備份以外,還有很多其他用途

1)虛擬化

在使用 LVM2 時,快照可以不是只讀的。這意味著,在創建快照之後, 可以像常規塊設備一樣掛載和讀寫快照。

因 為流行的虛擬化系統(比如 Xen、VMWare、Qemu 和 KVM)可以將塊設備用作 guest 映像,所以可以創建這些映像的完整拷貝,並根據需要使用它們,它們就像是內存佔用量很低的虛擬機。這樣做的好處是部署迅速(創建快照的時間常常不超過幾 秒)和節省空間(guest 共享原映像的大多數數據)。

設置的步驟如下:

   1. 為原映像創建一個邏輯卷。
    2. 使用這個 LV 作為磁碟映像安裝 guest 虛擬機。
    3. 暫停這個虛擬機。內存映像可以是一個常規文件,所有其他快照都放在裡面。
    4. 為原 LV 創建一個可讀寫的快照。
    5. 使用快照卷作為磁碟映像生成一個新的虛擬機。如果需要的話,要修改網路/控制台設置。
    6. 登錄已經創建的虛擬機,修改網路設置/主機名。

完成這些步驟之後, 就可以讓用戶訪問剛創建的虛擬機了。如果需要另一個虛擬機,那麼只需重複步驟 4 到 6(所以不需要重新安裝虛擬機)。還可以用一個腳本自動執行這些步驟。

在使用完虛擬機之後, 可以停止虛擬機並銷毀快照。

2)數據回溯

在 一個生產系統上要執行一些操作,需要慎之又慎,即便在模擬環境中做過很多次測試都沒有問題,但是並不能保證在生產環境就一定成功,於是這個時候,我們把系 統做一個snapshot,這樣一旦新操作出現問題,立刻回溯到創建snapshot的時間點,當然你也可以認為這是一個備份的擴展使用。

最後,我們舉一些例子,加深對snapshot的理解。

a) 創建一個20M的snapshot,執行一些操作看看CoW的動作。

我們舉一個例子來說明如何創建和使用snapshot。我們假定創建一個20M的snapshot,這就意味著在snapshot生命周期里,你僅能有20M的數據量改變。

下面的命令,為/dev/vg/lvdata創建/dev/vg/lvdata-sp

# lvcreate -L20M -s -n lvdata-sp /dev/vg/lvdata
Logical volume 「lvdata-sp」 created

其中lvdata大小為120MB。
# lvdisplay /dev/vg/lvdata-sp
? Logical volume ?
LV Name /dev/vg/lvdata-sp
VG Name vg
LV UUID Yl0fQU-Ve9T-lfmp-xJPq-Uwrd-RVVM-lDDVz0
LV Write Access read/write
LV snapshot status active destination for /dev/vg/lvdata
LV Status available
# open 1
LV Size 200.00 MB
Current LE 50
COW-table size 20.00 MB
COW-table LE 5
Allocated to snapshot 0.27%
Snapshot chunk size 8.00 KB
Segments 1
Allocation inherit
Read ahead sectors 0
Block device 253:0上面的 Allocated to snapshot 0.27%是我們關心的,表示目前還有99.73%的空間沒有使用。

我們嘗試在lvdata創建一個10M的文件,再看看這個參數值。# mount /dev/vg/lvdata /media/lvdata/
# dd if=/dev/hda of=/media/lvdata/10M bs=1M count=10
10+0 records in
10+0 records out
10485760 bytes (10 MB) copied, 0.272393 seconds, 38.5 MB/s
# lvdisplay /dev/vg/lvdata-sp
? Logical volume ?
LV Name /dev/vg/lvdata-sp
VG Name vg
LV UUID Yl0fQU-Ve9T-lfmp-xJPq-Uwrd-RVVM-lDDVz0
LV Write Access read/write
LV snapshot status active destination for /dev/vg/lvdata
LV Status available
# open 0
LV Size 200.00 MB
Current LE 50
COW-table size 20.00 MB
COW-table LE 5
Allocated to snapshot 51.02%
Snapshot chunk size 8.00 KB
Segments 1
Allocation inherit
Read ahead sectors 0
Block device 253:0」Allocated to snapshot 51.02%「,符合我們的預期。此時snapshot還剩下大概10M不到的空間了,如果我么再在lvdata上創建一個12M的文件,會發生什麼呢?
#dd if=/dev/hda of=/media/lvdata/12M bs=1M count=12
12+0 records in
12+0 records out
12582912 bytes (13 MB) copied, 0.288311 seconds, 43.6 MB/s
device-mapper: snapshots: Invalidating snapshot: Unable to allocate exception.創建文件的過程中,一個報錯出現了,snapshot已經無效。我們看看snapshot卷的詳細信息。# lvdisplay /dev/vg/lvdata-sp
/dev/vg/lvdata-sp: read failed after 0 of 4096 at 0: 輸入/輸出錯誤
? Logical volume ?
LV Name /dev/vg/lvdata-sp
VG Name vg
LV UUID Yl0fQU-Ve9T-lfmp-xJPq-Uwrd-RVVM-lDDVz0
LV Write Access read/write
LV snapshot status INACTIVE destination for /dev/vg/lvdata
LV Status available
# open 0
LV Size 200.00 MB
Current LE 50
COW-table size 20.00 MB
COW-table LE 5
Snapshot chunk size 8.00 KB
Segments 1
Allocation inherit
Read ahead sectors 0整個snapshot卷已經出現I/0錯誤了,而且snapshot的狀態也是「INACTIVE」。

是否能掛載上來呢?# mount /dev/vg/lvdata-sp /media/snapshot/
mount: you must specify the filesystem type
#dmesg
Buffer I/O error on device dm-0, logical block 0
Buffer I/O error on device dm-0, logical block 1
Buffer I/O error on device dm-0, logical block 2
Buffer I/O error on device dm-0, logical block 3
Buffer I/O error on device dm-0, logical block 4
Buffer I/O error on device dm-0, logical block 5
Buffer I/O error on device dm-0, logical block 6
Buffer I/O error on device dm-0, logical block 7
Buffer I/O error on device dm-0, logical block 8
Buffer I/O error on device dm-0, logical block 9
hfs: unable to find HFS+ superblock從dmesg的錯誤信息來看,超級塊的信息也丟失了

嘗試激活一下lvdata-sp

# lvchange -ay /dev/vg/lvdata-sp
/dev/vg/lvdata-sp: read failed after 0 of 4096 at 0: 輸入/輸出錯誤

恩,這個snapshot已經被釋放了,所以剩下要做得事情就是刪除它。# lvremove /dev/vg/lvdata-sp
/dev/vg/lvdata-sp: read failed after 0 of 4096 at 0: 輸入/輸出錯誤
Do you really want to remove active logical volume 「lvdata-sp」? : y
Logical volume 「lvdata-sp」 successfully removedb)利用snapshot在線備份MySQL資料庫(或者其他資料庫)

流程是先做一個flush操作,並鎖定表,任何創建snapshot,任何解鎖,然後備份數據,最後釋放snapshot。這樣,MySQL幾乎不會中斷其運行。

FLUSH TABLES WITH READ LOCK;
lvcreate ?size 100m ?snapshot ?name snap /dev/VolGroup01/LogVol00
UNLOCK TABLES;

接著做一些備份的工作mkdir /snap
mount /dev/VolGroup01/snap /snap
# This is where you back up whatever you need from /snap, e.g. rsync(1)
umount /snap
lvremove /dev/VolGroup01/snap
rmdir /snap
備份實例


# cat backup.sh01.#!/bin/bash

02.#backup mysql database

03.#create with huzi at  2008-12-29

04.MYSQL="/usr/local/mysql/bin/mysql"

05.$MYSQL -u root -pmysql<<EOF

06.flush tables with read lock;

07.system lvcreate -L 20M -s --name snap /dev/vg0/data

08.unlock tables;

09.system mount /dev/vg0/snap /mnt

10.system rm -rf /root/mysql_back/mysql`date +%Y-%m-%d -d'1 days ago'`

11.system mkdir /root/mysql_back/mysql`date +%Y-%m-%d`

12.system cp -ar /mnt/mysql/* /root/mysql_back/mysql`date +%Y-%m-%d`

13.system umount /mnt

14.system echo "y" | lvremove /dev/vg0/snap

15.exit

16.EOF
複製代碼
# cat backup.sh#!/bin/bash
#backup mysql database
#create with huzi at 2008-12-29
MYSQL="/usr/local/mysql/bin/mysql"
$MYSQL -u root -pmysql<<EOF  -------------------定義重定向輸入
flush tables with read lock; -------------------------鎖表
system lvcreate -L 20M -s --name snap /dev/vg0/data -------------------MYSQL system 命令調用系統命令生成LVM數據卷的快照
unlock tables; ---------------------解鎖
system mount /dev/vg0/snap /mnt  ------------------------MYSQL system 命令調用 系統mount 掛載到/mnt目錄
system rm -rf /root/mysql_back/mysql`date +%Y-%m-%d -d'2 days ago'` ---------------------------刪除 兩天前的數據
system mkdir /root/mysql_back/mysql`date +%Y-%m-%d` ------------------建立新的目錄
system cp -ar /mnt/mysql/* /root/mysql_back/mysql`date +%Y-%m-%d` ------------------直接CP文件到現有的新建立的目錄上
system umount /mnt ---------------umount /mnt目錄
system echo "y" | lvremove /dev/vg0/snap  ---------------刪除LVM快照
exit ------------------退出MYSQL SHELL
EOF   --------------------重定向輸入結束
《解決方案》

學習鳥  謝謝分享
《解決方案》

回復 1# 聽老歌

樓主我問一下,這個snapshot是不是在對data下的庫結構進行備份?

    
   
《解決方案》

ls的,snapshot是lvm的快照,不是資料庫的.

[火星人 ] [MySQL性能調優] MYSQL大容量庫的備份策略已經有693次圍觀

http://coctec.com/docs/service/show-post-294.html