對於不少運維同行來講,平時管理mysql除了應開的需求查詢一些數據條目和監控性能外,更多的則是爲了保證數據的可靠性對其進行備份和複製的操做管理, 不過最近聽很多同行都說如今的互聯網已經進入了緩存和nosql爲王的時代,大可取代mysql這種關係型數據庫,不得不認可在大量甚至海量的業務且要求數據即時響應回饋的場景中,如微信,微博,緩存和nosql的重要性和性能體現(如redis),但要說取代mysql的話,我只能表示:呵呵mysql
其實mysqldump這種熱備+邏輯的備份方式被應用的仍是蠻多的,但其單線程的工做模式及生成sql寫入文件的這種方式,與文件系統級別的物理備份相比,效率就顯得有些差了。
redis
這裏介紹一下innodb的開源備份工具Xtrabackup,至於說其實現物理熱備的原理,簡單來講其理解innodb底層存儲機制,相似逐頁請求鎖定,不會產生阻塞和按數據塊來備份。percona官網對其和Innodb Hot Backup的所支持的功能和各項參數作了較詳細的對比,有興趣的朋友能夠看一下,地址 http://www.percona.com/software/percona-xtrabackup,固然了,他們不免有些王婆賣瓜之嫌,但我感受人家敢明目張膽的貼出來和Innodb Hot Backup進行叫板,並且也沒被mysql官方惹上什麼官司,就已經說明人家的實力了吧。若是平常工做中對mysql或者說innodb類的庫操做比較多的,建議你們多瞭解和關注一下percona的官網。其對Xtrabackup的推薦介紹中有如下幾點:sql
Backups that complete quickly and reliablyshell
Uninterrupted transaction processing during backups數據庫
Savings on disk space and network bandwidthcentos
Automatic backup verification緩存
Higher uptime due to faster restore time服務器
簡單理解的話就是:微信
快速可靠的徹底備份網絡
備份過程當中不會打擾到事務操做
能執行壓縮數據流網絡傳輸,有效節省帶寬和磁盤資源
自動備份校驗
恢復速度比較快
既然優勢這麼多,咱們來認識和使用一下這個工具,使用以前,請確實mysql的版本爲5.5+,若是安裝報錯相似:perl(Time:HiRes),用yum安裝上便可,若是想使用其一些高級特性比較導入導出單張表,那就請在配置文件中設置innodb_file_per_table = 1(對每一個新建立的表生成並使用單獨的表空間)。可以使用官方提供的rpm包直接安裝,下載地址: http://www.percona.com/downloads/XtraBackup/
個人操做系統環境爲centos6.2_64位,mysql版本爲5.5.33
yum -y install perl-Time-HiRes
rpm -ivh percona-xtrabackup-2.1.4-656.rhel6.x86_64.rpm
看一下安裝的文件,其中innobackupex爲主命令程序,使用時會自行判斷你的mysql版本是5.5仍是5.6,使用innobackupex --help可查看其使用的語法格式。
[root@gzy ~]# rpm -ql percona-xtrabackup /usr/bin/innobackupex /usr/bin/innobackupex-1.5.1 /usr/bin/xbcrypt /usr/bin/xbstream /usr/bin/xtrabackup /usr/bin/xtrabackup_55 /usr/bin/xtrabackup_56 /usr/share/doc/percona-xtrabackup-2.1.4 /usr/share/doc/percona-xtrabackup-2.1.4/COPYING
建立一個適用於備份操做的最小權限用戶:
mysql> grant reload,lock tables,replication client on *.* to 'backup'@'localhost' identified by '123456'; Query OK, 0 rows affected (0.30 sec) mysql> flush privileges; Query OK, 0 rows affected (0.08 sec)
接下來具體使用和測試一下備份innodb類型的庫,演示一下徹底+增量備份,最後用徹底+增量+二進制日誌恢復的過程。
innobackupex --user=backup -password=123456 /backup/
用戶是以前建立的備份用戶,/backup/是備份的目錄,在執行過程當中會打印不少執行時的信息,若是執行成功的話,最後會顯示:
innobackupex: Backup created in directory '/backup/2014-02-17_01-09-48' innobackupex: MySQL binlog position: filename 'mysql-bin.000021', position 354 140217 01:09:57 innobackupex: Connection to database server closed 140217 01:09:57 innobackupex: completed OK!
發現了嗎?自動在咱們的備份目錄下建立了個以當前日期和時間命名格式的目錄,查看一下,發現除了備份的相關庫和數據文件以外,還生成了一些xtrabackup相關文件。
[root@gzy ~]# ll /backup/2014-02-17_01-09-48/ total 26664 -rw-r--r--. 1 root root 260 Feb 17 01:09 backup-my.cnf -rw-r-----. 1 root root 27262976 Feb 17 01:09 ibdata1 drwxr-xr-x. 2 root root 4096 Feb 17 01:09 mydb drwxr-xr-x. 2 root root 4096 Feb 17 01:09 mysql drwxr-xr-x. 2 root root 4096 Feb 17 01:09 performance_schema drwxr-xr-x. 2 root root 4096 Feb 17 01:09 test -rw-r--r--. 1 root root 13 Feb 17 01:09 xtrabackup_binary -rw-r--r--. 1 root root 23 Feb 17 01:09 xtrabackup_binlog_info -rw-r-----. 1 root root 89 Feb 17 01:09 xtrabackup_checkpoints -rw-r-----. 1 root root 2560 Feb 17 01:09 xtrabackup_logfile drwxr-xr-x. 2 root root 4096 Feb 17 01:09 zabbix
這裏對其工做流程作一下說明,首先,使用innobakupex備份時,其會調用xtrabackup備份全部的InnoDB表,複製全部關於表結構定義的相關文件(.frm)、以及MyISAM、MERGE、CSV和ARCHIVE表的相關文件,同時還會備份觸發器和數據庫配置信息相關的文件。這些文件會被保存至一個以時間命令的目錄中。
xtrabackup_checkpoints : 備份類型(如徹底或增量)、備份狀態(如是否已經爲prepared狀態,這個爲準備工做,包括事務日誌和數據文件,把事務日誌中已提交的事務同步至數據文件,未提交的進行回滾)和LSN(日誌序列號)範圍信息;每一個InnoDB頁(一般爲16k大小)都會包含一個日誌序列號,即LSN。LSN是整個數據庫系統的系統版本號,每一個頁面相關的LSN可以代表此頁面最近是如何發生改變的。查看一下其內容:
[root@gzy ~]# cd /backup/2014-02-17_01-09-48/ [root@gzy 2014-02-17_01-09-48]# cat xtrabackup_checkpoints backup_type = full-backuped # 表示備份類型爲徹底備份 from_lsn = 0 # LSN號從0開始 to_lsn = 5618613 # LSN號到0結束 last_lsn = 5618613 # 最後的lsn號,換句話說,一會進行增量備份時會以這個數字開始,能夠理解爲 xtrabackup爲每次備份打的開始和結束的標記 compact = 0 # 0表示未啓用壓縮
xtrabackup_binlog_info: mysql服務器當前正在使用的二進制日誌文件及至備份這一刻爲止二進制日誌事件的位置。這個容易理解:
[root@gzy 2014-02-17_01-09-48]# cat xtrabackup_binlog_info mysql-bin.000021 354
xtrabackup_binary:備份中用到的xtrabackup的可執行文件,由於mysql版本是5.5,因此其調用的是/usr/bin/xtrabackup_55
[root@gzy 2014-02-17_01-09-48]# cat xtrabackup_binary xtrabackup_55
backup-my.cnf:備份命令用到的配置選項信息,也就是my.cnf配置文件中定義的相關參數
[root@gzy 2014-02-17_01-09-48]# cat backup-my.cnf # This MySQL options file was generated by innobackupex. # The MySQL server [mysqld] innodb_data_file_path=ibdata1:10M:autoextend innodb_log_files_in_group=2 innodb_log_file_size=5242880 innodb_fast_checksum=0 innodb_page_size=16384 innodb_log_block_size=512
接下來咱們添加一個叫test1的用戶,而後進行一次增量備份。
mysql> grant all on *.* to 'test1'@'localhost' identified by '123456'; Query OK, 0 rows affected (0.04 sec) mysql> flush privileges; Query OK, 0 rows affected (0.07 sec) mysql> select Host,User,Password from mysql.user; +------------------+--------+-------------------------------------------+ | Host | User | Password | +------------------+--------+-------------------------------------------+ | localhost | root | *2CF528CA7B474EC019B52035BDF52F143D939DBA | | gzy.tongzhou.com | root | *2CF528CA7B474EC019B52035BDF52F143D939DBA | | 127.0.0.1 | root | *2CF528CA7B474EC019B52035BDF52F143D939DBA | | % | zabbix | *2CF528CA7B474EC019B52035BDF52F143D939DBA | | localhost | backup | *6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9 | | localhost | test1 | *6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9 | +------------------+--------+-------------------------------------------+ 6 rows in set (0.01 sec)
每一個InnoDB的頁面都會包含一個LSN信息,每當相關的數據發生改變,相關的頁面的LSN就會自動增加。這正是InnoDB表能夠進行增量備份的基礎,即innobackupex經過備份上次徹底備份以後發生改變的頁面來實現。
增量備份的語法: innobackupex --incremental /backup --incremental-basedir=BASEDIR
其中,BASEDIR指的是徹底備份所在的目錄,此命令執行結束後,innobackupex命令會在/backup目錄中建立一個新的以時間命名的目錄以存放這次增量備份數據。--incremental意思是類型爲增量備份,另外,在執行過增量備份以後再一次進行增量備份時,其--incremental-basedir應該指向上一次的增量備份所在的目錄。
innobackupex -user=backup -password=123456 --incremental /backup/ --incremental-basedir=/backup/2014-02-17_01-09-48/
備份成功會顯示相關內容的,以及LSN號,備份生成的目錄,及二進制日誌文件及其pos點信息
xtrabackup: The latest check point (for incremental): '5618623' xtrabackup: Stopping log copying thread. .>> log scanned up to (5618623) xtrabackup: Transaction log of lsn (5618623) to (5618623) was copied. 140217 13:26:48 innobackupex: All tables unlocked innobackupex: Backup created in directory '/backup/2014-02-17_13-26-38' #這次增量生成的數據目錄 innobackupex: MySQL binlog position: filename 'mysql-bin.000021', position 574 140217 13:26:48 innobackupex: Connection to database server closed 140217 13:26:48 innobackupex: completed OK!
接下來咱們再進入mysql建立一個用戶test2
mysql> grant all on *.* to 'test2'@'localhost' identified by '123456'; Query OK, 0 rows affected (0.00 sec) mysql> flush privileges; Query OK, 0 rows affected (0.01 sec) mysql> select Host,User,Password from mysql.user; +------------------+--------+-------------------------------------------+ | Host | User | Password | +------------------+--------+-------------------------------------------+ | localhost | root | *2CF528CA7B474EC019B52035BDF52F143D939DBA | | gzy.tongzhou.com | root | *2CF528CA7B474EC019B52035BDF52F143D939DBA | | 127.0.0.1 | root | *2CF528CA7B474EC019B52035BDF52F143D939DBA | | % | zabbix | *2CF528CA7B474EC019B52035BDF52F143D939DBA | | localhost | backup | *6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9 | | localhost | test1 | *6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9 | | localhost | test2 | *6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9 | +------------------+--------+-------------------------------------------+ 7 rows in set (0.00 sec)
查看一下當前使用的二進制日誌:
mysql> show master status; +------------------+----------+--------------+------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | +------------------+----------+--------------+------------------+ | mysql-bin.000021 | 794 | | | +------------------+----------+--------------+------------------+ 1 row in set (0.00 sec)
接下來把這個二進制日誌備份到別處,並刪除mysql的數據目錄來進行恢復測試,此時並無再進行增量備份的操做哦!(注意!!!生產環境中mysql的二進制日誌文件與數據文件的有同等的重要性!因此其保存路徑必定要與mysql的數據目錄區分開的,且在硬件級別最少保證raid1,固然了使用mysql的複製結構如主從,多主等模型也是不可少的)
個人mysql 數據目錄爲/data
[root@gzy ~]# cp /data/mysql-bin.000021 /tmp [root@gzy ~]# ls /data/ gzy.tongzhou.com.err mysql mysql-bin.000006 mysql-bin.000012 mysql-bin.000018 test gzy.tongzhou.com.pid mysql-bin.000001 mysql-bin.000007 mysql-bin.000013 mysql-bin.000019 zabbix ibdata1 mysql-bin.000002 mysql-bin.000008 mysql-bin.000014 mysql-bin.000020 ib_logfile0 mysql-bin.000003 mysql-bin.000009 mysql-bin.000015 mysql-bin.000021 ib_logfile1 mysql-bin.000004 mysql-bin.000010 mysql-bin.000016 mysql-bin.index mydb mysql-bin.000005 mysql-bin.000011 mysql-bin.000017 performance_schema
接下來中止mysql進程並刪除/data......
Shutting down MySQL.... SUCCESS! [root@gzy ~]# rm -rf /data/* [root@gzy ~]#
如今四大皆空了,接下來用剛纔建立的徹底備份+增量備份+二進制日誌來進行恢復操做。
首先將已提交的事務進行「重放」,以後全部的增量備份數據將合併到徹底備份上,全部備份數據中未提交的事務進行「回滾」。
先進行徹底備份的準備:
innobackupex --apply-log --redo-only /backup/2014-02-17_01-09-48/
再進行增量備份的準備:
innobackupex --apply-log --redo-only /backup/2014-02-17_01-09-48/ --incremental-dir=/backup/2014-02-17_13-26-38/
確保2次操做都出現成功的提示:
completed OK!
由於增量備份的數據都已合併到徹底備份中去了,因此此時只恢復徹底備份便可
innobackupex --copy-back /backup/2014-02-17_01-09-48/
再來查看一下數據目錄/data
[root@gzy ~]# ll /data/ total 26644 -rw-r--r--. 1 root root 27262976 Feb 17 14:10 ibdata1 drwxr-xr-x. 2 root root 4096 Feb 17 14:10 mydb drwxr-xr-x. 2 root root 4096 Feb 17 14:10 mysql drwxr-xr-x. 2 root root 4096 Feb 17 14:10 performance_schema drwxr-xr-x. 2 root root 4096 Feb 17 14:10 test drwxr-xr-x. 2 root root 4096 Feb 17 14:10 zabbix
貌似恢復回來了?!好吧,把該目錄的屬主屬組變成mysql後啓動一下服務試試
[root@gzy ~]# chown mysql.mysql /data -R [root@gzy ~]# service mysqld start Starting MySQL........ SUCCESS!
提示啓動成功,咱們進入mysql來查看一下剛纔咱們所建立的測試用戶是否存在: