小型網站MYSQL問題二:Percona Xtrabackup實現數據庫備份和恢復

故事背景:前面大膽的選擇了innodb,接下來就要考慮數據庫的備份和恢復。俗話說“常在河邊走,哪能不濕鞋“,自從接觸數據這塊,使我一直對它保持敬畏之心。在這里使用了percona公司的xtrabckup工具來實現數據庫備份和恢復。操作步驟記錄如下:

1、安裝軟件倉庫(不要問我為什么不用源碼安裝,好吧,其實我懶。)

wget https://www.percona.com/downloads/percona-release/redhat/0.1-3/percona-release-0.1-3.noarch.rpm
rpm -ivh percona-release-0.1-3.noarch.rpm
rpm -ql percona-release
    /etc/pki/rpm-gpg/RPM-GPG-KEY-Percona
    /etc/yum.repos.d/percona-release.repo
    /usr/share/doc/percona-release-0.1
    /usr/share/doc/percona-release-0.1/RPM-GPG-KEY-Percona
yum -y install percona-xtrabackup

2、備份策略及準備測試數據

采用先全備份加增量備份的方案。在利用xtrabackup對innodb表做備份工作時,建議mysql啟用“innodb_file_per_table=1”變量且同時啟用innodb_file_per_table = 1 innodb_expand_import = 1

這樣使每表都有一個自己的表空間,不然很難進行單表備份和還原。還有二進制日志文件就不要與數據文件放在同一個目錄了,你不想當數據丟失時,二進制日志也一同丟了。

測試數據:

mysql> SELECT VERSION(); 
    +------------+ 
    | VERSION()  | 
    +------------+ 
    | 5.5.36-log | 
    +------------+ 
    1 row in set (0.00 sec) 
mysql> SHOW DATABASES; #創建了一個mydb1數據庫 
    +--------------------+ 
    | Database          | 
    +--------------------+ 
    | information_schema | 
    | mydb1              | 
    | mysql              | 
    | performance_schema | 
    | test              | 
    +--------------------+ 
mysql> SELECT * FROM mydb1.tb1; #表中只有一條數據 
    +----+------+------+ 
    | id | name | age  | 
    +----+------+------+ 
    |  1 | tom  |  10 | 
    +----+------+------+

創建備份數據存放目錄:

mkdir -pv /backup/{fullbackup,incremental} 
    #fullbackup  存放全備份數據 
    #incremental 存放增量備份數據

創建復制用戶:

mysql> GRANT RELOAD,LOCK TABLES,REPLICATION CLIENT ON *.* TO 'bkuser'@'localhost' IDENTIFIED BY '123456'; 
mysql> FLUSH PRIVILEGES;

3、全備份數據

innobackupex --user=bkuser --password=123456 /backup/fullbackup/ 
    #最后出現“150415 16:30:23  innobackupex: completed OK!”這樣的信息表示備份完成 
ls /backup/fullbackup/2015-04-15_16-30-19/ 
    backup-my.cnf  mysql              xtrabackup_binary      xtrabackup_logfile 
    ibdata1        performance_schema  xtrabackup_binlog_info 
    mydb1          test                xtrabackup_checkpoints 
cat /backup/fullbackup/2015-04-15_16-30-19/xtrabackup_checkpoints 
    backup_type = full-backuped 
    from_lsn = 0 
    to_lsn = 1644877 
    last_lsn = 1644877 
    compact = 0

4、增量備份數據

先做一些數據修改:

mysql> INSERT INTO mydb1.tb1 (name,age) VALUES ('jack',20); 
mysql> SELECT * FROM tb1;  #增加一條數據 
    +----+------+------+ 
    | id | name | age  | 
    +----+------+------+ 
    |  1 | tom  |  10 | 
    |  2 | jack |  20 | 
    +----+------+------+

做第一次增量備份:

innobackupex --user=bkuser --password=123456 --incremental /backup/incremental/ --incremental-basedir=/backup/fullbackup/2015-04-15_16-30-19/ 
ls /backup/incremental/2015-04-15_16-42-00/ 
    backup-my.cnf  mydb1              test                    xtrabackup_checkpoints 
    ibdata1.delta  mysql              xtrabackup_binary      xtrabackup_logfile 
    ibdata1.meta  performance_schema  xtrabackup_binlog_info 
cat /backup/incremental/2015-04-15_16-42-00/xtrabackup_checkpoints 
    backup_type = incremental 
    from_lsn = 1644877  #這是全備時的"to_lsn"值 
    to_lsn = 1645178 
    last_lsn = 1645178 
    compact = 0

再做數據修改:

mysql> INSERT INTO mydb1.tb1 (name,age) VALUES ('jason',30); 
mysql> SELECT * FROM tb1; 
    +----+-------+------+ 
    | id | name  | age  | 
    +----+-------+------+ 
    |  1 | tom  |  10 | 
    |  2 | jack  |  20 | 
    |  3 | jason |  30 | 
    +----+-------+------+

做第二次增量備份:

innobackupex --user=bkuser --password=123456 --incremental /backup/incremental/ --incremental-basedir=/backup/incremental/2015-04-15_16-42-00/ 
    #這里的"--incremental-basedir"是指向第一次增量備份的目錄 
ls /backup/incremental/2015-04-15_16-49-07/ 
    backup-my.cnf  mydb1              test                    xtrabackup_checkpoints 
    ibdata1.delta  mysql              xtrabackup_binary      xtrabackup_logfile 
    ibdata1.meta  performance_schema  xtrabackup_binlog_info 
cat /backup/incremental/2015-04-15_16-49-07/xtrabackup_checkpoints 
    backup_type = incremental 
    from_lsn = 1645178 #這是第一次增量的"to_lsn"值 
    to_lsn = 1645463 
    last_lsn = 1645463 
    compact = 0

再來做一次數據修改,以便演示根據二進制日志做時間點的恢復:

mysql> INSERT INTO mydb1.tb1 (name,age) VALUES ('lucky',40); 
mysql> SELECT * FROM tb1; 
    +----+-------+------+ 
    | id | name  | age  | 
    +----+-------+------+ 
    |  1 | tom  |  10 | 
    |  2 | jack  |  20 | 
    |  3 | jason |  30 | 
    |  4 | lucky |  40 | 
    +----+-------+------+

5、恢復

5.1、數據破壞

service mysqld stop 
rm -rf /mnt/mydata/data/*  #把數據目錄數據全部刪除

對于xtrabackup做數據恢復的理解:

xtrabackup做數據恢復與mysqldump這樣的邏輯備份工作的恢復有很大的區別,xtrabackup進行數據恢復時需要把各個增量的數據備份與全備份的數據進行合并,

對每次增量備份的合并只能將已提交的事務進行重放(redo),對合備份的數據恢復也只能做redo操作,把各個增量都合并完成后再把沒有提交的事務進行回滾(undo)操作,

合并完增量備份后,全備份的“xtrabackup_checkpoints”文件中的“last_lsn”應該是最后一次增量備份時的值,這些合并做redo的過程就是恢復數據前的準備工作(prepare)。

而真正在做數據恢復,建議先把全備和增量備份的文件都copy一份為副本,避免操作失誤導致備份文件的損壞。

5.2、數據恢復的準備(prepare)工作

#準備全備份的數據 
innobackupex --apply-log --redo-only /backup/fullbackup/2015-04-15_16-30-19/ 
#準備第一次增量數據 
innobackupex --apply-log --redo-only /backup/fullbackup/2015-04-15_16-30-19/ --incremental-dir=/backup/incremental/2015-04-15_16-42-00/ 
#準備第二次增量數據 
innobackupex --apply-log --redo-only /backup/fullbackup/2015-04-15_16-30-19/ --incremental-dir=/backup/incremental/2015-04-15_16-49-07/
cat /backup/fullbackup/2015-04-15_16-30-19/xtrabackup_checkpoints 
    backup_type = full-prepared 
    from_lsn = 0 
    to_lsn = 1645463 #這是最后一次增量備份的位置,到此數據已全部合并 
    last_lsn = 1645463 
    compact = 0

5.3、真正數據恢復

innobackupex --copy-back /backup/fullbackup/2015-04-15_16-30-19/  #僅一個“--copy-back”選項 
ls /mnt/mydata/data/ 
    ibdata1  mydb1  mysql  performance_schema  test
chown -R mysql.mysql /mnt/mydata/data/  #修改恢復數據的屬主與屬組 
service mysqld start 
    Starting MySQL.. SUCCESS! 
mysql> SELECT * FROM mydb1.tb1;  #檢查數據 
    +----+-------+------+ 
    | id | name  | age  | 
    +----+-------+------+ 
    |  1 | tom  |  10 | 
    |  2 | jack  |  20 | 
    |  3 | jason |  30 | 
    +----+-------+------+ 
#lucky信息還沒有恢復

5.4、利用二進制日志文件基于時間點恢復

查看最后一次增量備份時的二進制日志文件及position信息:
cat /backup/incremental/2015-04-15_16-49-07/xtrabackup_binlog_info 
    mysql-bin.000031    1665  
mysqlbinlog --start-position=1665 /var/log/mysql_log/mysql-bin.000031 > /tmp/position.sql 
    #用mysqlbinlog工具導出最后一次增量備份后的sql操作
導入數據:
mysql> source /tmp/position.sql 
mysql> SELECT * FROM mydb1.tb1; 
    +----+-------+------+ 
    | id | name  | age  | 
    +----+-------+------+ 
    |  1 | tom  |  10 | 
    |  2 | jack  |  20 | 
    |  3 | jason |  30 | 
    |  4 | lucky |  40 | 
    +----+-------+------+ 
#數據全部恢復

6、總結

利用innobackupex工具可對在有混合存儲引擎的場景下對數據庫進行全備份,當是備份innodb表時innobackupex腳本內部會自動調用xtrabackup工具來進行備份操作,

在數據還原時應停止mysql實例,清空數據目錄,然后先做prepare準備工作,第二步才是真正的數據還原(–copy-back),數據還原到數據目錄后不要忘記修改數據目錄的權限。

當然innobackupex工具也能實現對單庫單表的導出、導出,如果是對Innodb表,那建議直接用xtrabackup工具,這樣更直觀的使用各個選項進行備份。

============================華麗分隔線(下面是重點)================================================

背景:在到第5.3步的時候,數據庫啟動失敗。why、what、fuck。說好的一條龍服務?

痛定思痛,上日志。

151216 11:16:20
mysqld_safe Starting mysqld daemon with databases from /data/mysql
151216 11:16:20 [Note] /usr/libexec/mysqld (mysqld 5.5.47-log) starting as process 2931 ...
151216 11:16:20 [Note] Plugin 'FEDERATED' is disabled.
151216 11:16:20 InnoDB: The InnoDB memory heap is disabled
151216 11:16:20 InnoDB: Mutexes and rw_locks use GCC atomic builtins
151216 11:16:20 InnoDB: Compressed tables use zlib 1.2.3
151216 11:16:20 InnoDB: Using Linux native AIO
151216 11:16:20 InnoDB: Initializing buffer pool, size = 128.0M
151216 11:16:20 InnoDB: Completed initialization of buffer pool
InnoDB: Error: log file ./ib_logfile0 is of different size 0 50331648 bytes        #這里是48M
InnoDB: than specified in the .cnf file 0 5242880 bytes!           #這里是5M
151216 11:16:20 [ERROR] Plugin 'InnoDB' init function returned error.
151216 11:16:20 [ERROR] Plugin 'InnoDB' registration as a STORAGE ENGINE failed.   #注冊引擎失敗,打擊好大
151216 11:16:20 [ERROR] Unknown/unsupported storage engine: innodb     #什么,又不支持innodb
151216 11:16:20 [ERROR] Aborting
 
151216 11:16:20 [Note] /usr/libexec/mysqld: Shutdown complete
 
151216 11:16:20 mysqld_safe mysqld from pid file /var/run/mysqld/mysqld.pid ended

首先我刪除了恢復到/data/mysql目錄下面的ibdata1和ib_logfile0、ib_logfile1,此時可以啟動數據庫,然而提示表不存在。

向各位老師請教后,修改innodb_log_file_size=48M并寫入/etc/my.cnf,啟動正常。

總結:innodb_log_file_size參數屬于mysql系統參數,當配置不當時,mysql會啟動失敗。使用xtrabackup備份時默認值是5M,但是當遷移到新的環境后,初始化為48M,導致不匹配。后續應該將此參數寫入/etc/my.cnf防止遷移帶來的參數不匹配問題。

Command-Line Format --innodb_log_file_size=#
System Variable Name innodb_log_file_size
Variable Scope Global
Dynamic Variable No
Permitted Values Type integer
Default 5242880
Min Value 1048576
Max Value 4GB / innodb_log_files_in_group

The size in bytes of each log file in a log group. The combined size of log files (innodb_log_file_size * innodb_log_files_in_group) cannot exceed a maximum value that is slightly less than 4GB. A pair of 2047 MB log files, for example, would allow you to approach the range limit but not exceed it. The default value is 5MB. Sensible values range from 1MB to 1/N-th of the size of the buffer pool, where N is the number of log files in the group. The larger the value, the less checkpoint flush activity is needed in the buffer pool, saving disk I/O. Larger log files also make crash recovery slower, although improvements to recovery performance in MySQL 5.5 and higher make the log file size less of a consideration. For general I/O tuning advice, 

具體參考:http://dev.mysql.com/doc/refman/5.5/en/innodb-parameters.html#sysvar_innodb_log_file_size

原創文章,作者:陳近南,如若轉載,請注明出處:http://www.www58058.com/10139

(1)
陳近南陳近南
上一篇 2015-12-19 20:09
下一篇 2015-12-19 20:30

相關推薦

  • 6個變態的C語言Hello World程序

    下面的六個程序片段主要完成這些事情: 輸出Hello, World 混亂C語言的源代碼 下面的所有程序都可以在GCC下編譯通過,只有最后一個需要動用C++的編譯器g++才能編程通過。 hello1.c   #define _________ }     #define …

    Linux干貨 2015-04-01
  • Linux iptables配置應用

                    Linux iptables配置應用 概述:    Linux的防火墻體系主要工作在網絡層,只對tcp/ip數據包實施過濾和限制,屬于典型的包過濾防火墻(或稱為網絡層防火墻)。Linux的防火墻體系基于內核編碼實現,因…

    系統運維 2016-11-18
  • 第一周的學習總結

       本人是Linux 小白,0基礎。加入馬幫開始Linux之旅。由于完全不懂Linux,所以在學習的過程中,每課都要看上2遍。接下來說說我第一周所學的內容。 首先是了解到了計算機基礎知識,計算機的組成部分、CPU架構類型、其他外圍設備。 操作系統基礎知識進程管理、內存管理、網絡管理、驅動管理、安全管理等。 Linux的起源、發行版以及構…

    Linux干貨 2016-02-28
  • Linux中Vim編輯器的使用

    Linux中Vim編輯器的使用 Vim功能介紹 vim是一款功能豐富而強大的文本編輯器,支持語法高亮,支持多窗口編輯,是vi文本編輯器的增強版。如果在CentOS7.2中如果是選擇最小化安裝,其默認是沒有安裝vim rpm包的,需要自行安裝,可以使用yum工具進行在線安裝。  vim至今已經走過了25個春秋,現在8.0版的已經發布了。  …

    Linux干貨 2016-12-02
  • 文件查找:locate/find

    文件查找就是在文件系統上查找符合條件的文件,工具名分別為:locate和find locate是非實時查找或數據庫查找的工具;而find則是實時查找工具。 locate locate依賴于事先構建的索引。索引的構建是在系統較為空閑時自動進行(即為周期性任務),也可以手動更新數據庫(updatedb) 注意:索引構建過程需要遍歷整個根文件系統,極其消耗資源。 …

    Linux干貨 2016-03-12
  • corosync+pacemaker+drbd+mysql來實現mysql的高可用和數據的同步

    實現拓撲圖: 實驗流程: 先對兩主機安裝上corosync和pacemaker 兩主機安裝drbd服務,并且設置好drbd的組設備 選擇drbd主節點上,進行數據庫的初始化 進行資源的定義和配置 測試 實驗前,我們還需要做一些準備工作: 1、時間必須保持同步   使用ntp服務器 2、節點必須名稱互相通信    解析節點名稱 &…

    Linux干貨 2015-11-10

評論列表(3條)

  • stanley
    stanley 2015-12-19 20:22

    非常不錯,久違的好博客,已置頂

  • 以馬內利
    以馬內利 2015-12-21 08:54

    我也發現innodb_log_file_size的問題了,哈哈。 這個坑貌似配過的都得踩一腳

  • bigwinner
    bigwinner 2016-04-14 11:05

    樓主寫的十分詳細,線上如果出問題,不會有時間一步一步的這么去恢復的,都是通過腳本實現的;

欧美性久久久久