mysql進階篇(三種備份方法總結:lvm, mysqldump, xtrabackup)

二進制日志詳解:

    二進制日志通常作為備份的重要資源,所以再說備份之前先總結一下二進制日志的相關內容 

    1. 二進制日志的內容

        引起mysql服務器改變的任何操作。

        復制功能依賴于此日志。

        從服務器通過復制主服務器的二進制日志完成主從復制,在執行之前保存于中繼日志中。 

        從服務器通??梢躁P閉二進制日志以提升性能。

    2. 二進制文件的文件表現形式: 

        默認在安裝目錄下,存在mysql-bin.00001, mysql-bin.00002的二進制文件

        另外還有mysql-bin.index用來記錄被mysql管理的二進制文件列表

        如果需要刪除二進制日志時,切勿直接刪除二進制文件,這樣會使得mysql管理混亂 

    3. 二進制文件查看相關mysql命令。 

        SHOW MASTER STATUS ; 查看正在使用的二進制文件 

            MariaDB [(none)]> SHOW MASTER STATUS ;         
                +------------------+----------+--------------+------------------+
                | File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |
                +------------------+----------+--------------+------------------+
                | mysql-bin.000003 |      245 |              |                  |
                +------------------+----------+--------------+------------------+

         FLUSH LOGS; 手動滾動二進制日志 

            MariaDB [(none)]> FLUSH LOGS;            
            MariaDB [(none)]> SHOW MASTER STATUS ; 
                +------------------+----------+--------------+------------------+
                | File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |
                +------------------+----------+--------------+------------------+
                | mysql-bin.000004 |      245 |              |                  |
                +------------------+----------+--------------+------------------+
            滾動以后,mysql重新創建一個新的日志mysql-bin.000004

        SHOW BINARY LOGS 顯示使用過的二進制日志文件

            MariaDB [(none)]> SHOW BINARY LOGS ;            
                +------------------+-----------+
                | Log_name         | File_size |
                +------------------+-----------+
                | mysql-bin.000001 |     30373 |
                | mysql-bin.000002 |   1038814 |
                | mysql-bin.000003 |       288 |
                | mysql-bin.000004 |       245 |

        SHOW BINLOG EVENTS 以表的形式查看二進制文件

            SHOW BINLOG EVENTS [IN 'log_name'] [FROM pos] [LIMIT [offset,] row_count]                
                MariaDB [(none)]> SHOW BINLOG EVENTS IN 'mysql-bin.000001' \G;
                *************************** 99. row ***************************
                   Log_name: mysql-bin.000001
                Pos: 30225
                 Event_type: Query
                  Server_id: 1
                End_log_pos: 30354
                   Info: use `mysql`; DROP TEMPORARY TABLE `tmp_proxies_priv` /* generated by server */

    4. MySQL二進制文件讀取工具mysqlbinlog 

        Usage: mysqlbinlog [options] log-files            
            --start-datetime
            --stop-datetime
            --start-position
            --stop-position
        # mysqlbinlog --start-position 30225 --stop-position 30254  mysql-bin.000001            
        截取一下結果: 
            # at 30225
            #151130 12:43:35 server id 1  end_log_pos 30354 Querythread_id=1exec_time=0error_code=0
            use `mysql`/*!*/;
            SET TIMESTAMP=1448858615/*!*/;
            SET @@session.pseudo_thread_id=1/*!*/
        根據以上截取結果第二行,進行解釋二進制日志內容            
            1) 時間點: 151130 12:43:35
            2) 服務器ID: server id 1
            服務器ID主要用于標記日志產生的服務器,主要用于雙主模型中,互為主從,確保二進制文件不會被相互循環復制
            3) 記錄類型: Query  
            4) 線程號: thread_id = 1 
            5) 語句的時間戳和寫入二進制日志文件的時間差; exec_time=0 
            6) 事件內容
            7) 事件位置 #at 30225 
            8) 錯誤代碼 error_code=0 
            9) 事件結束位置 end_log_pos也就是下一事件開始的位置

    5. 二進制日志格式

        由bin_log_format={statement|row|mixed}定義 

            1) statement: 基于語句,記錄生成數據的語句 

                缺點在于如果當時插入信息為函數生成,有可能不同時間點執行結果不一樣,

                例如: INSERT INTO t1 VALUE (CURRENT_DATE());

            2) row: 基于行數據

                缺點在于,有時候數據量會過大

            3) mixed: 混合模式,又mysql自行決定何時使用statement, 何時使用row 模式

    6. 二進制相關參數總結

            1) log_bin = {ON|OFF} 

                還可以是個文件路徑,主要用于控制全局binlog的存放位置和是否開啟

            2) log_bin_trust_function_creators

                是否記錄在

            3) sql_log_bin = {ON|OFF}

                會話級別是否關閉binlog, 如果關閉當前會話內的操作將不會記錄

            4) sync_binlog 是否馬上同步事務類操作到二進制日志中

            5) binlog_format = {statement|row|mixed} 二進制日志的格式,上面單獨提到了

            6) max_binlog_cache_size = 

                二進制日志緩沖空間大小,僅用于緩沖事務類的語句;

        7) max_binlog_stmt_cache_size =

            語句緩沖,非事務類和事務類共用的空間大小

        8) max_binlog_size = 

            二進制日志文件上限,超過上限后則滾動

        9) 刪除二進制日志 

              PURGE { BINARY | MASTER } LOGS { TO 'log_name' | BEFORE datetime_expr }

      MariaDB> PURGE BINARY LOGS TO 'mysql-bin.010';            
      MariaDB> PURGE BINARY LOGS BEFORE '2008-04-02 22:46:26';
       建議:切勿將二進制日志與數據文件放在一同設備;

二進制日志備份和恢復: 

    為什么做備份: 

        1. 災難恢復 

        2. 審計,數據庫在過去某一個時間點是什么樣的 

        3. 測試 

    備份的目的: 

        1. 用于恢復

        2. 備份結束后,需要周期性的做恢復測試

    備份類型: 

        1. 根據備份時,服務器是否在線

            1) 冷備(cold backup): 服務器離線,讀寫操作都不能進行 

            2) 溫備份: 全局施加共享鎖,只能讀不能寫

            3) 熱備(hot backup):數據庫在線,讀寫照樣進行 

        2. 根據備份時的數據集分類 

            1) 完全備份(full backup)

            2) 部分備份(partial backup)

        3. 根據備份時的接口 

            1) 物理備份(physical backup): 直接復制數據文件 ,打包歸檔

                特點: 

                不需要額外工具,直接歸檔命令即可,但是跨平臺能力比較差

                如果數據量超過幾十個G,則適用于物理備份

            2) 邏輯備份(logical backup): 把數據抽取出來保存在sql腳本中

                特點: 

                可以使用文本編輯器編輯

                導入方便,直接讀取sql語句即可

                邏輯備份恢復時間慢,占據空間大

                無法保證浮點數的精度

                恢復完數據庫后需要重建索引

        4. 根據備份整個數據還是變化數據 

            1) 完全備份 full backup  

            2) 增量備份 incremental backup 

                    在不同時間點起始備份一段數據

                    比較節約空間

            3) 差異備份  differential backup 

                    備份從每個時間點到上一次全部備份之間的數據,隨著時間增多二增多 

                    比較容易恢復

                    對于很大的數據庫,可以考慮主從模型,備份從服務器的內容。

        5. 備份策略,需要考慮因素如下

            備份方式 

            備份實踐

            備份成本

            鎖時間

            時長

            性能開銷

            恢復成本

            恢復時長

            所能夠容忍丟失的數據量

        6. 備份內容 

            1) 數據庫中的數據

            2) 配置文件 

            3) mysql中的代碼: 存儲過程,存儲函數,觸發器

            4) OS 相關的配置文件,chrontab 中的備份策略腳本

            5) 如果是主從復制的場景中: 跟復制相關的信息

            6) 二進制日志文件需要定期備份,一旦發現二進制文件出現問題,需馬上對數據進行完全備份

        7. 常用備份工具 

            1)mysqldump: 邏輯備份工具

                innodb: 熱備,溫備

                MyISAM, Aria: 溫備 

                單線程備份恢復比較慢

            2)mysqldumper: 多線程的mysqldump 

            3)vm-snapshot: 

                接近于熱備的工具:因為要先請求全局鎖,而后創建快照,并在創建快照完成后釋放全局鎖;

                使用cp、tar等工具進行物理備份;

                備份和恢復速度較快;

                很難實現增量備份,并且請求全局需要等待一段時間,在繁忙的服務器上尤其如此;

            4)SELECT clause INTO OUTFILE '/path/to/somefile'

                  LOAD DATA INFILE '/path/from/somefile'

                    部分備份工具, 不會備份關系定義,僅備份表中的數據;

                    邏輯備份工具,快于mysqldump,因為不備份表格式信息

            5)Innobase: 商業備份工具, innobackup

                InnoDB熱備,增量備份;

                MyISAM溫備,不支持增量,只有完全備份 

                        屬于物理備份,速度快;

            6)Xtrabackup: 由Percona提供的開源備份工具

                InnoDB熱備,增量備份;

                MyISAM溫備,不支持增量;

            7)mysqlhotcopy: 接近冷備,基本沒用 

mysqldump工具基本使用

    1. mysqldump [OPTIONS] database [tables…]

        還原時庫必須存在,不存在需要手動創建

    --all-databases: 備份所有庫    
    --databases db1 db2 ...: 備份指定的多個庫,如果使用此命令,恢復時將不用手動創建庫
    --lock-all-tables:請求鎖定所有表之后再備份,對MyISAM、InnoDB、Aria做溫備
    --lock-table: 對正在備份的表加鎖,但是不建議使用,如果其它表被修改,則備份后表與表之間將不同步
    --single-transaction: 能夠對InnoDB存儲引擎實現熱備;
      啟動一個很大的大事物,基于MOCC可以保證在事物內的表版本一致
      自動加鎖不需要,再加--lock-table, 可以實現熱備
備份代碼:
    --events: 備份事件調度器代碼
    --routines: 備份存儲過程和存儲函數
    --triggers:備份觸發器
備份時滾動日志:
    --flush-logs: 備份前、請求到鎖之后滾動日志;
      方恢復備份時間點以后的內容
復制時的同步位置標記:主從架構中的,主服務器數據。效果相當于標記一個時間點。
    --master-data=[0|1|2]
    0: 不記錄
    1:記錄為CHANGE MASTER語句
    2:記錄為注釋的CHANGE MASTER語句

    2. 使用mysqldump備份大體過程:

        1) 請求鎖:–lock-all-tables或使用–singe-transaction進行innodb熱備;

        2) 滾動日志:–flush-logs

        3) 選定要備份的庫:–databases

        4) 記錄二進制日志文件及位置:–master-data=

            FLUSH TABLES5 WITH READ LOCK; 

    3. 恢復:

        恢復過程無需寫到二進制日志中 

        建議:關閉二進制日志,關閉其它用戶連接;

    4. 備份策略:基于mysqldump

    備份:mysqldump+二進制日志文件;

        周日做一次完全備份:備份的同時滾動日志

        周一至周六:備份二進制日志;

    恢復:

        完全備份+各二進制日志文件中至此刻的事件

    5. 實例:

        1) 完全備份mysql數據庫,并實現還原 

            備份之前的數據庫

         mysql> SHOW DATABASES; 
            +--------------------+
            | Database           |
            +--------------------+
            | information_schema |
            | hellodb            |
            | mysql              |
            | students           |
            | test               |
            | testdb             |
            +--------------------+
            此時要確保二進制日志開啟,我實驗的時候發現不知道為什么沒開,于是在配置文件中server段加一行
        # vim /etc/my.cnf 中添加log_bin=/data/mysqldata/mysql_bin 然后重啟服務
        # service mysqld restart 
        # ls /data/mysqldata/mysql_bin.* 可以看到一下三個文件,證明二進制已然開啟
            mysql_bin.000001  mysql_bin.000002  mysql_bin.index
            考慮到遠程連接,為安全考慮,最好不用管理員賬號備份,所以需要創建一個用戶專門用作mysqldump備份
        mysql> GRANT SELECT,SHOW DATABASES,LOCK TABLES,RELOAD,EVENT  ON *.* TO 'dumpper'@'192.168.37.%' IDENTIFIED BY 'dumpper'; 
        Query OK, 0 rows affected (0.00 sec)

            然后使用mysqldump進行備份 

        # mysqldump --events --master-data=2 --all-databases --lock-all-tables --flush-logs -udumpper -h192.168.37.129 -pdumpper > /tmp/dump_bak.sql
          這里的選項對應以上給dumpper用戶賦予的權限
            SHOW DATABASES ---> --all-databases 
            LOCK TABLES ---> --lock-all-tables 
            RELOAD ---> --flush-logs 
            EVENT ---> --events 
            SUPPER ---> --master-data 主要授予SHOW MASTER STATUS權限
            
          在hellodb.students表中插入一行,再刪除一個hellodb 然后嘗試恢復
            mysql> INSERT hellodb.students (Name,Age,Gender) VALUE ('Linghu Chong',28,'M');
            mysql> DROP DATABASE hellodb; 
            
          此時需要關閉session級別的二進制日志使得,恢復內容不記錄日志
            mysql> SET SESSION sql_log_bin='OFF'; 
            mysql> SOURCE /tmp/dump_bak.sql;
        
          此時數據庫恢復到,插入Linghu Chong 這一行之前,然后通過二進制日志恢復直到數據庫被刪除之前的內容
            由于設置了--master-data選項,所以在備份文件中可以找到如下一行
            -- CHANGE MASTER TO MASTER_LOG_FILE='mysql_bin.000005', MASTER_LOG_POS=106;
            這一行標記了新的二進制文件從那個點起始,通過查看二進制日志mysql_bin.000005可以得知,還需要恢復106到134也就是hellodb被刪除之前的數據
            # mysqlbinlog --start-position 106 --stop-position 271 /data/mysqldata/mysql_bin.000005 > binlog106_271.sql 
                mysql>SOURCE /tmp/binlog106_271.sql 
                mysql> SELECT * FROM hellodb.mysql 可以看到最后一行,以前插入的數據重新恢復
                |    26 | Linghu Chong  |  28 | M      |    NULL |      NULL |
                +-------+---------------+-----+--------+---------+-----------+

        2) 編寫腳本,并加入crontab, 為了看效果比較快,這里設定每小時執行一次 

    腳本如下:     
    #!/bin/bash
    #
    ## Using mysqldump to backup the all databases 
    function backup {
        prefix=$1
        outputdir=$2
        [ -d $outputdir ] ||(echo 'No output dir, creating one!' &&  mkdir -p $outputdir)
        now=`/bin/date +'%Y_%b_%d_%k%M'`
        /usr/local/mysql/bin/mysqldump --events --master-data=2 --all-databases --single-transaction --flush-logs -udumpper -h192.168.98.129 -pdumpper > $outputdir/${prefix}_${now}.sql
    }
    function main {
        case $# in
        2)
            backup $1 $2
            ;;
        *)
            echo 'Usage: ./mysqldump_wrapper.sh prefix outputdir'
            ;;
        esac
    }
    main $*
    周期任務計劃表
    # crontab -e 添加如下內容 
        * * * * *  /usr/local/mysql/mysqldump_wrapper.sh back /tmp/mysqlback
    ## 如果正常的話,在備份目錄中,每分鐘將備份一次
        -rw-r--r-- 1 root root 521824 Dec  1 11:42 back_2015_Dec_01_1142.sql
        -rw-r--r-- 1 root root 521824 Dec  1 11:43 back_2015_Dec_01_1143.sql
        rw-r--r-- 1 root root 521824 Dec  1 11:44 back_2015_Dec_01_1144.sql

lvm-snapshot:基于LVM快照的備份

    關于快照: 

        1. 事務日志跟數據文件必須在同一個卷上;

        2. 剛剛創立的快照卷,里面沒有任何數據,所有數據均來源于原卷

        3. 一旦原卷數據發生修改,修改的數據將復制到快照卷中,此時訪問數據一部分來自于快照卷,一部分來自于原卷

        4. 當快照使用過程中,如果修改的數據量大于快照卷容量,則會導致快照卷崩潰。 

        5. 快照卷本身不是備份,只是提供一個時間一致性的訪問目錄。 

    基于快照備份幾乎為熱備: 

        1. 創建快照卷之前,要請求MySQL的全局鎖;在快照創建完成之后釋放鎖;

        2. 如果是Inoodb引擎, 當flush tables 后會有一部分保存在事務日志中,卻不在文件中。 因此恢復時候,需要事務日志和數據文件

              但釋放鎖以后,事務日志的內容會同步數據文件中,因此備份內容并不絕對是鎖釋放時刻的內容,由于有些為完成的事務已經完成,但在備份數據中因為沒完成而回滾。 因此需要借助二進制日志往后走一段

    基于快照備份注意事項: 

        1. 事務日志跟數據文件必須在同一個卷上;

        2. 創建快照卷之前,要請求MySQL的全局鎖;在快照創建完成之后釋放鎖;

        3. 請求全局鎖完成之后,做一次日志滾動;做二進制日志文件及位置標記(手動進行);

    備份與恢復的大體步驟

        備份

        1. 請求全局鎖,并滾動日志

     mysql> FLUSH TABLES WITH READ LOCK;
     mysql> FLUSH LOGS;

        2. 做二進制日志文件及位置標記(手動進行);

    # mysql -e 'show master status' > /path/to/orignal_volume

        3. 創建快照卷

    # lvcreate -L   -s -n    -p r  /path/to/some_lv

        4.釋放全局鎖

        5. 掛載快照卷并備份

        6.備份完成之后,刪除快照卷

        恢復:

        1. 二進制日志保存好;

            提取備份之后的所有事件至某sql腳本中;

        2. 還原數據,修改權限及屬主屬組等,并啟動mysql

        3. 做即時點還原

        4. 生產環境下, 一次大型恢復后,需要馬上進行一次完全備份。 

    備份與恢復事例: 

        環境, 實現創建了一個test_vg卷組,里面有個mylv1用來裝mysql數據,掛載到/data/mysqldata 

        備份: 

    1. 創建備份專用的用戶,授予權限FLUSH LOGS 和 LOCK TABLES 

    MariaDB > GRANT RELOAD,LOCK TABLES,SUPER ON *.* TO 'lvm'@'192.168.98.%' IDENTIFIED BY 'lvm';    
    MariaDB > FLUSH PRIVILEGES;

    2. 記錄備份點

    # mysql -ulvm -h192.168.98.129 -plvm -e 'SHOW MASTER STATUS' > /tmp/backup_point.txt

    3. 創建快照卷并掛載快照卷

    # lvcreate -L 1G -s -n lvmbackup -p r /dev/test_vg/mylv1    
    # mount  -t ext4  /dev/test_vg/lvmbackup /mnt/

    4. 釋放鎖 

    # mysql -ulvm -h192.168.98.129 -plvm -e 'UNLOCK TABLES'    
    ## 做一些模擬寫入工作 
    MariaDB [test]> create database testdb2

     5. 復制文件

    # cp /data/mysqldata /tmp/backup_mysqldata -r

     6. 備份完成卸載,刪除快照卷 

    # umount /mnt     
    # lvmremove /dev/test_vg/lvmbackup

     還原: 假如整個mysql服務器崩潰,并且目錄全部被刪除

    1. 數據文件復制回源目錄

    # cp -r /tmp/backup_mysqldata/*  /data/mysqldata/     
    MariaDB [test]> show databases ;
        +--------------------+
        | Database           |
        +--------------------+
        | information_schema |
        | hellodb            |
        | mysql              |
        | mysqldata          |
        | openstack          |
        | performance_schema |
        | test               |
        +--------------------+
        此時還沒有testdb2, 因為這個是備份之后創建的,因此需要通過之前記錄的二進制日志位置向后還原

     2. 查看之前記錄的記錄點。向后還原

    # cat /tmp/backup_point.txt 
      FilePositionBinlog_Do_DBBinlog_Ignore_DB
      mysql-bin.000001245
    # mysqlbinlog /data/binlog/mysql-bin.000001 --start-position 245 > tmp.sql
    MariaDB [test]> source /data/mysqldata/tmp.sql 
    MariaDB [test]> show databases ; 
        +--------------------+
        | Database           |
        +--------------------+
        | information_schema |
        | hellodb            |
        | mysql              |
        | mysqldata          |
        | openstack          |
        | performance_schema |
        | test               |
        | testdb2            |
        +--------------------+
        8 rows in set (0.00 sec)
        testdb2 已經被還原回來。

使用Xtrabackup進行MySQL備份:

    安裝

        1. 簡介

            Xtrabackup是由percona提供的mysql數據庫備份工具,據官方介紹,這也是世界上惟一一款開源的能夠對innodb和xtradb數據庫進行熱備的工具。特點:

            1) 備份過程快速、可靠;

            2) 備份過程不會打斷正在執行的事務;

            3) 能夠基于壓縮等功能節約磁盤空間和流量;

            4) 自動實現備份檢驗;

            5) 還原速度快;

        2. 安裝

            其最新版的軟件可從 http://www.percona.com/software/percona-xtrabackup/ 獲得。本機使用2.2.12版本

    # yum install percona-toolkit-2.2.16-1.noarch.rpm
    # yum install percona-xtrabackup-2.3.2-1.el6.x86_64.rpm

    完全備份

        如果要使用一個最小權限的用戶進行備份,則可基于如下命令創建此類用戶:

   Usage:  innobackupex --user=DBUSER --password=DBUSERPASS  /path/to/BACKUP-DIR/
       --user: 需要創建一個擁有最小權限的用戶
   MariaDB [(none)]> GRANT RELOAD, LOCK TABLES, REPLICATION CLIENT ON *.* TO 'xtrauser'@'localhost' IDENTIFIED BY 'xtrauser' ;
   MariaDB [(none)]> FLUSH PRIVILEGES ;

              /path/to/BACKUP_DIR

                    備份出來的數據存放目錄,外加包含一些xtrabackup的元數據

                    使用innobakupex備份時,其會調用xtrabackup備份所有的InnoDB表,復制所有關于表結構定義的相關文件(.frm)、以及MyISAM、MERGE、CSV和ARCHIVE表的相關文件,同時還會備份觸發器和數據庫配置信息相關的文件。這些文件會被保存至一個以時間命令的目錄中。

        事例: 

    # innobackupex --user=xtrauser --password=xtrauser /tmp/xtrabackup/
        ...
        151202 14:52:01 Executing UNLOCK TABLES
        151202 14:52:01 All tables unlocked
        151202 14:52:01 Backup created in directory '/tmp/xtrabackup//2015-12-02_14-51-56'
        MySQL binlog position: filename 'mysql-bin.000001', position '952'
        151202 14:52:01 [00] Writing backup-my.cnf
        151202 14:52:01 [00]        ...done
        151202 14:52:01 [00] Writing xtrabackup_info
        151202 14:52:01 [00]        ...done
        xtrabackup: Transaction log of lsn (1752057) to (1752057) was copied.
        151202 14:52:01 completed OK!

        當看到最后這一行時候,說明備份已經完成 

    在備份的同時,innobackupex還會在備份目錄中創建如下文件:

        1. xtrabackup_checkpoints: 備份類型(如完全或增量)、備份狀態(如是否已經為prepared狀態)和LSN(Log Serial Number日志序列號)范圍信息;

    # cat xtrabackup_checkpoints     
        backup_type = full-backuped
        from_lsn = 0
        to_lsn = 1752057
        last_lsn = 1752057
        compact = 0
        recover_binlog_info = 0

         在mysql中,存儲數據的數據塊會有按照順序的ID, 如果某一塊數據被修改,將會賦予新的ID。 根據這些ID,可以標記數據的新老成都。xtrabackup也就是使用這些ID來進行備份,和增量備份

        每個InnoDB頁(通常為16k大小)都會包含一個日志序列號,即LSN。LSN是整個數據庫系統的系統版本號,每個頁面相關的LSN能夠表明此頁面最近是如何發生改變的。

        2. xtrabackup_binlog_info: mysql服務器當前正在使用的二進制日志文件及至備份這一刻為止二進制日志事件的位置。

    # cat xtrabackup_binlog_info     
    mysql-bin.000001952

        3. xtrabackup_info: 包含很多xtrabackup工具信息以及所備份的數據庫信息

    # cat xtrabackup_info     
        uuid = 3073ff65-98c1-11e5-9af1-000c29622425
        name = 
        tool_name = innobackupex
        tool_command = --user=xtrauser --password=... /tmp/xtrabackup/
        tool_version = 2.3.2
        ibbackup_version = 2.3.2
        server_version = 5.5.46-MariaDB-log
        start_time = 2015-12-02 14:51:59
        end_time = 2015-12-02 14:52:01
        lock_time = 0
        binlog_pos = filename 'mysql-bin.000001', position '952'
        innodb_from_lsn = 0
        innodb_to_lsn = 1752057
        partial = N
        incremental = N
        format = file
        compact = N
        compressed = N
        encrypted = N

        4. backup-my.cnf —— 備份命令用到的配置選項信息;

    # cat backup-my.cnf     
        # This MySQL options file was generated by innobackupex.
        # The MySQL server
        [mysqld]
        innodb_checksum_algorithm=innodb
        innodb_log_checksum_algorithm=innodb
        innodb_data_file_path=ibdata1:10M:autoextend
        innodb_log_files_in_group=2
        innodb_log_file_size=5242880
        innodb_fast_checksum=false
        innodb_page_size=16384
        innodb_log_block_size=512
        innodb_undo_directory=.
        innodb_undo_tablespaces=0

            在使用innobackupex進行備份時,還可以使用–no-timestamp選項來阻止命令自動創建一個以時間命名的目錄;如此一來,innobackupex命令將會創建一個BACKUP-DIR目錄來存儲備份數據。

        準備(prepare)一個完全備份

            一般情況下,在備份完成后,數據尚且不能用于恢復操作,因為備份的數據中可能會包含尚未提交的事務或已經提交但尚未同步至數據文件中的事務。

            因此,此時數據文件仍處理不一致狀態。“準備”的主要作用正是通過回滾未提交的事務及同步已經提交的事務至數據文件也使得數據文件處于一致性狀態。

            innobakupex命令的–apply-log選項可用于實現上述功能。如下面的命令: 實際上就是把未完成的事務提交,準備工作需要在還原之前才執行,在這之前都能執行準備工作。

    Usage: innobackupex --apply-log  /path/to/BACKUP-DIR  
      
    事例: 
    # innobackupex --apply-log /tmp/xtrabackup/2015-12-02_15-10-53/
        xtrabackup: starting shutdown with innodb_fast_shutdown = 1
        InnoDB: FTS optimize thread exiting.
        InnoDB: Starting shutdown...
        InnoDB: Shutdown completed; log sequence number 1752598
        151202 15:19:05 completed OK!
    出現這幾行,說明準備完成
    在實現“準備”的過程中,innobackupex通常還可以使用--use-memory選項來指定其可以使用的內存的大小,默認通常為100M。如果有足夠的內存可用,可以多劃分一些內存給prepare的過程,以提高其完成速度。

        從一個完全備份中恢復數據 

            注意:恢復不用啟動MySQL

            innobackupex命令的–copy-back選項用于執行恢復操作,其通過復制所有數據相關的文件至mysql服務器DATADIR目錄中來執行恢復過程。innobackupex通過backup-my.cnf來獲取 DATADIR目錄的相關信息。

usage: innobackupex --copy-back  /path/to/BACKUP-DIR
# innobackupex --copy-back /tmp/xtrabackup/2015-12-02_15-10-53/
    如果執行正確,其輸出信息的最后幾行通常如下:
    151202 15:23:32 [01] Copying ./mysql/time_zone_transition.MYI to /data/mysqldata/mysql/time_zone_transition.MYI
    151202 15:23:32 [01]        ...done
    151202 15:23:32 completed OK!

    當數據恢復至DATADIR目錄以后,還需要確保所有數據文件的屬主和屬組均為正確的用戶,如mysql,否則,在啟動mysqld之前還需要事先修改數據文件的屬主和屬組。如:

# chown -R  mysql:mysql  /data/mysqldata

         我發現的坑: 

              這里我發現一個坑,如果備份時,在配置文件中沒有明確定義innodb_log_size大小,這里可能無法啟動服務。 

              原因是,xtrabackup的默認innodb_log_size可能與mysql不一致。 這里使用的xtrabackup是比較新的版本2.3.2

              默認生成的日志大小為50331648而不是5242880,所以會出現問題。 解決方法是手工設定一下日志大小,寫在配置文件中。 

    使用innobackupex進行增量備份

            每個InnoDB的頁面都會包含一個LSN信息,每當相關的數據發生改變,相關的頁面的LSN就會自動增長。這正是InnoDB表可以進行增量備份的基礎,即innobackupex通過備份上次完全備份之后發生改變的頁面來實現。

        1. 備份過程: 

            要實現第一次增量備份,可以使用下面的命令進行:

                usage: innobackupex –incremental /backup –incremental-basedir=BASEDIR

            BASEDIR:

                指的是完全備份所在的目錄,此命令執行結束后,innobackupex命令會在/backup目錄中創建一個新的以時間命名的目錄以存放所有的增量備份數據。另外,在執行過增量備份之后再一次進行增量備份時,其–incremental-basedir應該指向上一次的增量備份所在的目錄。

                需要注意的是,增量備份僅能應用于InnoDB或XtraDB表,對于MyISAM表而言,執行增量備份時其實進行的是完全備份。

            舉例: 

            先做一次完全備份,在之前完全備份的基礎上做兩次增量,之間創建兩個數據庫 

            全備份: 

    # innobackupex --user=xtrauser --password=xtrauser --no-timestamp /tmp/xtrabackup/full_backup
    MariaDB [(none)]> CREATE DATABASE testdb1;

         第一次增量: 

    # innobackupex --user=xtrauser --password=xtrauser --incremental /tmp/xtrabackup/ --incremental-basedir=/tmp/xtrabackup/full_backup    
    MariaDB [(none)]> CREATE DATABASE testdb2;

         第二次增量: 

    # innobackupex --user=xtrauser --password=xtrauser --incremental  /tmp/xtrabackup/ --incremental-basedir=/tmp/xtrabackup/2015-12-02_17-15-35

        2. 準備過程

        “準備”(prepare)增量備份與整理完全備份有著一些不同,尤其要注意的是:

            1)需要在每個備份(包括完全和各個增量備份)上,將已經提交的事務進行“重放”?!爸胤拧敝?,所有的備份數據將合并到完全備份上。

            2)基于所有的備份將未提交的事務進行“回滾”。于是,操作就變成了:不能回滾,因為有可能第一次備份時候沒提交,在增量中已經成功提交

        使用方法如下: 

    # innobackupex --apply-log --redo-only BASE-DIR

        接著執行:

    # innobackupex --apply-log --redo-only BASE-DIR --incremental-dir=INCREMENTAL-DIR-1

        而后是第二個增量:

    # innobackupex --apply-log --redo-only BASE-DIR --incremental-dir=INCREMENTAL-DIR-2

         這樣一個一個準備完成后,所有增量將合并至全備份中。

         其中BASE-DIR指的是完全備份所在的目錄,而INCREMENTAL-DIR-1指的是第一次增量備份的目錄,INCREMENTAL-DIR-2指的是第二次增量備份的目錄,其它依次類推,即如果有多次增量備份,每一次都要執行如上操作;

        事例: 

    # innobackupex --apply-log --redo-only /tmp/xtrabackup/full_backup    
    # innobackupex --apply-log --redo-only /tmp/xtrabackup/full_backup/ --incremental-dir=/tmp/xtrabackup/2015-12-02_17-15-35
    # innobackupex --apply-log --redo-only /tmp/xtrabackup/full_backup/ --incremental-dir=/tmp/xtrabackup/2015-12-02_17-17-14

        3. 恢復過程:與完全備份類似,直接copy-back完全備份的那個目錄。 此時所有的增量已經正好到完全備份的目錄中 

    # rm -rf /data/mysqldata/* 
    # innobackupex --copy-back /tmp/xtrabackup/full_backup/
    # chown -R  mysql:mysql  /data/mysqldata
    MariaDB [(none)]> show databases; 
        +--------------------+
        | Database           |
        +--------------------+
        | information_schema |
        | hellodb            |
        | mysql              |
        | performance_schema |
        | test               |
        | test1              |
        | testdb1            |
        | testdb2            |
        +--------------------+
        8 rows in set (0.04 sec)
    可以看到后面創建的兩個testdb1, testdb2 全部恢復回來

    Xtrabackup的“流”及“備份壓縮”功能

            Xtrabackup對備份的數據文件支持“流”功能,即可以將備份的數據通過STDOUT傳輸給tar程序進行歸檔,而不是默認的直接保存至某備份目錄中。要使用此功能,僅需要使用–stream選項即可。如:

            usage: innobackupex –stream=tar  /backup | gzip > /backup/`date +%F_%H-%M-%S`.tar.gz

           事例: 

        # innobackupex --user=xtrauser --password=xtrauser --stream=tar /tmp/xtrabackup/ | gzip > /tmp/xtrabackup/`date +%F_%H-%M-%S`.tar.gz

            甚至也可以使用類似如下命令將數據備份至其它服務器:

            usage: innobackupex –stream=tar  /backup | ssh user@hostname  "cat –  > /backups/`date +%F_%H-%M-%S`.tar" 

        # innobackupex --user=xtrauser --password=xtrauser --stream=tar /tmp/xtrabackup | ssh root@192.168.98.129  "cat -  > /tmp/`date +%F_%H-%M-%S`.tar"

            這里有個bug, 會進入無限log記錄,好像是新版本的問題,目前還不知道怎么解決。 

          此外,在執行本地備份時,還可以使用–parallel選項對多個文件進行并行復制。此選項用于指定在復制時啟動的線程數目。當然,在實際進行備份時要利用此功能的便利性,也需要啟用innodb_file_per_table選項或共享的表空間通過innodb_data_file_path選項存儲在多個ibdata文件中。對某一數據庫的多個文件的復制無法利用到此功能。其簡單使用方法如下:

            usage:  innobackupex –parallel  /path/to/backup

        同時,innobackupex備份的數據文件也可以存儲至遠程主機,這可以使用–remote-host選項來實現: 貌似此功能在2.1以后就被取消了

            usage:  innobackupex –remote-host=root@hostname  /path/IN/REMOTE/HOST/to/backup

    導入或導出單張表

            默認情況下,InnoDB表不能通過直接復制表文件的方式在mysql服務器之間進行移植,即便使用了innodb_file_per_table選項。而使用Xtrabackup工具可以實現此種功能,不過,此時需要“導出”表的mysql服務器啟用了innodb_file_per_table選項(嚴格來說,是要“導出”的表在其創建之前,mysql服務器就啟用了innodb_file_per_table選項),并且“導入”表的服務器同時啟用了innodb_file_per_table和innodb_expand_import選項。

        在創建數據庫之前,在配置文件中server段下面寫入innodb_file_per_table=1, 記得是1不是on也不是yes,這個坑出現在5.1版本中,我看了后面的mariadb沒有這個問題

        1) “導出”表

            導出表是在備份的prepare階段進行的,因此,一旦完全備份完成,就可以在prepare過程中通過–export選項將某表導出了:

        usage: innobackupex –apply-log –export /path/to/backup

        事例: 

    # innobackupex --user=xtrauser --password=xtrauser /tmp/xtrabackup
    # innobackupex --apply-log --export  /tmp/2015-12-03_12-37-35/

        此命令會為每個innodb表的表空間創建一個以.exp結尾的文件,這些以.exp結尾的文件則可以用于導入至其它服務器。

    # ls *.exp  
        classes.exp  coc.exp  courses.exp  scores.exp  students.exp  teachers.exp  toc.exp

        2 )“導入”表

        使用show CREATE TABLE mytable; 來查看原始表創建命令 

        要在mysql服務器上導入來自于其它服務器的某innodb表,需要先在當前服務器上創建一個跟原表表結構一致的表,而后才能實現將表導入:

        事例: 這里以students 表為例 

    mysql> SHOW CREATE TABLE hellodb.students \G;    
        *************************** 1. row ***************************
           Table: students
        Create Table: CREATE TABLE `students` (
          `StuID` int(10) unsigned NOT NULL AUTO_INCREMENT,
          `Name` varchar(50) NOT NULL,
          `Age` tinyint(3) unsigned NOT NULL,
          `Gender` enum('F','M') NOT NULL,
          `ClassID` tinyint(3) unsigned DEFAULT NULL,
          `TeacherID` int(10) unsigned DEFAULT NULL,
          PRIMARY KEY (`StuID`)
        ) ENGINE=InnoDB AUTO_INCREMENT=26 DEFAULT CHARSET=utf8

    在testdb庫中創建這個表
    mysql> CREATE TABLE `students` (
        `StuID` int(10) unsigned NOT NULL AUTO_INCREMENT,
        `Name` varchar(50) NOT NULL,
        `Age` tinyint(3) unsigned NOT NULL,
        `Gender` enum('F','M') NOT NULL,
        `ClassID` tinyint(3) unsigned DEFAULT NULL,
        `TeacherID` int(10) unsigned DEFAULT NULL,
        PRIMARY KEY (`StuID`)
        ) ENGINE=InnoDB AUTO_INCREMENT=26 DEFAULT CHARSET=utf8
        
    然后將此表的表空間刪除:
    mysql> ALTER TABLE mydatabase.mytable  DISCARD TABLESPACE;
    
    接下來,將來自于“導出”表的服務器的students表的students.ibd和students.exp文件復制到當前服務器的數據目錄,然后使用如下命令將其“導入”:
    注意權限。。。。
    # cp /tmp/2015-12-03_12-37-35/hellodb/students{.ibd,.exp} /data/mysqldata/testdb/
    # chown mysql.mysql /data/mysqldata/testdb/students.*
    mysql> ALTER TABLE mydatabase.mytable  IMPORT TABLESPACE;

       好像這里也有bug 明天試一下

        嘗試結果如下: 

            1) 在mysql 5.1 版本中無法實現

            2) mariadb 5.5 也不行 

            3) 只有在mysql 5.6中可以成功實現 

最后這里是馬哥對于備份和恢復的幾點經驗之談,請允許我無恥的總結在這里

    備份注意:

        1. 將數據和備份放在不同的磁盤設備上;異機或異地備份存儲較為理想;

        2. 備份的數據應該周期性地進行還原測試;

        3. 每次災難恢復后都應該立即做一次完全備份;

        4. 針對不同規?;蚣墑e的數據量,要定制好備份策略;

        5. 二進制日志應該跟數據文件在不同磁盤上,并周期性地備份好二進制日志文件;

從備份中恢復應該遵循步驟:

        1. 停止MySQL服務器;

        2. 記錄服務器的配置和文件權限;

        3. 將數據從備份移到MySQL數據目錄;其執行方式依賴于工具;

        4. 改變配置和文件權限;

        5. 以限制訪問模式重啟服務器;mysqld的–skip-networking選項可跳過網絡功能;

            方法:編輯my.cnf配置文件,添加如下項:

            skip-networking

            socket=/tmp/mysql-recovery.sock

        6. 載入邏輯備份(如果有);而后檢查和重放二進制日志;

        7. 檢查已經還原的數據;

        8. 重新以完全訪問模式重啟服務器;

            注釋前面在my.cnf中添加的選項,并重啟;

原創文章,作者:以馬內利,如若轉載,請注明出處:http://www.www58058.com/9781

(1)
以馬內利以馬內利
上一篇 2015-12-10 11:08
下一篇 2015-12-10 22:29

相關推薦

  • Linux系統終端類型

    引言 終端(Terminal)也稱終端設備,是計算機網絡中處于網絡最外圍的設備,主要用于用戶信息的輸入以及處理結果的輸出等。在早期計算機系統中,由于計算機主機昂貴,因此一個主機一般會配置多個終端,這些終端本身不具備計算能力,僅僅承擔信息輸入輸出的工作,運算和處理均由主機來完成,在個人計算機時代,個人計算機可以運行稱為終端仿真器的程序來模仿一個終端的工作。 &…

    Linux干貨 2016-10-19
  • 訪問控制列表ACL

     ACL是Access Control List的縮寫,主要的目的是提供傳統的owner、group、others的read、write、execute權限之外的具體權限設置。ACL可以針對單一用戶、單一文件、單一目錄來進行r、w、x的權限設置,對于需要特殊權限的使用狀況非常有幫助。使用getfacl和setfacl來設置查看acl的權限。ACL權…

    Linux干貨 2016-08-07
  • 虛擬機的安裝

    虛擬機的安裝步驟: 1、打開VMware點擊創建新的虛擬機 2、選擇典型安裝方式點擊下一步 3、選擇稍后安裝操作系統點擊下一步 4、客戶機操作系統選擇Linux,版本選擇Centos 64位 5、設定虛擬機的名稱及存放路徑 6、設定磁盤的容量,選中將虛擬磁盤存儲為單個文件 7、對虛擬設備進行設置 8、CD/DVD此項選中使用ISO映像文件并選擇映像所在路徑 …

    2018-03-27
  • 文本處理grep

    grep:文本過濾(模式:pattern)工具grep, egrep, fgrep【適合處理比較大的文本】(不支持正則表達式搜索) sed:stream editor,文本編輯工具 awk:Linux上的實現gawk,文本報告生成器 grep(Global search 全局搜索 Regular expression 正則表達式 and Print out …

    Linux干貨 2017-05-09
  • 正則表達式詳解

    正則表達式詳解

    2017-09-20
  • Xen虛擬化平臺安裝及實時遷移

    前言 Xen是英國劍橋大學計算機實驗室開發的一個虛擬化開源項目,Xen可以在一套物理硬件上安全的執行多個虛擬機,它和操作平臺結合的極為密切,占用的資源極少。以高性能、占用資源少著稱,贏得了IBM、AMD、HP、Redhat和Novell等眾多世界級軟硬件廠商的高度認可和大力支持,已被國內外眾多企事業用戶用來搭建高性能的虛擬化平臺。 Xen虛擬化類型 Xen對…

    Linux干貨 2015-07-19
欧美性久久久久