天天看點

InnoDB 個性化備份

常用的備份有哪些

InnoDB 個性化備份

性能對比

InnoDB 個性化備份

邏輯備份 vs 實體備份

如何選擇,全憑業務場景

實體備份:innodb vs myisam

myisam引擎,隻需要flush tables後,就可以随意拷貝檔案 innodb可通過xtrabackup來拷貝檔案
簡單來說,就是備份的資料都處在同一時間點
InnoDB 個性化備份
InnoDB 個性化備份
innobackupex 是一個perl寫的腳本,為了友善,封裝了xtrabackup,是以一般備份都用innobackupex xtrabackup 隻備份innodb表 ,其餘的都交給innobackupex 新版本如:2.4,2.3.xx 已經将innodbex用c 重寫了,然後連結到xtrabackup
innobackupex 調用 xtrabackup --suspend-at-end xtrabackup 開始拷貝 innodb 資料檔案,共享表空間 當xtrabackup拷貝完innodb檔案後,會建立 xtrabackup_suspended_2 當innobackupex看到xtrabackup_suspended_2檔案被建立後,進行加鎖 flush no_write_to_binlog tables flush tables with read lock innobackupex開始檢查db server支援的特性,如:gtid,backup locks,changed page bitmap等 然後開始拷貝非innodb檔案,以及表結構frm 當所有的檔案都備份完成後,結束redo 事務的拷貝。 接下來釋放鎖 flush no_write_to_binlog engine logs unlock tables 删除xtrabackup_suspended_2檔案 , 并且退出
InnoDB 個性化備份

從上述流程圖可以看出,flush tables with read lock【ftwrl】 這個時間點,就是備份恢複的時間點,即一緻性點

因為資料再拷貝的過程中是不一緻的,mysql利用其自身的crash recover機制,用redo來保證最終一緻性

這裡,假設一種場景,innodb是16k的重新整理,當重新整理到4k的時候,拷貝線程來講這個頁拷貝走,這樣不就人為的造成了一次partial-write了嗎?

對于partial-write的場景,由于redo日志是實體邏輯的,通過redo沒有辦法恢複,這可如何是好呢?

這裡是核心:

xtrabackup方式: xtrabackup裡面做了很多事情,它在拷貝的過程中使用innodb的buf_page_is_corrupted()函數檢查此頁的資料是否正常,如果不正常,再重新拷貝,嘗試n次重試之後還不行,就退出報錯。

flush-method=o_direct,會直接從innodb buffer 寫入到 磁盤,這個操作可能就會發生partial-write了。一旦發生這樣的事情,mysql是無法恢複的,是以,我們的備份必須保證髒頁全部重新整理完,也就是在備份程式中 a)必須保證沒有寫了 b)必須驗證和檢測modified db pages是否等于0。 如果以上都ok,那麼這個頁肯定是完整的。除此之外,我們還有一招,就是多次rsync,確定完整。

flush-method=預設 , 預設的會先從innodb buffer 寫入到 os緩存,這個操作是原子的,由作業系統保證。

備份的意圖:備份master或者slave上的資料,然後傳輸到一個挂有大磁盤的伺服器上,保留若幹天

這個問題,xtrabackup也考慮到了,用xbstream + ssh 的方式,但是有一個緻命的缺點,就是無法斷點續傳,如果網絡斷掉,那就悲劇

另外一個方式就是:先xtrabackup到本地一個目錄,然後用rsync【支援斷點續傳】來傳送到遠端伺服器。 這種方法的緻命缺點是:本地磁盤需要浪費一半的空間,且copy了兩遍備份資料

以上兩種方式都存在缺陷,那麼我們不得不思考第三種方式,是否可以直接copy到遠端機器呢?

如果是在master上備份,那麼直接copy是不行的,因為redo一直再變且輪詢

InnoDB 個性化備份

如果是在slave上,或者etl&backup機器上呢? 不難發現,xtrabackup記錄了redo的變化,如果我們人為的讓redo不再增長,stop slave,這樣的備份原理是否和xtrabackup一樣呢?

InnoDB 個性化備份

這樣做的好處是,不用浪費一半的空間,也不需要傳送2次

InnoDB 個性化備份

通過以上流程圖,可以發現一個重要的線索:我們的實體備份,是不會備份binlog的【重要】

是以,友誼的小船說翻就翻

InnoDB 個性化備份

對于5.1 & 5.5,用xtrabackup for 5.1 or 5.5 ,如果innodb_flush_log_at_trx_commit=1 ,應該沒問題

InnoDB 個性化備份

對于5.6 , 用xtrabackup for 5.1 or 5.5 , 即便如果innodb_flush_log_at_trx_commit=1,有可能會丢失事務

InnoDB 個性化備份

對于5.6 , 用xtrabackup for 5.6, 不會丢失事務

好了,現在進入正題,我們是否可以類似myisam的方式随意拷貝呢?

答案:可以

第一種方法: 保持和myiam一緻就可以。

myisam之是以可以随意拷貝,那是因為通過flush tables後,所有檔案都會fsync到磁盤,這時候拷貝肯定沒有問題。 innodb則不是,通過flush tables根本沒有辦法控制redo的重新整理,data page的重新整理以及ibdata的重新整理。 是以,這裡我們隻要解決這三個問題即可。 redo: 我們可以通過innodb_flush_log_at_trx_commit=1來保證。 data page: 通過自身的checkpoint可以保證。 ibdata裡面包含了:innodb table的資料字典資訊,change buffer,doublewrite ,undo logs,這些目前好像還沒有什麼可以強制全部重新整理。

是以,我們可以通過stop slave的方式,至少可以保證資料不丢失。至于ibdata裡面的檔案不重新整理,也沒太大關系,通過自身的crash-recover機制,自動修複。

是以,我們通過stop slave後,直接copy檔案恢複的時候,你可能會看到這樣的資訊:

當你看到crash recovery finished完成後,基本也就ok了。

好了,這裡還有一個疑問我不太清楚,就是到底有多少個lsn

那麼錯誤日志中的the log sequence numbers xx in ibdata files ,又是啥呢?

經過測試:kill -9 mysqld

得到的結論是: 隻要是非正常關閉的mysql,都會出現這樣的報錯,即便是沒有任何資料的mysql

是以,我猜測,ibdata files中記錄的lsn,從mysql一啟動,裡面的lsn就會比redo中的lsn小,是專用于檢測是否正常關閉mysql的嗎?

anyway,這都不影響我們innodb線上拷貝的大局了。

好了,通過以上測試,我們已經明白,stop slave後,等一會會,當髒頁重新整理完的時候,就可以認為資料全部重新整理到磁盤了,這樣就和myisam沒有任何差別

ok,這裡又引入了一個值得思考的問題,那就是: 怎麼判斷髒頁已經刷完了呢?

檢查4個lsn,當四個lsn都相等的時候,肯定刷完了。
檢查modified db pages的值,這個值就表示flush list中還有多少個page沒有被重新整理,如果全為0,表示flush list中髒頁全部重新整理。

第二種方式

stop slave後,如果髒頁沒有重新整理完呢?不相等,我們還能拷貝嗎?

答案是:當然可以。

lsn不相等,意味着,我們crash-recover的時候需要通過redo來恢複資料,稍微慢點而已,不影響大局。

是以,不管以上兩種方式的哪一種,如果你想通過stop slave的方式,直接拷貝檔案的話,最好執行下

這樣,就跟xtrabackup沒什麼差別了

xtrabackup 在什麼版本恢複的時候,可能會丢失最後一個事務

innodb 檔案 和 非innodb 檔案的備份,都是通過拷貝檔案的方式來做的,其中有什麼不同嗎?

資料恢複的原理的是什麼

xtrabackup的詳細流程細化