天天看點

MariaDB-之基于mysqldump 、lvm-snapshot、 xtrabackup的備份

本文主要講述基于mysqldump、邏輯卷的快照和Xtrabackup做資料庫的備份與複制及注意事項

  做備份的目錄目的為做災難恢複、做審計、測試,要對備份的資料做恢複性測試

  備份類型

      根據備份時,資料庫伺服器是否線上,可以分為

          冷備:cold backup    

          溫備:warm backup 全局施加共享鎖,隻能讀,不能寫

          熱備:hot backup    

      根據備份的資料集,可以分為:

          完全備份 full backup

          部分備份 partial backup

      根據備份時的接口(直接備份資料檔案還是通過mysql伺服器導出資料)

          實體備份:直接複制(歸檔)資料檔案的備份方式

          邏輯備份:把資料從庫中提取出來儲存為文本檔案

      根據備份時是備份整個資料還是僅備份變化的資料,可以分為

          增量備份 incremental backup

          差異備份 differential backup 從上一次完全備份開始備份

   備份政策:

       選擇備份方式

       選擇備份時間

       考慮恢複成本

       考慮恢複時長

       考慮備份成本:施加鎖的時間,備份時長,備份負載

   備份對象:

       資料

       配置檔案

       代碼:存儲過程、存儲函數、觸發器

       OS相關的配置檔案,如crontab配置計劃及相關腳本

       跟複制相關的配置資訊:二進制日志檔案

   常用的備份工具簡介

       mysqldump,單線程,是一個邏輯備份工具,可以對InnoDB熱備、MyISAM溫備、Aria溫備

       缺點:備份和恢複過程較慢,很難實作差異或增量備份

       mysqldumper:多線程的mysqldump    

       缺點:很難實作差異或增量備份

       基于邏輯卷快照:接近于熱備的工具,因為要先請求全局鎖,而後建立快照,并在建立完成後釋放全局鎖,可以使用cp、tar等工具進行實體備份,備份和恢複歲都很快

       缺點:很難實作增量備份,并且請求全局鎖需要等待一段時間,在繁忙的伺服器上尤其如此

       select語句:

       備份:select clause into outfile '/path/to/somefile'

       恢複:load data infile '/path/to/somefile' into table 'tb_name'

       Innobase:商業備份工具,

       innobackup

       Xtarbackup: 由Percona提供的開源備份工具。

       mysqlhostcopy:幾乎冷備

本實驗資料目錄是放在邏輯卷組上的,目錄為/mydata/data ,基于 10.0.10-MariaDB實作,MariaDB的安裝可以參考本人Mysql的部落格來實作

一、mysqldump

      mysqldump僅适用于資料集較小場景

      用法:mysqldump [options] [db_name [tbl_name ...]]

      主要選項解釋:

      --all-databases, -A:備份所有資料庫

      --databases, -B:要備份的資料庫,可以同時備份多個,使用空格分隔

      --flush-logs, -F:備份前、請求到鎖之後滾動日志,要記錄下複制時的二進制日志

      --flush-privileges:通知資料庫重讀授權表

      --host=host_name, -h host_name:要備份的資料庫的主機名,可以基于網絡備份

      --lock-all-tables, -x:請求鎖定所有表之後再備份,對MyISAM,InnoDB,Aria做溫備

      --single-transaction:能夠對InnoDB存儲引擎實作熱備

      -u usename 備份的使用者名

      -p password 登陸資料庫的密碼

      --events:備份事件排程器代碼

      --routines:備份存儲過程和存儲函數

      --triggers:備份觸發器

      --master-date={0|1|2},0表示不記錄,1表示距離為change master 語句,2表示記錄為注釋的change master語句

備份執行個體:

本實驗mysql是沒有密碼的,如果有則加-u -p選項

[root@master ~]# mysqldump --databases hellodb --lock-all-tables --flush-logs --master-data=2 >/tmp/db.sql      

備份完之後,再修改插入一些資料庫資料,

MariaDB [none]>use hellodb
 MariaDB [hellodb]> insert into classes values (13,'xx',12);
Query OK, 1 row affected (0.40 sec)      

把資料庫全部删除。用DROP指令

MariaDB [(none)]> drop database hellodb      

檢視/tmp/db.sql,可以看見備份時的二進制日志位置

然後進行二進制日志備份:

[root@master ~]# mysqlbinlog --start-position=367 --stop-position=555 /binlog/mysql-bin000001 > /tmp/db1.sql      

恢複資料:打開mysql

先關閉二進制日志,導入完全備份

MariaDB [(none)]> set session sql_log_bin=0
MariaDB [(none)]> source /tmp/db.sql //導入備份檔案      

然後導入二進制備份:

MariaDB [(none)]> source /tmp/db1.sql //導入備份檔案      

開啟二進制日志:

MariaDB [(none)]> set session sql_log_bin=1      

檢視資料是否恢複:

MariaDB-之基于mysqldump 、lvm-snapshot、 xtrabackup的備份

注:在實際恢複時最好編輯my.cnf配置檔案,添加如下項:

skip-networking    //跳過網絡功能來恢複資料

二、基于lvm邏輯卷的快照備份

1、事務日志跟資料檔案必須在同一個卷上;

2、建立快照卷之前,要請求MySQL的全局鎖;在快照建立完成之後釋放鎖;

3、請求全局鎖完成之後,做一次日志滾動;做二進制日志檔案及位置标記(手動進行);

4、日志檔案與資料庫目錄不在同一目錄下

         備份步驟:

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

MariaDB [(none)]> flush tables with read lock;
Query OK, 0 rows affected (0.00 sec)
MariaDB [(none)]> flush logs;
Query OK, 0 rows affected (0.06 sec)      

         2、做二進制日志檔案及位置标記(手動進行);        

[root@master ~]#  mysql -e "show master status" > logs.txt
[root@master ~]#  cat logs.txt
File    Position    Binlog_Do_DB    Binlog_Ignore_DB
master-bin.000003   367      

        3、建立快照卷    

[root@master ~]# lvcreate -L 1G -s -n mydata-snap -p r /dev/myvg/lvl
Logical volume "mydata-snap" created      

           4、釋放全局鎖      

MariaDB [(none)]> unlock tables;
Query OK, 0 rows affected (0.00 sec)      

        5、挂載快照卷并備份

[root@master ~]# mount /dev/myvg/mydata-snap /mnt -o ro
[root@master ~]# cp -a /mnt/* /backup/2014-04-13      

        6、備份完成之後,删除快照卷

[root@master ~]#  umount /mnt
[root@master ~]#  lvremove /dev/myvg/mydata-snap      

把資料庫目錄删掉

        恢複:

         1、二進制日志儲存好;

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

mysqlbinlog --start-position=367 /binlog/mysql-bin000003 > /tmp/db2.sql      

         2、還原資料,修改權限及屬主屬組等,并啟動mysql          

# cp -a /backup/2014-04-13/* /mydata/data
# chown -R mysql.mysql /mydata/data/      

         3、做即時點還原            

MariaDB [(none)]> set session sql_log_bin=0
MariaDB [(none)]> source /tmp/db2.sql
MariaDB [(none)]> set session sql_log_bin=1      

三、基于Xtrabackup備份與恢複

1、簡介

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

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

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

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

(4)自動實作備份檢驗;

(5)還原速度快;

2、安裝

wget http://www.percona.com/redir/downloads/XtraBackup/LATEST/RPM/rhel6/x86_64/percona-xtrabackup-2.1.8-733.rhel6.x86_64.rpm
yum install percona-xtrabackup-2.1.8-733.rhel6.x86_64.rpm -y      

3.完全備份的實作  

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

MariaDB [(none)]>  create user 'backup'@'localhost' identified by '123';
MariaDB [(none)]> revoke all privileges,grant option from 'backup'@'localhost';
MariaDB [(none)]> grant reload,lock tables,replication client on *.* to 'backup'@'localhost';
MariaDB [(none)]> flush privileges;      

3.1 完全備份

[root@master ~]# innobackupex --user=backup --password=123 /backup      
//如果執行正确,其最後輸出的幾行資訊通常如下:
innobackupex: Backup created in directory '/backup/2014-04-13_16-03-47'
innobackupex: MySQL binlog position: filename 'mysql-bin.000006', position 1409
140413 16:03:54  innobackupex: Connection to database server closed
140413 16:03:54  innobackupex: completed OK!      

3.2、準備(prepare)一個完全備份

一般情況下,在備份完成後,資料尚且不能用于恢複操作,因為備份的資料中可能會包含尚未送出的事務或已經送出但尚未同步至資料檔案中的事務。是以,此時資料檔案仍處理不一緻狀态。“準備”的主要作用正是通過復原未送出的事務及同步已經送出的事務至資料檔案也使得資料檔案處于一緻性狀态。

innobakupex指令的--apply-log選項可用于實作上述功能。如下面的指令:

[root@master ~]# innobackupex --apply-log /backup/2014-04-13_16-25-57
//如果執行正确,其最後輸出的幾行資訊通常如下:
xtrabackup: starting shutdown with innodb_fast_shutdown = 1
InnoDB: FTS optimize thread exiting.
InnoDB: Starting shutdown...
InnoDB: Shutdown completed; log sequence number 1739798
140413 16:29:48  innobackupex: completed OK!      

3.3、從一個完全備份中恢複資料

注意:恢複不用啟動MySQ

innobackupex指令的--copy-back選項用于執行恢複操作,其通過複制所有資料相關的檔案至mysql伺服器DATADIR目錄中來執行恢複過程。innobackupex通過backup-my.cnf來擷取DATADIR目錄的相關資訊。

# innobackupex --copy-back /backup/2014-04-13_16-25-57
                                                                                                                                                                                                                                                                                                                                       
//如果執行正确,其輸出資訊的最後幾行通常如下:
innobackupex: Starting to copy InnoDB log files
innobackupex: in '/backup/2014-04-13_16-25-57'
innobackupex: back to original InnoDB log directory '/mydata/data'
innobackupex: Copying '/backup/2014-04-13_16-25-57/ib_logfile0' to '/mydata/data/ib_logfile0'
innobackupex: Copying '/backup/2014-04-13_16-25-57/ib_logfile1' to '/mydata/data/ib_logfile1'
innobackupex: Finished copying back files.
140413 16:34:50  innobackupex: completed OK!      

請確定如上資訊的最行一行出現“innobackupex: completed OK!”。

當資料恢複至DATADIR目錄以後,還需要確定所有資料檔案的屬主和屬組均為正确的使用者,如mysql,否則,在啟動mysqld之前還需要事先修改資料檔案的屬主和屬組。如:

# chown -R  mysql:mysql  /mydata/data/      

4、使用innobackupex進行增量備份

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

4.1要實作增量備份,可以使用下面的指令進行:

# innobackupex --incremental /backup --incremental-basedir=BASEDIR

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

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

[root@station142 ~]# innobackupex --user=backup --password=123 /backup      //生成完全備份目錄/backup/2014-04-13_17-01-40/
[root@station142 ~]# innobackupex --incremental /backup --incremental-basedir=/backup/2014-04-13_17-01-40/   //生成第1個增量目錄/backup/2014-04-13_17-03-30/
[root@station142 ~]# innobackupex --incremental /backup --incremental-basedir=/backup/2014-04-13_17-03-30/  //生成第2個增量目錄/backup/2014-04-13_17-09-28      

4.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指的是第二次增量備份的目錄,其它依次類推,即如果有多次增量備份,每一次都要執行如上操作;

[root@station142 ~]# innobackupex --apply-log --redo-only /backup/2014-04-13_17-01-40/
[root@station142 ~]# innobackupex --apply-log --redo-only /backup/2014-04-13_17-01-40/ --incremental-dir=/backup/2014-04-13_17-03-30/
[root@station142 ~]# innobackupex --apply-log --redo-only /backup/2014-04-13_17-01-40/ --incremental-dir=/backup/2014-04-13_17-09-28/      

4.3備份恢複

[root@station142 data]# innobackupex --copy-back /backup/2014-04-13_17-01-40/
[root@station142 data]# chown -R mysql.mysql /mydata/data/*      

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

Xtrabackup對備份的資料檔案支援“流”功能,即可以将備份的資料通過STDOUT傳輸給tar程式進行歸檔,而不是預設的直接儲存至某備份目錄中。要使用此功能,僅需要使用--stream選項即可。如:

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

甚至也可以使用類似如下指令将資料備份至其它伺服器:

# innobackupex --stream=tar  /backup | ssh [email protected]  "cat -  > /backups/`date +%F_%H-%M-%S`.tar"      

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

# innobackupex --parallel  /path/to/backup      

同時,innobackupex備份的資料檔案也可以存儲至遠端主機,這可以使用--remote-host選項來實作:

# innobackupex [email protected]  /path/IN/REMOTE/HOST/to/backup      

6、導入或導出單張表

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

6.1先完全備份

[root@station142 ~]# innobackupex --user=backup --password=123 /backup      

6.2“導出”表

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

[root@station142 hellodb]# innobackupex --apply-log --export /backup/2014-04-13_18-02-45/      

此指令會為每個innodb表的表空間建立一個以.exp結尾的檔案,這些以.exp結尾的檔案則可以用于導入至其它伺服器。

MariaDB-之基于mysqldump 、lvm-snapshot、 xtrabackup的備份

6.3“導入”表

要在mysql伺服器上導入來自于其它伺服器的某innodb表,需要先在目前伺服器上建立一個跟原表表結構一緻的表,而後才能實作将表導入:

本實驗把hellodb.studnets表删掉

MariaDB [hellodb]> drop table students;      

建立students表

MariaDB [hellodb]>  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 |      

然後将此表的表空間删除

MariaDB [test]> alter table students discard tablespace;      

接下來,将來自于“導出”表的伺服器的studnets表的studnets.ibd和studnets.exp檔案複制到目前伺服器的資料目錄,然後使用如下指令将其“導入”:

[root@station142 test]# cp students.ibd students.exp /mydata/data/test/
[root@station142 test]# chown mysql.mysql students.exp students.ibd
[root@station142 test]#mysql
MariaDB [test]> alter table students import tablespace;      
MariaDB-之基于mysqldump 、lvm-snapshot、 xtrabackup的備份

恢複students表成功

四、備份政策

繼續閱讀