1. 程式人生 > >mysql 三種災備方式

mysql 三種災備方式

轉自: http://tchuairen.blog.51cto.com/3848118/1432606/

目標:

1.使用mysqldump實現從邏輯角度完全備份mysql,配合二進位制日誌備份實現增量備份

2.使用lvm照從物理角度實現幾乎熱備的完全備份,配合二進位制日誌備份實現增量備份

3.使用percona公司的xrabackup實現完全熱備份與增量熱備份

環境準備:

建立目錄用於存放二進位制檔案位置

  • mkdir /home/mybinlog

  • chown mysql:mysql /home/mybinlog

修改my.cnf

  • vim /etc/my.cnf

  • log-bin=/home/mybinlog/mysql-bin    ##二進位制日誌目錄及檔名字首

  • innodb_file_per_table = 1      ##啟用InnoDB表每表一檔案,預設所有庫使用一個表空間

  • 然後啟動mysql

匯入hellodb.sql,在庫內建立study表,插入一些資料。

  • mysql <~/Desktop/hellodb.sql

  • use hellodb

  • create table study  (id tinyint auto_increment primary key,name char(10));

  • insert into study (name) values ('redhat'),('php'),('asp'),('CCNA'),('MSIC'),('CCNP'),('HCSE');

wKiom1Ow3EvglsoAAACORfpuzF0937.jpg

建立用於存放備份的目錄

  • mkdir /home/mysqlbackup                                \\用於存放備份檔案

  • mkdir /home/mysqlbackup/mylogbin                \\用於存放備份的二進位制日誌           

  • mkdir /home/mysqlbackup/mylogstatus            \\用於存放二進位制日誌起始位置

  • chown -R mysql:mysql  /home/mysqlbackup         

一、使用mysqldump實現完全熱備+增量備份。

我們要使用mysqldump工具對innodb儲存引擎的資料庫做完全熱備,並且滾動二進位制日誌,為了下次恢復或者增量方便,還要記錄一下當前二進位制日誌檔案位置。

  • mysqldump -uroot -predhat --single-transaction --master-data=2 --all-databases --routines --events  > /home/mysqlbackup/mydb_all_`date +%F`.sql

  • flush logs

  • mysql -uroot -predhat -e 'show master status' > /home/mysqlbackup/mylogstatus/`date +%F-%H`.txt

選項註解:

  • --databases    \\指定資料庫名

  • --lock-all-tables    \\為所有表加讀鎖,如果使用的是非事務型表,推薦使用這個選項備份。

  • --master-data=2    \\在備份檔案中記錄當前二進位制日誌的位置,並且為註釋的,1是不註釋掉在主從複製中才有意義

  • --single-transaction    \\(使得轉儲的資料為事務開始前的資料)啟動一個大事物,併為每張表建立快照,基於此項能實現熱備InnoDB表,由此,不需要同時使用--lock-all-tables

  • --routines    \\同時,備份儲存過程和儲存函式

  • --events    \\同時,備份事件排程器程式碼

  • --all-databases    \\備份伺服器上的所有庫

這時我們又給資料庫添加了資料

  • create table  system(id tinyint auto_increment primary key,Name char(10));

  • insert into system (Name) values ('windows'),('Centos'),('fedora');

做一次增量備份

檢視剛剛做完全備份,滾動日誌之後記錄二進位制日誌檔案與起始位置。

  • cat /home/mysqlbackup/mylogstatus/2014-06-30-15.txt

wKioL1OxGXawDjl5AADnXptXL2o179.jpg

檢視當前位置

  • show master status;

wKioL1OxGHuCT8PgAADBxKomiOM625.jpg

  • # mysqlbinlog --start-position=107 --stop-position=504 /home/mybinlog/mysql-bin.000007 >/home/mysqlbackup/incremental-`date +%F-%H`.sql

記錄當前show master status 狀態

  • mysql -uroot -predhat -e 'show master status' > /home/mysqlbackup/mylogstatus/`date +%F-%H`.txt

這時資料庫又加入了一些資料

  • insert into system (Name) values ('rlel'),('suselinux'),('VMX');

  • create table firm(id tinyint auto_increment primary key ,name char(10))

  • insert into firm (name) values ('baidu'),('huabang'),('sohu');

wKioL1OxHvPDNQqeAAEyDuASp-s279.jpg

模擬這時資料庫突然崩了

  • service mysqld stop

  • rm -rf /mydata/data/*

假如重灌了mysql,接下來完成恢復

  • ./scripts/mysql_install_db  --user=mysql --datadir=/mydata/data/

  • # service mysqld start

匯入完全備份與增量備份。

  • mysql < /home/mysqlbackup/mydb_all_2014-06-30.sql

  • mysql < /home/mysqlbackup/incremental-2014-06-30-16.sql

分析二進位制日誌,匯出從上一次增量以後,到崩潰時候檔案。

檢視上一次記錄的二進位制日誌檔案和位置。

  • cat /home/mysqlbackup/mylogstatus/2014-06-30-16.txt

wKiom1OxKvuAUogzAAD_goe9gos103.jpg

  • mysqlbinlog --start-position=504 /home/mybinlog/mysql-bin.000007 >/home/mysqlbackup/huifu-2014-06-30-17.sql

  • mysql -uroot -predhat < /home/mysqlbackup/huifu-2014-06-30-17.sql

wKiom1OxLZrTZaERAAGRNFqF-Sk032.jpg

為了下次做備份方便,再滾動下日誌,記錄下show master status; 狀態。

這就是一次使用mysqldump完整備份+二進位制日誌進行恢復的例項。

二、使用LVM的快照實現熱備。

前提是mysql的資料目錄,要在lvm邏輯捲上。

建立邏輯卷,掛載這些就省略了。

在MySQL中為所有表加讀鎖,不要關閉終端,否則鎖將失效,滾動日誌

  • flush tables with read lock;

  • flush logs;

記錄當前show master status狀態,建立快照卷,釋放讀鎖。

  •  mysql -uroot -p -e 'show master status'>/var/mybackup/logstatus/`date +%F-+%H`.txt

  • lvcreate -L 200M -n mydata-snap -p r -s /dev/mapper/vg0-lv0

  • unlock tables;

掛載快照,拷備出來,解除安裝快照,刪除快照

  • mkdir /mysnap

  • mount /dev/vg0/mydata-snap  /mysnap/

  • cp /mysnap/* /var/mybackup/2014-06-30/ -a

  • umount /mysnap/

  • lvremove /dev/vg0/mydata-snap

  • 這樣備份就完成了

這時有使用者建立了表,插入了資料。

  • create table uu(id int primary key,yy int);

  • insert into uu (id,yy) values (123,111),(223,121);

wKiom1OxgB7iDMcFAABsZIxKkHI698.jpg

然後資料庫崩潰了,現在測試下是否能完全+增量恢復。

  • /etc/init.d/mysqld stop

  • rm -rf /mydata/data/*

把備份資料拷貝回來,啟動服務,檢視記錄的show mater status;狀態,根據二進位制日誌匯出.sql指令碼,再匯入執行sql指令碼。

  • cp /var/mybackup/2014-06-30/* /mydata/data/ -a

  • service mysqld start

  • cat /var/mybackup/logstatus/2014-06-30-+22.txt

wKiom1Oxg2DTY-raAADXDEVCwqQ040.jpg

  • mysqlbinlog --start-position=107 /var/mybinlog/mysql-bin.000002 >/var/mybackup/incremental-2014-06-30-23.sql

  • mysql -uroot -predhat < /var/mybackup/incremental-2014-06-30-23.sql

wKioL1OxhCqg2qLpAAEv3ofDhIA861.jpg

好,lvm快照+二進位制日誌恢復完成。

三、使用xtrabackup實現對mysql進行熱備(完全+增量)。

安裝程式

  • yum install percona-xtrabackup-2.1.4-656.rhel6.i686.rpm

完全熱備資料庫。

  • innobackupex --user=root --password=redhat /var/mybackup/

這時假設資料庫崩潰了

  • service mysqld stop

  • rm -rf /mydata/data/*

預處理備份,恢復資料,修改屬主屬組,啟動mysql。

  • innobackupex --apply-log /var/mybackup/2014-07-01_13-49-38/

  • innobackupex --copy-back /var/mybackup/2014-07-01_13-49-38/

  • chown -R mysql.mysql /mydata/

  • service mysqld start

服務啟動了,恢復成功,每一次資料庫恢復完成以後,要立即做一次完全備份。

  • innobackupex --user=root --password=redhat /var/mybackup/

資料庫運行了一段時間,加入了一些資料。

  • create database redhat;

  • use redhat

  • create table  study(id tinyint auto_increment primary key,students char(10),course char(10));

  • insert into study (students,course) values ('tuchao','linux'),('fangchao','bashshell'),('tyz','lvm'),('yujiaqing','auto china');

  • select * from study;

wKiom1OyU1qhE8uGAADEtZh0hPQ938.jpg

做第一次增量備份。

  • innobackupex --user=root --password=redhat --incremental /var/mybackup/incrbak/ --incremental-basedir=/var/mybackup/2014-07-01_14-41-41/

  • --incremental-basedir //這裡要指定上一次最近的備份為基準,進行增量備份。

檢視檢查點檔案

  • cat incrbak/2014-07-01_14-51-28/xtrabackup_checkpoints

wKiom1OyXN3h92mKAAD9WV5AmJw273.jpg

再次給mysql新增一些資料。

  • insert into study (students,course) values ('wujihe','Java'),('qiulin','Ios kaifa');

wKioL1OyXqOTKaKcAAFncAyooeg011.jpg

做第二次增量備份。

注意:這裡的--incremental-basedir=指的是上一次增量備份的位置

  • innobackupex --user=root --password=redhat --incremental  /var/mybackup/incrbak/ --incremental-basedir=/var/mybackup/incrbak/2014-07-01_14-51-28/

檢視檢查點檔案

  • cat incrbak/2014-07-01_15-11-57/xtrabackup_checkpoints

backup_type = incremental

from_lsn = 1667183

to_lsn = 1667534

last_lsn = 1667534

compact = 0

mysql又運行了一段時間,再次加入了一些資料。

  • create table test(id tinyint auto_increment primary key ,name char(10));

  • insert into test (name) values ('aaa'),('bbb'),('redhat'),('hello world'),('centos');

  • select * from test;

wKioL1OyYhuCTOFvAACodkVZ8U8897.jpg

這時資料庫崩潰了。

  • service mysqld stop

  • rm -rf /mydata/data/*

預處理完全備份

  • innobackupex --apply-log --redo-only /var/mybackup/2014-07-01_14-41-41/

  • --redo-only //只做提交處理,不做回滾。

預處理第一個增量到完全備份

  • innobackupex --apply-log --redo-only /var/mybackup/2014-07-01_14-41-41/ --incremental-dir=/var/mybackup/incrbak/2014-07-01_14-51-28/

預處理第二個增量到完全備份

  • innobackupex --apply-log --redo-only /var/mybackup/2014-07-01_14-41-41/ --incremental-dir=/var/mybackup/incrbak/2014-07-01_15-11-57/

切換到完全備份的目錄裡面

  • cd /var/mybackup/2014-07-01_14-41-41/

檢視檢查點檔案

  • cat xtrabackup_checkpoints

backup_type = full-prepared

from_lsn = 0

to_lsn = 1667534

last_lsn = 1667534

compact = 0

你會發現日誌序列號範圍已經變成第二次增量備份後的日誌序列號了,表示增量同步成功。

恢復完全備份,修改檔案許可權,啟動服務。

  • innobackupex --copy-back /var/mybackup/2014-07-01_14-41-41/

  • chown -R mysql.mysql /mydata/

  • service mysqld start

登陸mysql互動介面檢視資料。

wKioL1OyaF-BYzKKAAFxoWwAQTU441.jpg

但是我們在第二次增量備份之後建立test表和插入的資料都沒有,沒關係我們通過二進位制日誌來恢復。

檢視第二次增量備份後xtrabackup幫我們建立的檔案(xtrabackup_binlog_info ),裡面記錄了二進位制日誌備份後的狀態和位置。

  • cat /var/mybackup/incrbak/2014-07-01_15-11-57/xtrabackup_binlog_info 

mysql-bin.000009941

分析二進位制日誌,匯出sql指令碼,並執行。

  • mysqlbinlog --start-position=941 /home/mybinlog/mysql-bin.000009 >/tmp/huifu-15-56.sql

  • source /tmp/huifu-15-56.sql

wKiom1Oya5_QcCIGAAEMoDcUHes997.jpg

mysql資料庫的災備及恢復完成。