一、備份的意義
從資料安全的角度來說,資料庫伺服器磁盤都會做RAID,Mariadb本身也有主從等容災機制,但它們都無法完全取代備份。容災和高可用能幫我們有效的應對實體的、硬體的、機械的故障,但是由我們手工操作導緻的邏輯錯誤、系統本身内生性BUG、惡意攻擊等方式破壞了你的資料卻無能為力。每一種邏輯錯誤發生的機率都極低,但是當多種可能性疊加的時候,小機率事件就放大成很大的安全隐患,這時候備份的必要性就凸顯了。
二、備份類型
1、根據備份時,資料庫伺服器是否線上:
冷備:cold backup
溫備:warm backup
熱備:hot backup
2、根據備份的資料集:
完全備份:full backup
部分備份: partial backup
3、根據備份時的接口(直接備份資料檔案還是通過mysql伺服器導出資料):
實體備份:直接複制(歸檔)資料檔案的備份方式;physical backup
邏輯備份:把資料從庫中提出出來儲存為文本檔案;logical backup
4、根據備份時是備份整個資料還是僅備份變化的資料:
增量備份:incremental backup
差異備份:differential backup
5、備份政策:
選擇備份方式
選擇備份時間
考慮到恢複成本
恢複時長
備份成本
鎖時間
備份時長
備份負載
6、備份對象
資料
配置檔案
代碼:存儲過程,存儲函數,觸發器
OS相關的配置檔案,如crontab配置計劃及相關的腳本,跟複制相關的配,二進制日志檔案
三、常見的備份工具
mariadb本身為我們提供了mysqldump、mysqlbinlog備份工具,percona也為我們提供了強大的Xtrabackup,加上開源的mydumper,還有基于主從同步的延遲備份、從庫冷備等方式,以及基于檔案系統快照的備份,其實将這些方式合理搭配已經能夠滿足我們的需要了。而備份本身是為了恢複,是以能夠讓我們在出現故障後迅速、準确恢複的備份方式,就是最适合我們的,當然,同時能夠省錢、省事,那就非常完美。下面就幾種備份工具進行一些比較,探讨下它們各自的适用場景,及簡單的使用做一下說明
1、mysqldump
⑴、mysqldump優缺點
mysqldump是最簡單的邏輯備份方式(工作方式單線程)。在備份myisam表的時候,如果要得到一緻的資料,就需要鎖表,簡單而粗暴。而在備份innodb表的時候,加上–master-data=2 –single-transaction 選項,在事務開始時刻,記錄下binlog-pos點,然後利用mvcc(多版本并發控制)來擷取一緻的資料,由于是一個大事務,在寫入和更新量很大的資料庫上,将産生非常多的undo,顯著影響性能,是以要慎用。
<a href="http://s3.51cto.com/wyfs02/M02/23/FC/wKioL1NJY1PwpftQAAF4qal76Cc359.jpg" target="_blank"></a>
優點:簡單,可針對單表備份,在完全導出表結構的時候尤其有用。可以做到對不同的存儲引擎進行備份(InnoDB熱備、MyISAM溫備、Aria溫備)
缺點:簡單粗暴,單線程,備份慢而且恢複,不支援差異或增量備份,如果要進行差異或增量備份要結合binlog日志檔案
mydumper是mysqldump的加強版。相比mysqldump:
内置支援壓縮,可以節省2-4倍的存儲空間。
支援并行備份和恢複,是以速度比mysqldump快很多,但是由于是邏輯備份,仍不是很快,如果要進行差異或增量備份要結合binlog日志檔案
部分備份工具
SELECT clause INTO OUTFILE '/path/to/somefile'
LOAD DATA INFILE '/path/from/somefile'
不會備份關系定義,僅備份表中的資料;
邏輯備份工具,快于mysqldump。
⑵、mysqldump指令介紹及簡單使用
①指令介紹
mysqldump [options] [db_name [tbl_name ...]]
備份單個庫:
mysqldump [options] db_name
恢複時:如果目标庫不存在,需要事先手動建立
options說明
--all-databases: 備份所有庫
--databases db1 db2 ...: 備份指定的多個庫
注意:備份前要加鎖
--lock-all-tables:請求鎖定所有表之後再備份,對MyISAM、InnoDB、Aria做溫備
--single-transaction: 能夠對InnoDB存儲引擎實作熱備;
備份代碼:
--events: 備份事件排程器代碼
--routines: 備份存儲過程和存儲函數
--triggers:備份觸發器
備份時滾動日志:
--flush-logs: 備份前、請求到鎖之後滾動日志;
複制時的同步位置标記:
--master-data=[0|1|2]
0: 不記錄
1:記錄為CHANGE MASTER語句
2:記錄為注釋的CHANGE MASTER語句
注意
使用mysqldump備份
請求鎖:--lock-all-tables或使用--singe-transaction進行innodb熱備;
滾動日志:--flush-logs
標明要備份的庫:--databases
記錄二進制日志檔案及位置:--master-data=
恢複
建議:關閉二進制日志,關閉其它使用者連接配接;
建議備份政策:基于mysqldump
備份部分
mysqldump+二進制日志檔案;
完全備份+各二進制日志檔案中至此刻的事件,對MySQL配置檔案,以及與MySQL相關的OS配置檔案在每次修改後都應該直接進行備份;
②、執行個體
要求如下:
備份所有資料庫,要每周日淩晨自動執行;
③解決方案(此方法不唯一)
備份階段
第一步,先遠端登入到資料庫上,事先看一下現有的資料庫。
<a href="http://s3.51cto.com/wyfs02/M01/23/FC/wKiom1NJaHbjzl5BAAH03wdWkVI320.jpg" target="_blank"></a>
由上圖可見,除了hellodb資料庫,其它的資料庫都是系統自帶的,看一下hellodb中有那些表,及目前binlog日志的記錄的位置。
<a href="http://s3.51cto.com/wyfs02/M01/24/2C/wKioL1NL446AziAXAAIAEWNmgcs930.jpg" target="_blank"></a>
由于目前資料庫隻有一個使用者資料庫,是以我們在乎其表的存儲引擎來判斷使用什麼方式來備份。(是申請鎖或是單事務)
<a href="http://s3.51cto.com/wyfs02/M00/23/FD/wKioL1NJaebTRB0wAAN7xg3NH6I301.jpg" target="_blank"></a>
檢視表狀态發現hellodb中的表全部都是MyISAM的存儲引擎,那麼就可以使用申請全局鎖來備份了。
1
<code># mysqldump -uroot -p </code><code>--all-databases --lock-all-tables --flush-logs --master-data=2 >/tmp/all.sql</code>
<a href="http://s3.51cto.com/wyfs02/M01/23/FC/wKiom1NJa7aiKc0oAAEZ8d6UEkE727.jpg" target="_blank"></a>
這時資料庫全部備份完畢(此方法隻适用于資料量不是很大,挑選一個相對并發的寫請求不是特别多的時間或午夜備份。如果資料量特别大,此方法将不做參考範圍)。
假如在這之後我們又在原來的庫中建立新的表或插入資料,而在某一次我誤操作删除了此資料庫。将如何恢複?
<a href="http://s3.51cto.com/wyfs02/M02/24/2C/wKiom1NL5PvhDZJ6AAEIzh4vRzk068.jpg" target="_blank"></a>
由上圖可見,原來的hellodb資料庫中多了一張表,為不示範恢複效果我将hellodb删除,看怎麼樣恢複
<a href="http://s3.51cto.com/wyfs02/M00/24/2C/wKioL1NL5XuCCG1mAAE_TpkyEQM706.jpg" target="_blank"></a>
現在hellodb己經删除,看如何恢複。
恢複部分
第一步,将伺服器離線,導出現在正在使用的binlog日志,還原之前的完全備份
檢視完全備份中binlog日志的起始位置。
2
<code>#vim /tmp/all.sql</code>
<code>-- CHANGE MASTER TO MASTER_LOG_FILE=</code><code>'mysql-bin.000002'</code><code>, MASTER_LOG_POS=365;</code>
将此日志中到删除資料庫drop database hellodb之前的資料導出到存放起來,以供時間點還原之用
<code># mysqlbinlog --start-position=365 --stop-position=863 mysql-bin.000002 >/tmp/binlogbakup.sql</code>
登入資料庫
3
4
5
6
7
<code>[root@localhost bin]# mysql</code>
<code>Welcome </code><code>to</code> <code>the MariaDB monitor. Commands </code><code>end</code> <code>with</code> <code>; </code><code>or</code> <code>\g.</code>
<code>Your MariaDB </code><code>connection</code> <code>id </code><code>is</code> <code>4</code>
<code>Server version: 10.0.10-MariaDB-log Source distribution</code>
<code>Copyright (c) 2000, 2014, Oracle, SkySQL Ab </code><code>and</code> <code>others.</code>
<code>Type </code><code>'help;'</code> <code>or</code> <code>'\h'</code> <code>for</code> <code>help. Type </code><code>'\c'</code> <code>to</code> <code>clear the </code><code>current</code> <code>input statement.</code>
<code>MariaDB [(none)]></code>
注:此時要臨時關閉二進制日志,關閉其它使用者連接配接;
<code>MariaDB [(none)]> </code><code>set</code> <code>session sql_log_bin=0;</code>
<code>Query OK, 0 </code><code>rows</code> <code>affected (0.00 sec)</code>
導入之前的備份
<code>MariaDB [(none)]> source /tmp/</code><code>all</code><code>.sql</code>
檢視資料庫中的表,裡面沒有我們備份之後建立的表,這時就用到了之前備份的binlog日志了
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<code>MariaDB [test]> show databases;</code>
<code>+</code><code>--------------------+</code>
<code>| </code><code>Database</code> <code>|</code>
<code>| hellodb |</code>
<code>| information_schema |</code>
<code>| mysql |</code>
<code>| performance_schema |</code>
<code>| test |</code>
<code>5 </code><code>rows</code> <code>in</code> <code>set</code> <code>(0.05 sec)</code>
<code>MariaDB [test]> use hellodb</code>
<code>Database</code> <code>changed</code>
<code>MariaDB [hellodb]> show tables;</code>
<code>+</code><code>-------------------+</code>
<code>| Tables_in_hellodb |</code>
<code>| classes |</code>
<code>| coc |</code>
<code>| courses |</code>
<code>| scores |</code>
<code>| students |</code>
<code>| teachers |</code>
<code>| toc |</code>
<code>7 </code><code>rows</code> <code>in</code> <code>set</code> <code>(0.00 sec)</code>
導入binlog日志,完全恢複資料。
<code>MariaDB [hellodb]> source /tmp/binlogbakup.sql</code>
<code>| addressbook |</code>
<code>8 </code><code>rows</code> <code>in</code> <code>set</code> <code>(0.00 sec)</code>
<code>MariaDB [hellodb]> </code><code>select</code> <code>* </code><code>from</code> <code>addressbook;</code>
<code>+</code><code>--------+---------+----------+----------+-----------------+</code>
<code>| fname | lname | phone | fax | email |</code>
<code>| France | D'Souza | 123 4567 | 000 7574 | fdz@</code><code>some</code><code>.domain |</code>
<code>1 row </code><code>in</code> <code>set</code> <code>(0.01 sec)</code>
這回資料就完整了。
附上一個基于mysqldump簡單複制單庫的myisam的腳本
<code>#!/bin/sh</code>
<code>###############################</code>
<code>#此腳本用來單庫完全份</code>
<code>#每個星期日做一次完全備份</code>
<code>#設定使用者名和密碼</code>
<code>v_user=</code><code>"root"</code>
<code>v_password=</code><code>"mysql"</code>
<code>#mysql安裝可執行程式所在位置</code>
<code>MysqlDir=</code><code>/usr/local/mari/bin</code>
<code>#備份資料庫</code>
<code>database=</code><code>"hellodb"</code>
<code>#設定備份路徑,建立備份檔案夾</code>
<code>BackupDir=</code><code>/maria_bak</code>
<code>Full_Backup=$BackupDir</code><code>/Full_backup</code>
<code>mkdir</code> <code>-p $Full_Backup/$(</code><code>date</code> <code>+%Y%m%d)</code>
<code>#開始備份,記錄備份開始時間</code>
<code>echo</code> <code>'###'</code><code>$(</code><code>date</code> <code>+</code><code>"%Y-%m-%d %H:%M:%S"</code><code>)</code><code>'###'</code><code>"備份開始"</code><code>>>$Full_Backup</code><code>/full_buckup</code><code>.log</code>
<code>$MysqlDir</code><code>/mysqldump</code> <code>-u$v_user -p$v_password --lock-all-tables --flush-logs --master-data=2 --databases $database>$Full_Backup/$(</code><code>date</code> <code>+%Y%m%d)</code><code>/full_backup</code><code>.sql</code>
<code>#壓縮備份檔案</code>
<code>gzip</code> <code>$Full_Backup/$(</code><code>date</code> <code>+%Y%m%d)</code><code>/full_backup</code><code>.sql</code>
<code>echo</code> <code>'###'</code><code>$(</code><code>date</code> <code>+</code><code>"%Y-%m-%d %H:%M:%S"</code><code>)</code><code>'###'</code><code>"備份完成"</code><code>>>$Full_Backup</code><code>/full_buckup</code><code>.log</code>
2. 基于檔案系統的快照
基于檔案系統的快照,是實體備份的一種。在備份前需要進行一些複雜的設定,在備份開始時刻獲得快照并記錄下binlog pos點,然後采用類似copy-on-write的方式,把快照進行轉儲。轉儲快照本身會消耗一定的IO資源,而且在寫入壓力較大的執行個體上,儲存被更改資料塊的前印象也會消耗IO,最終表現為整體性能的下降。而且伺服器還要為copy-on-write快照預留較多的磁盤空間,這本身對資源也是一種浪費。是以這種備份方式在生産環境使用的不多。
<a href="http://s3.51cto.com/wyfs02/M00/24/2D/wKiom1NL92TRAaKAAAEyVtHhHes360.jpg" target="_blank"></a>
注:
當剛為數資料檔案所在的卷(源卷)建立快照時,此時的快照卷是空的。
當源卷中的資料發生變化後,則将發生變化的那部分資料複制到快照卷上,此時通過快照通路則是未發生變化的資料來自于源卷,變化後的資料來自于快照卷。
快照不是備份,它是僅是提供通路檔案的一條通路,當源卷變化的量超出快照卷的大小時,快照卷将崩潰失效。
執行個體
前提:
首先,mariadb的資料檔案在邏輯卷上,如果使用的是支援事務的存儲引擎的話,那麼要将事務日志與資料檔案放在同一個卷上,這樣才能保證資料的完整性。
看一下資料檔案的屬性
<a href="http://s3.51cto.com/wyfs02/M02/24/69/wKiom1NOgaDwFpRzAAJ8Ukod_iQ470.jpg" target="_blank"></a>
步驟:
第一步,如果對源卷建立快照,那麼首先要對資料庫申請全局鎖,滾動二進制日志,記錄二進制日志位置标記
⑴、申請全局鎖
<code>MariaDB [(none)]> flush tables </code><code>with</code> <code>read</code> <code>lock;</code>
<code>MariaDB [(none)]> flush logs;</code>
<code>Query OK, 0 </code><code>rows</code> <code>affected (0.02 sec)</code>
<code>MariaDB [(none)]> show master status;</code>
<code>+</code><code>------------------+----------+--------------+------------------+</code>
<code>| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |</code>
<code>| mysql-bin.000012 | 365 | | |</code>
<code>1 row </code><code>in</code> <code>set</code> <code>(0.02 sec)</code>
将此二進制日志資訊記錄下來
<code># mysql -e 'show master status;'>/maribak/binlog_pos/binlog_$(date +%F_%T).txt</code>
<code># cat /maribak/binlog_pos/binlog_2014-04-14_04\:17\:13.txt</code>
<code>File Position Binlog_Do_DB Binlog_Ignore_DB</code>
<code>mysql-bin.000012 365</code>
此時可以建立快照了
<code># lvcreate -L 200M -s -n databak_snap -p r /dev/mydata/lv1</code>
<code> </code><code>Logical volume </code><code>"databak_snap"</code> <code>created</code>
第二步,建立完快照後解鎖
當快照卷建立完成後,可以對資料庫解鎖(建立鎖與解鎖必須是同一會話,也就是說,當建立完鎖之後,這個會話不可退出,之後還要在這個會話中對資料庫解鎖,一但退出,此會話的全局鎖将失效)
<code>MariaDB [(none)]> unlock tables;</code>
<code>Query OK, 0 rowsaffected (0.00 sec)</code>
這時資料庫又可以正常進行寫入操作了
第三步,備份快照
挂載備份之後的快照
<code>[root@bogon mnt]</code><code># mount /dev/mydata/databak_snap -o ro /mnt</code>
<code>[root@bogon mnt]</code><code># cd /mnt</code>
<code>[root@bogon mnt]</code><code># ll</code>
<code>total 176172</code>
<code>-rw-rw---- 1 mysql mysql 16384 Apr 14 04:11 aria_log.00000001</code>
<code>-rw-rw---- 1 mysql mysql 52 Apr 14 04:11 aria_log_control</code>
<code>-rw-r----- 1 mysql root 1099 Apr 14 04:11 bogon.err</code>
<code>-rw-rw---- 1 mysql mysql 5 Apr 14 04:11 bogon.pid</code>
<code>drwx------ 2 mysql mysql 4096 Apr 14 04:12 employees</code>
<code>-rw-rw---- 1 mysql mysql 79691776 Apr 14 04:14 ibdata1</code>
<code>-rw-rw---- 1 mysql mysql 50331648 Apr 14 04:14 ib_logfile0</code>
<code>-rw-rw---- 1 mysql mysql 50331648 Apr 14 04:14 ib_logfile1</code>
<code>-rw-rw---- 1 mysql mysql 0 Apr 14 04:11 multi-master.info</code>
<code>drwx------ 2 mysql root 4096 Apr 14 04:11 mysql</code>
<code>drwx------ 2 mysql mysql 4096 Apr 14 04:11 performance_schema</code>
<code>drwx------ 2 mysql root 4096 Apr 14 04:11 </code><code>test</code>
複制快照中的内容
<code>[root@bogon mnt]</code><code># cp -a * /maribak/databak/</code>
<code>[root@bogon mnt]</code><code># cd /maribak/databak/</code>
<code>[root@bogon databak]</code><code># ll</code>
删除快照卷
<code>#lvremove /dev/mydata/databak_snap</code>
裡源卷的資料庫employees中添入一些資料。
<code>MariaDB [employees]> </code><code>insert</code> <code>employees </code><code>values</code><code>(99,</code><code>'1998-09-21'</code><code>,</code><code>'JEYY'</code><code>,</code><code>'jose'</code><code>,</code><code>'M'</code><code>,</code><code>'2012-12-24'</code><code>);</code>
<code>MariaDB [employees]> </code><code>insert</code> <code>employees </code><code>values</code><code>(999999,</code><code>'1995-09-21'</code><code>,</code><code>'king'</code><code>,</code><code>'tom'</code><code>,</code><code>'M'</code><code>,</code><code>'2012-12-24'</code><code>);</code>
<code>MariaDB [employees]></code><code>insert</code> <code>employees </code><code>values</code><code>(5211345,</code><code>'1995-09-21'</code><code>,</code><code>'king'</code><code>,</code><code>'tom'</code><code>,</code><code>'F'</code><code>,</code><code>'2012-12-24'</code><code>);</code>
當備份過完成後,過了幾個小時,資料庫誤删除了一些資料,這時就可用到此次完全備份與即時點還原日志。
<code>MariaDB [employees]> </code><code>delete</code> <code>from</code> <code>employees </code><code>where</code> <code>gender=</code><code>'M'</code>
<code> </code><code>-> ;</code>
<code>Query OK, 179975 </code><code>rows</code> <code>affected (3 </code><code>min</code> <code>52.82 sec)</code>
還原部分
第一步,停止資料庫服務,将備份後的資料中的某一張表或整個庫替換此資料庫中誤删除的表或整個庫。
<code>[root@bogon employees]</code><code># service mari stop</code>
<code>Shutting down MySQL............... [ OK ]</code>
替換
<code>[root@bogon employees]</code><code># cp -a /maribak/databak/employees/employees.* .</code>
<code>cp</code><code>: overwrite `.</code><code>/employees</code><code>.frm'? y</code>
<code>cp</code><code>: overwrite `.</code><code>/employees</code><code>.ibd'? y</code>
<code>[root@bogon employees]</code><code># ll</code>
<code>total 237840</code>
<code>-rw-rw---- 1 mysql mysql 61 Apr 14 04:12 db.opt</code>
<code>-rw-rw---- 1 mysql mysql 1571 Apr 14 04:12 departments.frm</code>
<code>-rw-rw---- 1 mysql mysql 114688 Apr 14 04:12 departments.ibd</code>
<code>-rw-rw---- 1 mysql mysql 1999 Apr 14 04:12 dept_emp.frm</code>
<code>-rw-rw---- 1 mysql mysql 31457280 Apr 14 05:03 dept_emp.ibd</code>
<code>-rw-rw---- 1 mysql mysql 1999 Apr 14 04:12 dept_manager.frm</code>
<code>-rw-rw---- 1 mysql mysql 131072 Apr 14 04:55 dept_manager.ibd</code>
<code>-rw-rw---- 1 mysql mysql 1164 Apr 14 04:12 employees.frm</code>
<code>-rw-rw---- 1 mysql mysql 23068672 Apr 14 04:12 employees.ibd</code>
<code>-rw-rw---- 1 mysql mysql 1501 Apr 14 04:12 salaries.frm</code>
<code>-rw-rw---- 1 mysql mysql 146800640 Apr 14 05:03 salaries.ibd</code>
<code>-rw-rw---- 1 mysql mysql 1647 Apr 14 04:12 titles.frm</code>
<code>-rw-rw---- 1 mysql mysql 41943040 Apr 14 05:03 titles.ibd</code>
注:此時檔案的屬性要與原檔案的一緻
第二步,啟動服務
<code>[root@bogon employees]</code><code># service mari start</code>
<code>Starting MySQL.. [ OK ]</code>
檢視完全備份資訊
<code>MariaDB [employees]> </code><code>select</code> <code>* </code><code>from</code> <code>employees </code><code>where</code> <code>hire_date ></code><code>'2000-01-01'</code><code>;</code>
<code>+</code><code>--------+------------+------------+------------+--------+------------+</code>
<code>| emp_no | birth_date | first_name | last_name | gender | hire_date |</code>
<code>| 47291 | 1960-09-09 | Ulf | Flexer | M | 2000-01-12 |</code>
<code>| 60134 | 1964-04-21 | Seshu | Rathonyi | F | 2000-01-02 |</code>
<code>| 72329 | 1953-02-09 | Randi | Luit | F | 2000-01-02 |</code>
<code>| 205048 | 1960-09-12 | Ennio | Alblas | F | 2000-01-06 |</code>
<code>| 222965 | 1959-08-07 | Volkmar | Perko | F | 2000-01-13 |</code>
<code>| 226633 | 1958-06-10 | Xuejun | Benzmuller | F | 2000-01-04 |</code>
<code>| 227544 | 1954-11-17 | Shahab | Demeyer | M | 2000-01-08 |</code>
<code>| 422990 | 1953-04-09 | Jaana | Verspoor | F | 2000-01-11 |</code>
<code>| 424445 | 1953-04-27 | Jeong | Boreale | M | 2000-01-03 |</code>
<code>| 428377 | 1957-05-09 | Yucai | Gerlach | M | 2000-01-23 |</code>
<code>| 463807 | 1964-06-12 | Bikash | Covnot | M | 2000-01-28 |</code>
<code>| 499553 | 1954-05-06 | Hideyuki | Delgrande | F | 2000-01-22 |</code>
并沒有備份後插入的資料,是以在用到binlog日志了,檢視目前的binlog的位置
<code>MariaDB [employees]> show master status;</code>
<code>| mysql-bin.000013 | 326 | | |</code>
<code>1 row </code><code>in</code> <code>set</code> <code>(0.00 sec)</code>
跨檔案了~~~,沒關系統,先還原同一個日志檔案中的資料,再恢複這個日志中的資料,在mysql-bin.000012中找到delect之前的位置,并使用mysqlbinlog将其導出,臨時性關閉binlog日志功能,恢複此間資料。
<code># mysqlbinlog /mysql/binlog/mysql-bin.000012</code>
<code>..........省略中........</code>
<code># at 1108</code>
<code>#140414 4:53:25 server id 1 end_log_pos 1146 GTID 0-1-7138</code>
<code>/*!100001 SET @@session.gtid_seq_no=7138*</code><code>//</code><code>*!*/;</code>
<code>BEGIN</code>
<code>/*!*/;</code>
<code># at 1146</code>
<code>#140414 4:53:25 server id 1 end_log_pos 1254 Query thread_id=6 exec_time=233 error_code=0</code>
<code>SET TIMESTAMP=1397422405/*!*/;</code>
<code>delete from employees where gender=</code><code>'M'</code>
從日志中看辨別到1108即可恢複到删除之前,将此區間導出
<code>[root@bogon binlog_pos]</code><code># mysqlbinlog --start-position=365 --stop-position=1108 /mysql/binlog/mysql-bin.000012 >zengliang.sql</code>
<code>[root@bogon binlog_pos]</code><code># ls</code>
<code>binlog_2014-04-14_04:17:13.txt zengliang.sql</code>
在資料中臨時關閉binlog日志功能。
<code>MariaDB [employees]> </code><code>set</code> <code>session sql_log_bin=0;</code>
<code>Query OK, 0 </code><code>rows</code> <code>affected (0.01 sec)</code>
<code>MariaDB [employees]> source /maribak/binlog_pos/zengliang.sql;</code>
檢視一下原來的資料
<code>+</code><code>---------+------------+------------+------------+--------+------------+</code>
<code>| emp_no | birth_date | first_name | last_name | gender | hire_date |</code>
<code>| 99 | 1998-09-21 | JEYY | jose | M | 2012-12-24 |</code>
<code>| 47291 | 1960-09-09 | Ulf | Flexer | M | 2000-01-12 |</code>
<code>| 60134 | 1964-04-21 | Seshu | Rathonyi | F | 2000-01-02 |</code>
<code>| 72329 | 1953-02-09 | Randi | Luit | F | 2000-01-02 |</code>
<code>| 205048 | 1960-09-12 | Ennio | Alblas | F | 2000-01-06 |</code>
<code>| 222965 | 1959-08-07 | Volkmar | Perko | F | 2000-01-13 |</code>
<code>| 226633 | 1958-06-10 | Xuejun | Benzmuller | F | 2000-01-04 |</code>
<code>| 227544 | 1954-11-17 | Shahab | Demeyer | M | 2000-01-08 |</code>
<code>| 422990 | 1953-04-09 | Jaana | Verspoor | F | 2000-01-11 |</code>
<code>| 424445 | 1953-04-27 | Jeong | Boreale | M | 2000-01-03 |</code>
<code>| 428377 | 1957-05-09 | Yucai | Gerlach | M | 2000-01-23 |</code>
<code>| 463807 | 1964-06-12 | Bikash | Covnot | M | 2000-01-28 |</code>
<code>| 499553 | 1954-05-06 | Hideyuki | Delgrande | F | 2000-01-22 |</code>
<code>| 999999 | 1995-09-21 | king | tom | M | 2012-12-24 |</code>
<code>| 5211345 | 1995-09-21 | king | tom | F | 2012-12-24 |</code>
<code>15 </code><code>rows</code> <code>in</code> <code>set</code> <code>(0.31 sec)</code>
全部都回來了,退出會話,再次登入後,binlog日志将開始記錄了。(以上操作,均要在 設定了skip-networking的情況下操作,完全恢複後,在配置檔案中[mysqld]中将skip-networking注釋掉,記得再來一次完全備份後,mariadb又可重新工作了)
3. Xtrabackup
⑴、簡介
Xtrabackup是由percona提供的mysql資料庫備份工具,據官方介紹,這也是世界上惟一一款開源的能夠對innodb和xtradb資料庫進行熱備的工具。特點:
備份過程快速、可靠;
備份過程不會打斷正在執行的事務;
能夠基于壓縮等功能節約磁盤空間和流量;
自動實作備份檢驗;
還原速度快;
⑵、安裝
其最新版的軟體可從 http://www.percona.com/software/percona-xtrabackup/ 獲得
⑶、原理說明
它的工作原理如下:
<a href="http://s3.51cto.com/wyfs02/M01/24/6A/wKiom1NOrx6DxnjfAAGL2YqCTtk029.jpg" target="_blank"></a>
由于mysql中不可避免的含有myisam表,同時innobackup并不備份表結構等檔案,是以想要完整的備份mysql執行個體,就少不了要執行flush tables with read lock,而這個語句會被任何查詢(包括select)阻塞,在阻塞過程中,它又反過來阻塞任何查詢(包括select)。如果碰巧備份執行個體上有長查詢先于flush tables with read lock執行,資料庫就會hang住。而當flush tables with read lock獲得全局鎖後,雖然查詢可以執行,但是仍會阻塞更新,是以,我們希望flush tables with read lock從發起到結束,持續的時間越短越好。
⑷、執行個體:
利用Xtrabackup實作完全與增量備份
步驟
前提
授權一個僅可以備份操作的使用者
<code>MariaDB [(none)]> </code><code>grant</code> <code>reload,lock tables,replication client </code><code>on</code> <code>*.* </code><code>to</code> <code>'bakupuser'</code><code>@</code><code>'localhost'</code> <code>identified </code><code>by</code> <code>'bakuppass'</code><code>;</code>
<code>Query OK, 0 </code><code>rows</code> <code>affected (1.34 sec)</code>
①、完全備份
指令格式:
<code># innobackupex --user=DBUSER --password=DBUSERPASS /path/to/BACKUP-DIR/</code>
說明:
使用innobakupex備份時,其會調用xtrabackup備份所有的InnoDB表,複制所有關于表結構定義的相關檔案(.frm)、以及MyISAM、MERGE、CSV和ARCHIVE表的相關檔案,同時還會備份觸發器和資料庫配置資訊相關的檔案。這些檔案會被儲存至一個以時間指令的目錄中。
在備份的同時,innobackupex還會在備份目錄中建立如下檔案:
xtrabackup_checkpoints —— 備份類型(如完全或增量)、備份狀态(如是否已經為prepared狀态)和LSN(日志序列号)範圍資訊;每個InnoDB頁(通常為16k大小)都會包含一個日志序列号,即LSN。LSN是整個資料庫系統的系統版本号,每個頁面相關的LSN能夠表明此頁面最近是如何發生改變的。xtrabackup_binlog_info —— mysql伺服器目前正在使用的二進制日志檔案及至備份這一刻為止二進制日志事件的位置。
xtrabackup_binlog_pos_innodb —— 二進制日志檔案及用于InnoDB或XtraDB表的二進制日志檔案的目前position。
xtrabackup_binary —— 備份中用到的xtrabackup的可執行檔案;
backup-my.cnf —— 備份指令用到的配置選項資訊;
在使用innobackupex進行備份時,還可以使用--no-timestamp選項來阻止指令自動建立一個以時間命名的目錄;如此一來,innobackupex指令将會建立一個BACKUP-DIR目錄來存儲備份資料。
====================================正式開始=====================================
完全備份部分
對目前的mariadb資料庫做一次完備份
<code>MariaDB [(none)]> show databases;</code>
<code>| employees |</code>
<code>5 </code><code>rows</code> <code>in</code> <code>set</code> <code>(0.07 sec)</code>
<code># innobackupex --user=bakupuser --password=bakuppass --host=localhost /maribak/</code>
<code>………………過程資訊……………………</code>
<code>innobackupex: Backup created </code><code>in</code> <code>directory </code><code>'/maribak/2014-04-14_07-17-33'</code>
<code>innobackupex: MySQL binlog position: filename </code><code>'mysql-bin.000013'</code><code>, position 542</code>
<code>140414 07:17:57 innobackupex: Connection to database server closed</code>
<code>140414 07:17:57 innobackupex: completed OK!</code>
最後顯示的資訊:
備份的位置(以時間指令的目錄下)
binlog日志的目前位置
備份的狀态
看一下備份目錄中的檔案
27
28
29
30
31
32
33
34
35
36
37
<code># ll</code>
<code>total 208932</code>
<code>-rw-r--r-- 1 root root 357 Apr 14 07:17 backup-my.cnf</code>
<code>drwx------ 2 root root 4096 Apr 14 07:17 employees</code>
<code>-rw-r----- 1 root root 213909504 Apr 14 07:17 ibdata1</code>
<code>drwx------ 2 root root 4096 Apr 14 07:17 mysql</code>
<code>drwxr-xr-x 2 root root 4096 Apr 14 07:17 performance_schema</code>
<code>drwxr-xr-x 2 root root 4096 Apr 14 07:17 </code><code>test</code>
<code>-rw-r--r-- 1 root root 13 Apr 14 07:17 xtrabackup_binary</code>
<code>-rw-r--r-- 1 root root 23 Apr 14 07:17 xtrabackup_binlog_info</code>
<code>-rw-r----- 1 root root 93 Apr 14 07:17 xtrabackup_checkpoints</code>
<code>-rw-r----- 1 root root 2560 Apr 14 07:17 xtrabackup_logfile</code>
<code># cat backup-my.cnf #備份指令用到的配置選項資訊</code>
<code># This MySQL options file was generated by innobackupex.</code>
<code># The MySQL server</code>
<code>[mysqld]</code>
<code>innodb_checksum_algorithm=innodb</code>
<code>innodb_log_checksum_algorithm=innodb</code>
<code>innodb_data_file_path=ibdata1:10M:autoextend</code>
<code>innodb_log_files_in_group=2</code>
<code>innodb_log_file_size=50331648</code>
<code>innodb_fast_checksum=0</code>
<code>innodb_page_size=16384</code>
<code>innodb_log_block_size=512</code>
<code>innodb_undo_tablespaces=0</code>
<code>[root@bogon 2014-04-14_07-17-33]</code><code># cat xtrabackup_binary</code>
<code>xtrabackup_56</code>
<code>#xtrabackup版本資訊</code>
<code>[root@bogon 2014-04-14_07-17-33]</code><code># cat xtrabackup_binlog_info</code>
<code>mysql-bin.000013 542</code>
<code>#binlog日志位置及标記</code>
<code>[root@bogon 2014-04-14_07-17-33]</code><code># cat xtrabackup_checkpoints</code>
<code>backup_type = full-backuped </code><code>#備份的類型(預設為完全備份)</code>
<code>from_lsn = 0 </code><code>#日志序列号(資料檔案的LSN存儲在資料檔案的第1個頁面,即ID為0的頁面的頭部,是整個檔案的LSN。)</code>
<code>to_lsn = 885197721 </code><code>#到那一個日志序列号</code>
<code>last_lsn = 885197721 </code><code>#最後一個日志序列号(指的是結束位置在那裡)</code>
<code>compact = 0</code>
==========================================到此完全備份完成==============================
為了示範效果我會将資料目錄清空。
<code>[root@bogon maribak]</code><code># cd /mariadb/data</code>
<code>[root@bogon data]</code><code># ll</code>
<code>total 307248</code>
<code>-rw-rw---- 1 mysql mysql 16384 Apr 14 05:03 aria_log.00000001</code>
<code>-rw-rw---- 1 mysql mysql 52 Apr 14 05:03 aria_log_control</code>
<code>-rw-r----- 1 mysql root 2680 Apr 14 05:12 bogon.err</code>
<code>-rw-rw---- 1 mysql mysql 5 Apr 14 05:12 bogon.pid</code>
<code>drwx------ 2 mysql mysql 4096 Apr 14 04:12 employees</code>
<code>-rw-rw---- 1 mysql mysql 213909504 Apr 14 05:37 ibdata1</code>
<code>-rw-rw---- 1 mysql mysql 50331648 Apr 14 05:37 ib_logfile0</code>
<code>-rw-rw---- 1 mysql mysql 50331648 Apr 14 05:37 ib_logfile1</code>
<code>-rw-rw---- 1 mysql mysql 0 Apr 14 04:11 multi-master.info</code>
<code>drwx------ 2 mysql root 4096 Apr 14 04:11 mysql</code>
<code>drwx------ 2 mysql mysql 4096 Apr 14 04:11 performance_schema</code>
<code>drwx------ 2 mysql root 4096 Apr 14 04:11 </code><code>test</code>
<code>[root@bogon data]</code><code># rm -rf *</code>
<code>[root@bogon data]</code><code># pwd</code>
<code>/mariadb/data</code>
<code>[root@bogon data]</code><code># ls</code>
<code>[root@bogon data]</code><code>#</code>
完全恢複部分
準備(prepare)一個完全備份
一般情況下,在備份完成後,資料尚且不能用于恢複操作,因為備份的資料中可能會包含尚未送出的事務或已經送出但尚未同步至資料檔案中的事務。是以,此時資料檔案仍處理不一緻狀态。“準備”的主要作用正是通過復原未送出的事務及同步已經送出的事務至資料檔案也使得資料檔案處于一緻性狀态。
指令說明:
<code># innobackupex --apply-log /path/to/BACKUP-DIR</code>
innobakupex指令的--apply-log選項可用于實作上述功能
在實作“準備”的過程中,innobackupex通常還可以使用--use-memory選項來指定其可以使用的記憶體的大小,預設通常為100M。如果有足夠的記憶體可用,可以多劃分一些記憶體給prepare的過程,以提高其完成速度。
============================================正式開始====================================
準備工作開始
<code># innobackupex --apply-log /maribak/2014-04-14_07-17-33</code>
<code>[notice (again)]</code>
<code> </code><code>If you use binary log and don't use any hack of group commit,</code>
<code> </code><code>the binary log position seems to be:</code>
<code>InnoDB: Last MySQL binlog </code><code>file</code> <code>position 0 1281, </code><code>file</code> <code>name </code><code>/mysql/binlog/mysql-bin</code><code>.000012</code>
<code>xtrabackup: starting </code><code>shutdown</code> <code>with innodb_fast_shutdown = 1</code>
<code>InnoDB: FTS optimize thread exiting.</code>
<code>InnoDB: Starting </code><code>shutdown</code><code>...</code>
<code>InnoDB: Shutdown completed; log sequence number 885203607</code>
<code>140414 07:46:45 innobackupex: completed OK!</code>
==================================準備工作完成=================================
從一個完全備份中恢複資料
恢複不用啟動MySQL
<code># innobackupex --copy-back /path/to/BACKUP-DIR</code>
innobackupex指令的--copy-back選項用于執行恢複操作,其通過複制所有資料相關的檔案至mysql伺服器DATADIR目錄中來執行恢複過程。innobackupex通過backup-my.cnf來擷取DATADIR目錄的相關資訊。
<code># innobackupex --copy-back /maribak/2014-04-14_07-17-33</code>
<code>innobackupex: Starting to copy InnoDB log files</code>
<code>innobackupex: </code><code>in</code> <code>'/maribak/2014-04-14_07-17-33'</code>
<code>innobackupex: back to original InnoDB log directory </code><code>'/mariadb/data'</code>
<code>innobackupex: Copying </code><code>'/maribak/2014-04-14_07-17-33/ib_logfile0'</code> <code>to </code><code>'/mariadb/data/ib_logfile0'</code>
<code>innobackupex: Copying </code><code>'/maribak/2014-04-14_07-17-33/ib_logfile1'</code> <code>to </code><code>'/mariadb/data/ib_logfile1'</code>
<code>innobackupex: Finished copying back files.</code>
<code>140414 07:57:48 innobackupex: completed OK!</code>
如果出現ok表示恢複完畢了。
回到資料目錄下看一下檔案的屬性,確定檔案的所有屬性都是正确的使用者,并可以以身份來通路與運作,如果不是,請修改其檔案屬性
<code>total 307244</code>
<code>-rw-rw---- 1 mysql mysql 16384 Apr 14 07:59 aria_log.00000001</code>
<code>-rw-rw---- 1 mysql mysql 52 Apr 14 07:59 aria_log_control</code>
<code>-rw-r----- 1 mysql root 1044 Apr 14 07:59 bogon.err</code>
<code>drwxr-xr-x 2 root root 4096 Apr 14 07:57 employees</code>
<code>-rw-r--r-- 1 root root 213909504 Apr 14 07:57 ibdata1</code>
<code>-rw-r--r-- 1 root root 50331648 Apr 14 07:57 ib_logfile0</code>
<code>-rw-r--r-- 1 root root 50331648 Apr 14 07:57 ib_logfile1</code>
<code>drwxr-xr-x 2 root root 4096 Apr 14 07:57 mysql</code>
<code>drwxr-xr-x 2 root root 4096 Apr 14 07:57 performance_schema</code>
<code>drwxr-xr-x 2 root root 4096 Apr 14 07:57 </code><code>test</code>
<code>-rw-r--r-- 1 root root 36 Apr 14 07:57 xtrabackup_binlog_pos_innodb</code>
<code>[root@bogon data]</code><code># chown -R mysql.mysql *</code>
<code>-rw-r----- 1 mysql mysql 1044 Apr 14 07:59 bogon.err</code>
<code>drwxr-xr-x 2 mysql mysql 4096 Apr 14 07:57 employees</code>
<code>-rw-r--r-- 1 mysql mysql 213909504 Apr 14 07:57 ibdata1</code>
<code>-rw-r--r-- 1 mysql mysql 50331648 Apr 14 07:57 ib_logfile0</code>
<code>-rw-r--r-- 1 mysql mysql 50331648 Apr 14 07:57 ib_logfile1</code>
<code>drwxr-xr-x 2 mysql mysql 4096 Apr 14 07:57 mysql</code>
<code>drwxr-xr-x 2 mysql mysql 4096 Apr 14 07:57 performance_schema</code>
<code>drwxr-xr-x 2 mysql mysql 4096 Apr 14 07:57 </code><code>test</code>
<code>-rw-r--r-- 1 mysql mysql 36 Apr 14 07:57 xtrabackup_binlog_pos_innodb</code>
啟動mariadb
<code>]# mysql</code>
<code>5 </code><code>rows</code> <code>in</code> <code>set</code> <code>(0.37 sec)</code>
<code>MariaDB [(none)]> use employees</code>
<code>MariaDB [employees]> </code><code>select</code> <code>* </code><code>from</code> <code>employees </code><code>where</code> <code>hire_date ></code><code>'2001-01-01'</code><code>;</code>
<code>+</code><code>---------+------------+------------+-----------+--------+------------+</code>
<code>| emp_no | birth_date | first_name | last_name | gender | hire_date |</code>
<code>| 99 | 1998-09-21 | JEYY | jose | M | 2012-12-24 |</code>
<code>| 999999 | 1995-09-21 | king | tom | M | 2012-12-24 |</code>
<code>| 5211345 | 1995-09-21 | king | tom | F | 2012-12-24 |</code>
<code>3 </code><code>rows</code> <code>in</code> <code>set</code> <code>(0.72 sec)</code>
資料都恢複回來了。
==========================================到此完全備份、恢複完成======================
②增量備份
使用innobackupex進行增量備份
每個InnoDB的頁面都會包含一個LSN資訊,每當相關的資料發生改變,相關的頁面的LSN就會自動增長。這正是InnoDB表可以進行增量備份的基礎,即innobackupex通過備份上次完全備份之後發生改變的頁面來實作。
<code># innobackupex --incremental /backup --incremental-basedir=BASEDIR</code>
指令說明
其中,BASEDIR指的是完全備份所在的目錄,此指令執行結束後,innobackupex指令會在/backup目錄中建立一個新的以時間命名的目錄以存放所有的增量備份資料。另外,在執行過增量備份之後再一次進行增量備份時,其--incremental-basedir應該指向上一次的增量備份所在的目錄。
需要注意的是,增量備份僅能應用于InnoDB或XtraDB表,對于MyISAM表而言,執行增量備份時其實進行的是完全備份。
“準備”(prepare)增量備份與整理完全備份有着一些不同,尤其要注意的是:
(1)需要在每個備份(包括完全和各個增量備份)上,将已經送出的事務進行“重放”。“重放”之後,所有的備份資料将合并到完全備份上。
(2)基于所有的備份将未送出的事務進行“復原”。
于是,操作就變成了:
<code># innobackupex --apply-log --redo-only BASE-DIR</code>
接着執行:
<code># innobackupex --apply-log --redo-only BASE-DIR --incremental-dir=INCREMENTAL-DIR-1</code>
而後是第二個增量:
<code># innobackupex --apply-log --redo-only BASE-DIR --incremental-dir=INCREMENTAL-DIR-2</code>
其中BASE-DIR指的是完全備份所在的目錄,而INCREMENTAL-DIR-1指的是第一次增量備份的目錄,INCREMENTAL-DIR-2指的是第二次增量備份的目錄,其它依次類推,即如果有多次增量備份,每一次都要執行如上操作;
==================================增加備份正式開始====================================
首先,在還原後的資料庫中插入一些資料。
<code>MariaDB [employees]> </code><code>insert</code> <code>employees </code><code>values</code><code>(0000001,</code><code>'1998-09-21'</code><code>,</code><code>'essun'</code><code>,</code><code>'com'</code><code>,</code><code>'M'</code><code>,</code><code>'2012-12-24'</code><code>);</code>
<code>Query OK, 1 row affected (0.10 sec)</code>
<code>MariaDB [employees]> </code><code>insert</code> <code>employees </code><code>values</code><code>(0000002,</code><code>'1998-09-21'</code><code>,</code><code>'essun'</code><code>,</code><code>'com'</code><code>,</code><code>'M'</code><code>,</code><code>'2012-12-24'</code><code>);</code>
<code>Query OK, 1 row affected (0.01 sec)</code>
<code>MariaDB [employees]> </code><code>insert</code> <code>employees </code><code>values</code><code>(0000003,</code><code>'1998-09-21'</code><code>,</code><code>'essun'</code><code>,</code><code>'com'</code><code>,</code><code>'M'</code><code>,</code><code>'2012-12-24'</code><code>);</code>
<code>MariaDB [employees]> </code><code>insert</code> <code>employees </code><code>values</code><code>(0000004,</code><code>'1998-09-21'</code><code>,</code><code>'essun'</code><code>,</code><code>'com'</code><code>,</code><code>'M'</code><code>,</code><code>'2012-12-24'</code><code>);</code>
<code>MariaDB [employees]> </code><code>insert</code> <code>employees </code><code>values</code><code>(0000005,</code><code>'1998-09-21'</code><code>,</code><code>'essun'</code><code>,</code><code>'com'</code><code>,</code><code>'M'</code><code>,</code><code>'2012-12-24'</code><code>);</code>
結果如下:
<code>MariaDB [employees]> </code><code>select</code> <code>* </code><code>from</code> <code>employees </code><code>where</code> <code>hire_date ></code><code>'2012-01-01'</code><code>;</code>
<code>| 1 | 1998-09-21 | essun | com | M | 2012-12-24 |</code>
<code>| 2 | 1998-09-21 | essun | com | M | 2012-12-24 |</code>
<code>| 3 | 1998-09-21 | essun | com | M | 2012-12-24 |</code>
<code>| 4 | 1998-09-21 | essun | com | M | 2012-12-24 |</code>
<code>| 5 | 1998-09-21 | essun | com | M | 2012-12-24 |</code>
<code>8 </code><code>rows</code> <code>in</code> <code>set</code> <code>(0.24 sec)</code>
增量備份開始
<code># innobackupex </code><code>--incremental /maribak/ --incremental-basedir=/maribak/2014-04-14_07-17-33/</code>
<code>innobackupex: Backup created </code><code>in</code> <code>directory </code><code>'/maribak/2014-04-14_08-33-50'</code>
<code>innobackupex: MySQL binlog position: filename </code><code>'mysql-bin.000014'</code><code>, position 1371</code>
<code>140414 08:34:03 innobackupex: </code><code>Connection</code> <code>to</code> <code>database</code> <code>server closed</code>
<code>140414 08:34:03 innobackupex: completed OK!</code>
<code>#cd maribak/</code>
<code># ls</code>
<code>2014-04-14_07-17-33 2014-04-14_08-33-50</code>
<code>#cd 2014-04-14_07-17-33 #上一次的完全備份</code>
<code># cat xtrabackup_checkpoints</code>
<code>backup_type = </code><code>full</code><code>-prepared</code>
<code>from_lsn = 0</code>
<code>to_lsn = 885197721</code>
<code>last_lsn = 885197721</code>
<code>#cd 2014-04-14_08-33-50</code>
<code>#cat xtrabackup_checkpoints #這次增量備份</code>
<code>backup_type = incremental</code>
<code>from_lsn = 885197721</code>
<code>to_lsn = 885227214</code>
<code>last_lsn = 885227214</code>
====================================到此增量備份完成==================================
如果在此增量之後,又增加了資料,如果資料量不是很大的話,基于二進制做即時還原會更快一些。此時又插入了一些資料
<code>MariaDB [employees]> </code><code>insert</code> <code>employees </code><code>values</code><code>(0000007,</code><code>'1998-09-21'</code><code>,</code><code>'sfsdf'</code><code>,</code><code>'org'</code><code>,</code><code>'M'</code><code>,</code><code>'2012-12-24'</code><code>);</code>
<code>MariaDB [employees]> </code><code>insert</code> <code>employees </code><code>values</code><code>(0000009,</code><code>'1998-09-21'</code><code>,</code><code>'sfsdf'</code><code>,</code><code>'me'</code><code>,</code><code>'M'</code><code>,</code><code>'2012-12-24'</code><code>);</code>
<code>MariaDB [employees]> </code><code>insert</code> <code>employees </code><code>values</code><code>(0000010,</code><code>'1998-09-21'</code><code>,</code><code>'sdfdf'</code><code>,</code><code>'NET'</code><code>,</code><code>'F'</code><code>,</code><code>'2012-12-24'</code><code>);</code>
<code>Query OK, 1 row affected (0.02 sec)</code>
<code>MariaDB [employees]> </code><code>insert</code> <code>employees </code><code>values</code><code>(0000011,</code><code>'1998-09-21'</code><code>,</code><code>'sdfdf'</code><code>,</code><code>'GOV'</code><code>,</code><code>'F'</code><code>,</code><code>'2012-12-24'</code><code>);</code>
基于增量的資料還原
第一步,删除資料檔案
<code>aria_log.00000001 bogon.err employees ib_logfile0 multi-master.info performance_schema xtrabackup_binlog_pos_innodb</code>
<code>aria_log_control bogon.pid ibdata1 ib_logfile1 mysql </code><code>test</code>
<code>[root@bogon data]</code><code># ls /mysql/binlog/ #binlog日志檔案所在位置,并沒有與資料檔案存放在一起</code>
<code>mysql-bin.000001 mysql-bin.000004 mysql-bin.000007 mysql-bin.000010 mysql-bin.000013</code>
<code>mysql-bin.000002 mysql-bin.000005 mysql-bin.000008 mysql-bin.000011 mysql-bin.000014</code>
<code>mysql-bin.000003 mysql-bin.000006 mysql-bin.000009 mysql-bin.000012 mysql-bin.index</code>
第二步,開始準備還原的資料
<code># innobackupex --apply-log --redo-only /maribak/2014-04-14_07-17-33/</code>
<code>notice (again)]</code>
<code>140414 08:56:10 innobackupex: completed OK!</code>
<code>#以上為完全備份準備完成</code>
<code># innobackupex --apply-log --redo-only /maribak/2014-04-14_07-17-33/ --incremental-dir=/maribak/2014-04-14_08-33-50/</code>
<code>innobackupex: Copying </code><code>'/maribak/2014-04-14_08-33-50/performance_schema/events_statements_summary_by_host_by_event_name.frm'</code> <code>to </code><code>'/maribak/2014-04-14_07-17-33/performance_schema/events_statements_summary_by_host_by_event_name.frm'</code>
<code>innobackupex: Copying </code><code>'/maribak/2014-04-14_08-33-50/performance_schema/events_stages_history_long.frm'</code> <code>to </code><code>'/maribak/2014-04-14_07-17-33/performance_schema/events_stages_history_long.frm'</code>
<code>140414 08:59:03 innobackupex: completed OK!</code>
<code>#以上為完全與增量整合完畢</code>
<code>#檢視一下整合後的日志序列号</code>
<code>#cat /maribak/2014-04-14_07-17-33/xtrabackup_checkpoints</code>
<code>backup_type = full-prepared</code>
是以說,隻有需要恢複資料時,才可開始準備資料,因為其間可能有多個增量需要整合!
=============================準備工作到此完畢===================================
開始還原
<code># innobackupex --copy-back /maribak/2014-04-14_07-17-33/</code>
<code>140414 09:06:26 innobackupex: completed OK!</code>
<code>total 307216</code>
<code>drwxr-xr-x 2 root root 4096 Apr 14 09:06 employees</code>
<code>-rw-r--r-- 1 root root 213909504 Apr 14 09:06 ibdata1</code>
<code>-rw-r--r-- 1 root root 50331648 Apr 14 09:06 ib_logfile0</code>
<code>-rw-r--r-- 1 root root 50331648 Apr 14 09:06 ib_logfile1</code>
<code>drwxr-xr-x 2 root root 4096 Apr 14 09:06 mysql</code>
<code>drwxr-xr-x 2 root root 4096 Apr 14 09:06 performance_schema</code>
<code>drwxr-xr-x 2 root root 4096 Apr 14 09:06 </code><code>test</code>
<code># chown -R mysql.mysql *</code>
<code>drwxr-xr-x 2 mysql mysql 4096 Apr 14 09:06 employees</code>
<code>-rw-r--r-- 1 mysql mysql 213909504 Apr 14 09:06 ibdata1</code>
<code>-rw-r--r-- 1 mysql mysql 50331648 Apr 14 09:06 ib_logfile0</code>
<code>-rw-r--r-- 1 mysql mysql 50331648 Apr 14 09:06 ib_logfile1</code>
<code>drwxr-xr-x 2 mysql mysql 4096 Apr 14 09:06 mysql</code>
<code>drwxr-xr-x 2 mysql mysql 4096 Apr 14 09:06 performance_schema</code>
<code>drwxr-xr-x 2 mysql mysql 4096 Apr 14 09:06 </code><code>test</code>
檢視binlog日志的标記,導出binlog日志并附加到資料庫中
<code># cat /maribak/2014-04-14_07-17-33/xtrabackup_binlog_info</code>
<code>mysql-bin.000014 1371</code>
<code>#mysqlbinlog --start-position=1371 /mysql/binlog/mysql-bin.000014 > /maribak/zengliang.sql</code>
<code># service mari start</code>
<code>Starting MySQL [ OK ]</code>
<code>MariaDB [(none)]> </code><code>set</code> <code>sql_log_bin=0;</code>
<code>Query OK, 0 rows affected (0.00 sec)</code>
<code>MariaDB [(none)]> </code><code>source</code> <code>/maribak/zengliang</code><code>.sql</code>
<code>MariaDB [employees]> </code><code>select</code> <code>* from employees.employees where hire_date ></code><code>'2012-01-01'</code><code>;</code>
<code>+---------+------------+------------+-----------+--------+------------+</code>
<code>| 7 | 1998-09-21 | sfsdf | org | M | 2012-12-24 |</code>
<code>| 9 | 1998-09-21 | sfsdf | me | M | 2012-12-24 |</code>
<code>| 10 | 1998-09-21 | sdfdf | NET | F | 2012-12-24 |</code>
<code>| 11 | 1998-09-21 | sdfdf | GOV | F | 2012-12-24 |</code>
<code>12 rows </code><code>in</code> <code>set</code> <code>(0.24 sec)</code>
============================================增量備份示範完畢===========================
附加一些進階應用
Xtrabackup的“流”及“備份壓縮”功能
Xtrabackup對備份的資料檔案支援“流”功能,即可以将備份的資料通過STDOUT傳輸給tar程式進行歸檔,而不是預設的直接儲存至某備份目錄中。要使用此功能,僅需要使用--stream選項即可。如:
<code># innobackupex --stream=tar /backup | gzip > /backup/`date +%F_%H-%M-%S`.tar.gz</code>
甚至也可以使用類似如下指令将資料備份至其它伺服器:
<code># innobackupex --stream=tar /backup | ssh [email protected] "cat - > /backups/`date +%F_%H-%M-%S`.tar"</code>
此外,在執行本地備份時,還可以使用--parallel選項對多個檔案進行并行複制。此選項用于指定在複制時啟動的線程數目。當然,在實際進行備份時要利用此功能的便利性,也需要啟用innodb_file_per_table選項或共享的表空間通過innodb_data_file_path選項存儲在多個ibdata檔案中。對某一資料庫的多個檔案的複制無法利用到此功能。其簡單使用方法如下:
<code># innobackupex --parallel /path/to/backup</code>
同時,innobackupex備份的資料檔案也可以存儲至遠端主機,這可以使用--remote-host選項來實作:
<code># innobackupex [email protected] /path/IN/REMOTE/HOST/to/backup</code>
導入或導出單張表
預設情況下,InnoDB表不能通過直接複制表檔案的方式在mysql伺服器之間進行移植,即便使用了innodb_file_per_table選項。而使用Xtrabackup工具可以實作此種功能,不過,此時需要“導出”表的mysql伺服器啟用了innodb_file_per_table選項(嚴格來說,是要“導出”的表在其建立之前,mysql伺服器就啟用了innodb_file_per_table選項),并且“導入”表的伺服器同時啟用了innodb_file_per_table和innodb_expand_import選項。
(1)“導出”表
導出表是在備份的prepare階段進行的,是以,一旦完全備份完成,就可以在prepare過程中通過--export選項将某表導出了:
<code># innobackupex --apply-log --export /path/to/backup</code>
此指令會為每個innodb表的表空間建立一個以.exp結尾的檔案,這些以.exp結尾的檔案則可以用于導入至其它伺服器。
(2)“導入”表
要在mysql伺服器上導入來自于其它伺服器的某innodb表,需要先在目前伺服器上建立一個跟原表表結構一緻的表,而後才能實作将表導入:
<code>MariaDB [(none)]> CREATE TABLE mytable (...) ENGINE=InnoDB</code>
然後将此表的表空間删除:
<code>MariaDB [(none)]>ALTER TABLE mydatabase.mytable DISCARD TABLESPACE;</code>
接下來,将來自于“導出”表的伺服器的mytable表的mytable.ibd和mytable.exp檔案複制到目前伺服器的資料目錄,然後使用如下指令将其“導入”:
<code>MariaDB [(none)]> ALTER TABLE mydatabase.mytable IMPORT TABLESPACE;</code>
使用Xtrabackup對資料庫進行部分備份
Xtrabackup也可以實作部分備份,即隻備份某個或某些指定的資料庫或某資料庫中的某個或某些表。但要使用此功能,必須啟用innodb_file_per_table選項,即每張表儲存為一個獨立的檔案。同時,其也不支援--stream選項,即不支援将資料通過管道傳輸給其它程式進行處理。
此外,還原部分備份跟還原全部資料的備份也有所不同,即你不能通過簡單地将prepared的部分備份使用--copy-back選項直接複制回資料目錄,而是要通過導入表的方向來實作還原。當然,有些情況下,部分備份也可以直接通過--copy-back進行還原,但這種方式還原而來的資料多數會産生資料不一緻的問題,是以,無論如何不推薦使用這種方式。
(1)建立部分備份
建立部分備份的方式有三種:正規表達式(--include), 枚舉表檔案(--tables-file)和列出要備份的資料庫(--databases)。
(a)使用--include
使用--include時,要求為其指定要備份的表的完整名稱,即形如databasename.tablename,如:
<code># innobackupex --include='^mageedu[.]tb1' /path/to/backup</code>
(b)使用--tables-file
此選項的參數需要是一個檔案名,此檔案中每行包含一個要備份的表的完整名稱;如:
<code># echo -e 'mageedu.tb1\nmageedu.tb2' > /tmp/tables.txt</code>
<code># innobackupex --tables-file=/tmp/tables.txt /path/to/backup</code>
(c)使用--databases
此選項接受的參數為資料名,如果要指定多個資料庫,彼此間需要以空格隔開;同時,在指定某資料庫時,也可以隻指定其中的某張表。此外,此選項也可以接受一個檔案為參數,檔案中每一行為一個要備份的對象。如:
<code># innobackupex --databases="mageedu testdb" /path/to/backup</code>
(2)整理(preparing)部分備份
prepare部分備份的過程類似于導出表的過程,要使用--export選項進行:
<code># innobackupex --apply-log --export /pat/to/partial/backup</code>
此指令執行過程中,innobackupex會調用xtrabackup指令從資料字典中移除缺失的表,是以,會顯示出許多關于“表不存在”類的警告資訊。同時,也會顯示出為備份檔案中存在的表建立.exp檔案的相關資訊。
(3)還原部分備份
還原部分備份的過程跟導入表的過程相同。當然,也可以通過直接複制prepared狀态的備份直接至資料目錄中實作還原,不要此時要求資料目錄處于一緻狀态。
===============================================完===================================
本文轉自 jinlinger 51CTO部落格,原文連結:http://blog.51cto.com/essun/1396832,如需轉載請自行聯系原作者