MySQL性能調優與架構設計(四)—— 備份與恢復

前言

  1. 數據庫的備份和恢復一直是DBA工作中最爲重要的一部分,也是基本工作之一。
  2. 任何正式環境的數據庫都必須有完整的備份計劃和恢復測試,本章內容將主要介紹 MySQL數據庫的備份與恢複相關內容。

數據庫備份使用場景

  1. 數據庫的備份很大程度上的作用,就是當我們的數據庫因爲某些原因而造成部分或者全部數據丟失後,方便找回丟失的數據。
  2. 但是不同類型的數據庫備份,所能應付情況是不一樣的,而且,數據庫的備份同時還具有其他很多的作用。
  3. 下面列舉一下需要用到數據庫備份的一些比較常見的情況

    (1)數據丟失應用場景:
        【1】人爲操作失誤造成某些數據被誤操作;
        【2】軟件BUG造成數據部分或者全部丟失;
        【3】硬件故障造成數據庫數據部分或全部丟失;
        【4】安全漏洞被入侵數據被惡意破壞; 
    (2)非數據丟失應用場景 :
        【1】特殊應用場景下基於時間點的數據恢復; 
        【2】開發測試環境數據庫搭建
        【3】相同數據庫的新環境搭建; 
        【4】數據庫或者數據遷移; 

邏輯備份與恢復測試

一、邏輯備份前言

  1. 大家都知道,數據庫在返回數據給我們使用的時候,都是按照我們最初設計期望的具有一定邏輯關聯格式的形式一條一條數據來展現的,具有一定的商業邏輯屬性,而在物理存儲的層面上數據庫軟件卻是按照數據庫軟件所設計的某種特定格式經過一定的處理後存放。
  2. 數據庫邏輯備份就是備份軟件按照我們最初設計的邏輯關係,以數據庫的邏輯結構對象爲單位,將數據庫中的數據按照預定義的邏輯關聯格式一條一條生成相關的文本文件,以達到備份的目的。
  3. 邏輯備份可以說是最簡單,也是目前中小型系統最常用的備份方式。
  4. 在mysql中我們常用的邏輯備份主要就是兩種,一種是將數據生成可以完全重現當前數據庫中數據的INSERT語句,另外一種就是將我們數據庫表數據通過邏輯備份軟件,以特定分隔符進行分隔後記錄在文本文件中。

二、常用的邏輯備份

  1. 生成INSERT語句備份

    (1)在mysql中,我們一般都是通過mysql數據庫軟件自帶工具程序中的mysqldump來實現生成INSERT語句的邏輯備份文件。
    (2)基本使用方法:Dumping definition and data mysql database or table
    mysqldump [OPTIONS] database [tables] 
    OR   mysqldump [OPTIONS] --databases [OPTIONS] DB1 [DB2 DB3...] 
    OR   mysqldump [OPTIONS] --all-databases [OPTIONS] 
    (3)由於mysqldump的使用方法比較簡單,大部分需要的信息都可以通過運行“mysqldump --help”而獲得。
    (4)這裏我只想結合MySQL數據庫的一些概念原理和大家探討一下當我們使用mysqldump來做數據庫邏輯備份的時候有些什麼技巧以及需要注意一些什麼內容。
    (5)我們都知道,對於大多數使用數據庫的軟件或者網站來說,都希望自己數據庫能夠提供儘可能高的可用性,而不是時不時的就需要停機停止提供服務。
    (6)因爲一旦數據庫無法提供服務,系統就無法再通過存取數據來提供一些動態功能。
    (7)所以對於大多數系統來說如果要讓每次備份都停機來做可能都是不可接受的,可是mysqldump程序的實現原理是通過我們給的參數信息加上數據庫中的系統表信息來一個表一個表獲取數據然後生成INSERT語句再寫入備份文件中。
    (8)這樣就出現了一個問題,在系統正常運行過程中,很可能會不斷有數據變更的請求正在執行,這樣就可能造成在ymsqldump備份出來的數據不一致。
    (9)也就是說備份數據很可能不是同一時間點的數據,而且甚至可能都沒辦法滿足完整性約束。
    (10)這樣的備份集對於有些系統來說可能並沒有太大問題,但是對於有些對數據的一致性和完整性要求比較嚴格系統來說問題就大了,就是一個完全無效的備份集。
    (11)對於如此場景,我們該如何做?我們知道,想數據庫中的數據一致,那麼只有兩種情況下可以做到:
        【1】同一時刻取出所有數據
             「1」對於第一種情況,我們可能會問,這可能嗎?不管如何,只要有兩個以上的表,就算我們如何寫程序,都不可能做到完全一致的取數時間點。
             「2」是的,我們確實無法通過常規方法讓取數的時間點完全一致,但是大家不要忘記,在同一個事務中,數據庫是可以做到所讀取的數據是處於同一個時間點的。
             「3」所以,對於事務支持的存儲引擎,如Innodb或者BDB等,我們就可以通過控制將整個備份過程控制在同一個事務中,來達到備份數據的一致性和完整性,而且mysqldump程序也給我們提供了相關的參數選項來支持該功能,就是通過“--single-transaction”選項,可以不影響數據庫的任何正常服務。
        【2】數據庫中的數據處於靜止狀態。
             「1」此種情況,需要將備份的表鎖定,只允許讀取而不允許寫入。
             「2」讓數據庫在備份過程中僅提供數據的查詢服務,鎖定寫入的服務,來使數據暫時處於一個一致的不會被修改的狀態,等mysqldump完成備份後再取消寫入鎖定,重新開始提供完整的服務。
             「3」mysqldump程序自己也提供了相關選項如“--lock-tables”和“--lock-all-tables”,在執行之前會鎖定表,執行結束後自動釋放鎖定。
             「4」這裏有一點需要注意,“--lock-tables”並不是一次性將需要dump的所有表鎖定,而是每次僅僅鎖定一個數據庫的表,如果你需要備份的表在不同的數據庫中,一定要使用“--lock-all-tables”才能確保數據的一致完整性。
    (12)一個非常有用的參數“--master-data[=value]”
        【1】當通過mysqldump生成INSERT語句的備份文件的時候,有一個非常有用的選項可以供我們使用,那就是“--master-data[=value]”。
        【2】當添加了“--master-data=1”的時候,mysqldump會將當前mysql使用到binlog日誌的名稱和位置記錄到dump文件中,並且是以CHANGE_MASTER語句的形式記錄,如果僅僅只是使用“--master-data”或者“--master-data=2”,則CHANGE_MASTER語句會以註釋形式存在。
        【3】這個選項在實時slave的在線搭建的時候是非常有用的,即使不是進行在線搭建slave,也可以在某些情況下做恢復的過程中通過備份的binlog做進一步恢復操作。
    (13)參數“--where=where-condition”
        【1】在某些場景下,我們可能只是爲了將某些特殊的數據導出到其他數據庫中,而又不希望通過先建臨時表的方式來實現,我們還可以通過mysqldump的“--where=where-condition”來實現;
        【2】此參數只能在只dump一個表的情況下使用
    (14)其他參數:
        【1】“no-data“參數僅僅dump數據庫結構創建腳本
        【2】“--no-create-info“去掉dump文件中創建表結構的命令
  2. 生成特定格式的純文本備份數據文件備份

    (1)除了生成INSERT命令來做邏輯備份之外,我們還可以通過另外一種方式將數據庫中的數據以特定分隔符將數據分隔記錄在文本文件中,以達到邏輯備份的效果。
    (2)這樣的備份數據與INSERT命令文件相比,所需要使用的存儲空間更小,數據格式更加清晰明確,編輯方便。
    (3)缺點是同一個備份文件中不能存在多個表的備份數據,沒有數據庫結構的重建命令。
    (4)對於備份集需要多個文件,對我們產生的影響就是文件多了維護和恢復成本增加,但這些基本上都可以通過編寫一些簡單的腳本來實現。
    (5)生成這樣的備份集方法:
        【1】通過執行SELECT ... TO OUTFILE FROM ...命令來實現
             「1」mysql中提供了一種SELECT語法,專供用戶通過sql語句將某些數據以指定格式輸出到文本文件中,同時也提供了實用工具和相關命令可以方便的將導出文件原樣再倒入到數據庫中。
             「2」該命令有幾個參數需要注意:
                  《1》實現字符轉義功能的“FIELDS ESCAPED BY ['name']”將語句中需要轉義的字符進行轉義;
                  《2》可以將字段的內容包裝起來的“FIELDS [OPTIONALLY] ENCLOSED BY 'name'”,如果不使用“OPTIONALLY”則包括數字類型的所有類型數據都會被“包裝”,使用“OPTIONALLY”之後,則數字類型的數據不會被指定字符“包裝”。 
                  《3》通過"FIELDS TERMINATED BY"可以設定每兩個字段之間的分隔符;
                  《4》而通過“LINES TERMINATED BY”則會告訴MySQL輸出文件在每條記錄結束的時候需要添加什麼字符。
        【2】通過mysqldump導出 
             「1」可能我們都知道mysqldump可以將數據庫中的數據以INSERT語句的形式生成相關備份文件,其實除了生成 INSERT語句之外,mysqldump還同樣能實現上面“SELECT ... TO OUTFILE FROM ...”所實現的功能,而且同時還會生成一個相關數據庫結構對應的創建腳本。
             「2」如果一次有多個表需要dump,就會針對每個表都會生成兩個相對應的文件。
             「3」mysqldump -uroot -T/tmp/mysqldump test test_outfile --fields-enclosed-by=\" --fields-terminated-by=,

三、邏輯備份的恢復方法

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