數據意味着企業的命脈,如果,數據丟失,就表示企業就要面臨巨大的經濟損失,甚至是更加嚴重的後果,所以,作爲運維人員,對於數據庫的備份與恢復是一種非常重要的任務,下面,我將介紹三種備份方式,分別爲:mysqldump備份(mysql自帶的),邏輯卷備份,xtrabackup備份(專用於InnoDB存儲引擎)。
首先,先介紹mysqldump這個備份工具,實現的主要是物理備份,之後,還需要根據二進制日誌的事件進行增量備份,這主要是針對InnoDB存儲引擎的,MyISAM存儲引擎,只需要將數據庫目錄下的數據拷貝到另一個主機即可;這種備份方式實現的是:完全備份+增量備份。
備份的策略:最好一週進行一次完全備份,每天進行一次增量備份
mysqldump的備份及數據恢復實驗:
我們先單獨創建一個目錄,作爲存放二進制日誌文件的位置,最後是另一個磁盤上
進行備份:此時,MySQL應該爲啓動狀態
[root@localhost ~]# mysqldump -B hellodb -lock-all-tables -master-data=2 -flush-logs -u root -h localhost -p > /myback/hellodb-`date +%F-%T`.sql #-h,這裏指localhost,但是,實際應該是MySQL服務器的地址,客戶端爲另一個地址 Enter password:
上面的認證信息可以寫到當前用戶的家目錄下
備份的數據庫文件中,有如下語句
– CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000005', MASTER_LOG_POS=245; #增量備份從這裏開始
登錄到數據庫上,在hellodb的數據庫中創建一個表
MariaDB [hellodb]> create table test(id int);
插入數據
MariaDB [hellodb]> insert into test values (1),(11);
在增量備份前,滾動一下日誌文件
MariaDB [(none)]> flush logs;
生成環境中,可能會自動滾動多個文件,備份時,要備份多個文件
進行增量備份:
根據時間進行增量備份,起始時間位增量備份的時間
[root@localhost ~]# mysqlbinlog –start-datetime '2014-09-22 18:20:43' –stop-datetime '2014-09-22 18:23:23' /MySQL/binlogs/mysql-bin.* > /myback/icrm-`date +%F-%T`.sql
此時,再次登錄數據庫,進行一些操作
MariaDB [(none)]> USE hellodb MariaDB [hellodb]> insert into test values (100),(200);
由於可能的誤操作,hellodb數據庫被刪除了
MariaDB [hellodb]> DROP DATABASE hellodb;
此時,我們就要保護好我們的二進制日誌文件了,我們將數字最大的二進制日誌導出到臨時文件,查找到DROP DATABASE這一欄目,記下其執行的編號
[root@localhost ~]# mysqlbinlog /MySQL/binlogs/mysql-bin.000006 > /myback/bny.sql [root@localhost ~]# vim /myback/bny.sql # at 444 #事件的序號爲444 #140922 18:26:48 server id 1 end_log_pos 531 Query thread_id=7 exec_time=0 error_code=0 SET TIMESTAMP=1411381608/*!*/; drop database hellodb /*!*/; DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; /*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
重新生成二進制日誌的文件
[root@localhost ~]# mysqlbinlog –stop-position 444 /MySQL/binlogs/mysql-bin.000006 > /myback/bny.sql
可將原來生成的進行覆蓋
連接到MariaDB上,將二進制日誌記錄的功能暫時關閉
MariaDB [(none)]> set session sql_log_bin=0;
還原數據庫,依次導入,這裏可以在另一個終端上導入
導入第一次完全備份的數據
[root@localhost ~]# mysql < /myback/hellodb-2014-09-18-00\:15\:22.sql
此時,後面的數據都沒有,test表都不存在
導入第一次增量備份
[root@localhost myback]# mysql < icrm-2014-09-22-18\:24\:39.sql
導入二進制日誌的操作部分
[root@localhost myback]# mysql < bny.sql
邏輯備份對於數據集非常大的時候,效率非常的差,可以執行物理備份,直接拷貝數據
使用rsync,鎖定mysql,將數據拉到遠程的客戶端主機上
下面要介紹的是基於LVM邏輯卷的一種物理備份,前提是,我們的MariaDB服務的數據庫目錄是基於LVM的邏輯卷掛載的目錄,我們在做邏輯卷的時候,要預留一部分空間,要進行物理備份的時候,將所有的表施加讀鎖,不讓用戶進行寫操作,同時,馬上創建快照,進行掛載,及時的釋放讀鎖,這樣,物理備份就完成了,如果,數據還在不斷的寫入,其餘的要藉助於我們的二進制日誌進行恢復數據了。
我們先在mysql中導入hellodb這個數據庫
[root@localhost ~]# mysql < hellodb.sql
再使用mysqldump工具進行完全備份
[root@localhost ~]# mysqldump -A –lock-all-tables > backup.sql
停止我們的mysql服務
[root@localhost ~]# service mysqld stop
首先,我們創建一個分區,並將其作爲邏輯卷
[root@localhost ~]# fdisk /dev/sda #創建10G分區 [root@localhost ~]# kpartx -af /dev/sda [root@localhost ~]# partx -a /dev/sda [root@localhost ~]# pvcreate /dev/sda3 [root@localhost ~]# vgcreate myvg /dev/sda3 [root@localhost ~]# lvcreate -L 6G -n mydata myvg [root@localhost ~]# mke2fs -t ext4 /dev/myvg/mydata [root@localhost ~]# mount /dev/myvg/mydata /MySQL/data/ [root@localhost ~]# chown -R mysql:mysql /MySQL/data/
重新初始化
[root@localhost mysql]# cd /usr/local/mysql/ [root@localhost mysql]# ./scripts/mysql_install_db –user=mysql –datadir=/MySQL/data/
啓動MySQL服務
[root@localhost mysql]# service mysqld start
恢復前面備份的數據
[root@localhost ~]# mysql < backup.sql
上面的操作是爲了建立將數據庫目錄建立在邏輯捲上的數據庫
下面就基於邏輯卷做物理備份
將所有的表鎖定
MariaDB [(none)]> flush tables with read lock; #會話不能退出
查看一下我們當前的數據所處的二進制日誌位置,也可以滾動下日誌
如果在腳本中查看,使用:mysql -e 'show master status' > /backup/binary-log
另起一個終端,創建快照卷
[root@localhost data]# lvcreate -L 1G -n mydata_snap -s -p r /dev/myvg/mydata
此時,立刻釋放前一個會話中的鎖
MariaDB [(none)]> unlock tables;
將快照捲進行掛載
[root@localhost ~]# mkdir /snap [root@localhost ~]# mount /dev/myvg/mydata_snap /snap/
此時,在/snap目錄下就是備份的數據
將快照卷備份的數據移到另一塊磁盤中去
[root@localhost ~]# cp -a /snap/ /backup/bk-`date +%F-%T`
就在此刻,有個用戶登錄到數據庫上,操作了一下命令
MariaDB [(none)]> use hellodb MariaDB [hellodb]> drop table toc;
toc表被刪除了,在mysql的數據庫目錄中也沒有這個表的數據了
但是,快照捲上還是有toc這個表的數據的
我們該如何將toc這個表恢復回來呢?
[root@localhost ~]# mysqlbinlog /MySQL/data/mysql-bin.000003 #查看刪除toc表的序號 [root@localhost ~]# mysqlbinlog –stop-position=245 /MySQL/data/mysql-bin.000003 > /backup/bk.sql
然後,我們實行全庫恢復
[root@localhost ~]# service mysqld stop [root@localhost ~]# rm -rf /MySQL/data/* #刪除現在的數據 [root@localhost ~]# cp -a /backup/bk-2014-09-21-20:39:55/* /MySQL/data/ #將備份的數據複製過去
啓動mysql,將二進制日誌時間導入
[root@localhost ~]# service mysqld start [root@localhost ~]# mysql < /backup/bk.sql
登錄數據庫,驗證
下面是最後一種備份,,使用xtrabackup備份工具備份數據,這是一種對於InnoDB存儲引擎來說是較優的熱備工具,是由percona研發,同時,這種備份工具還支持增量備份
安裝xtrabackup
[root@localhost src]# yum install percona-xtrabackup-2.2.3-4982.el6.x86_64.rpm
這樣安裝會自動解決依賴關係
查看我們的xtrabackup軟件生成了哪些文件
[root@localhost src]# rpm -ql percona-xtrabackup /usr/bin/innobackupex /usr/bin/xbcrypt /usr/bin/xbstream /usr/bin/xtrabackup /usr/share/doc/percona-xtrabackup-2.2.3 /usr/share/doc/percona-xtrabackup-2.2.3/COPYING
innobackupex:客戶端工具,要以mysql協議連入mysqld,不支持離線備份
實現完整備份:
innobackupex –user=DBUSER –password=DBUSERPASS /path/to/BACKUP-DIR –user=DBUSR –password=DBUSREPASS
備份時,最小使用一個全新最小的用戶備份,下面我們就創建這麼個用戶
MariaDB [(none)]> create user 'bkuser'@'localhost' identified by 'bk@123'; #創建用戶 MariaDB [(none)]> grant reload,lock tables,replication client on *.* to 'bkuser'@'localhost'; #賦予指定權限 MariaDB [(none)]> flush privileges;
進行備份:
[root@localhost ~]# innobackupex –user=bkuser –password=bk@123 /backup
然後,備份到一半時,就開始報錯了
InnoDB: Error: log file ./ib_logfile0 is of different size 5242880 bytes
InnoDB: than specified in the .cnf file 50331648 bytes!
innobackupex: Error: The xtrabackup child process has died at /usr/bin/innobackupex line 2672.
解決方法,修改mysql的配置文件:innodb_log_file_size=5M #大小改爲5M
然後,備份就ok了,只要出現下面的提示就可以了
140921 22:53:05 innobackupex: Connection to database server closed
140921 22:53:05 innobackupex: completed OK!
在/backup目錄下,會創建一個以日期命令的目錄
備份的配置文件是不完整的,MySQL的配置文件還是要手動備份
備份的同時,在備份目錄中創建如下文件
xtrabackup_checkpoints –> 備份類型、備份狀態、LSN(日誌序列號)範圍
LSN是增量備份的一個重要憑據
xtrabackup_binlog_info –>MySQL服務器當前正在使用的二進制日誌及北方這一刻二進制日誌事件的位置
[root@localhost 2014-09-22_09-56-04]# cat xtrabackup_binlog_info mysql-bin.000005 7925 #備份時,二進制日誌事件的位置 backup-my.cnf #備份命令用到的配置選項信息
準備數據:通過回滾爲提交的事務及同步已經提交的事務至數據文件也使得數據文件處於一致性狀態
innobackupex –apply-log
此時,關閉數據庫,刪除數據庫中的所有數據,注意,我們的二進制日誌是另外存放的
通過innobackup還原數據
[root@localhost ~]# innobackupex –copy-back /backup/2014-09-22_09-56-04/
通過–copy-back選項,注意,還原時,MySQL可以不啓動
查看MySQL的數據庫目錄
此時,數據都被還原了,我們的二進制默認存在其他位置
重要的一步,恢復的數據的屬主和屬組是root用戶,mysql是無法讀取的,要改變屬主信息
[root@localhost data]# chown -R mysql:mysql ./*
啓動mysql服務,登錄上去,查看我們的數據是否還在
數據都被恢復了,此時,我們應該做一次完全備份
[root@localhost ~]# innobackupex –user=root –password='' /backup/
完全備份後的xtrabackup_checkpoints中的信息如下
然後,我們連接到我們的數據庫
創建一個test的新表,並插入部分數據
MariaDB [hellodb]> create table test(id int,name varchar(20)); MariaDB [hellodb]> insert into test values(1,'luffy'),(2,'wsy'),(3,'c-shang');
然後,刪除students這個數據庫
MariaDB [hellodb]> drop table students;
對我們的數據庫,進行增量備份
[root@localhost ~]# innobackupex –incremental /backup/ –incremental-basedir=/backup/2014-09-22_10-33-00/
這個增量是針對我們恢復數據後的完全備份而進行的
會在/backup目錄下生成一個新的目錄,查看新的lsn序列號
查看新的增量備份的目錄下的xtrabackup_checkpoints文件的lsn
假設,此時,我們的用戶還在使用數據庫,插入了數據,但是,數據庫在這時崩潰了,數據全部丟失,我們如何恢復
連接數據庫,在test表中插入新的數據
MariaDB [hellodb]> insert into test values (4,'abc'),(5,'xyz');
模擬數據庫服務器崩潰,二進制日誌是另外存放的,如果不是的,注意保持二進制日誌
[root@localhost ~]# service mysqld stop [root@localhost data]# rm -rf /MySQL/data/*
此時,我們就要查看最後一次增量備份時,二進制日誌事件的位置
[root@localhost 2014-09-22_10-37-50]# cat xtrabackup_binlog_info mysql-bin.000001 9182
我們要利用我們的二進制日誌文件,導出9182事件之後的數據庫操作了
[root@localhost ~]# mysqlbinlog –start-position=9182 /binlogs/mysql-bin.000001 > /backup/bk-`date +%F-%T`.sql
還原我們的所有的數據庫
準備過程,只能提交
[root@localhost ~]# innobackupex –apply-log –redo-only /backup/2014-09-22_10-33-00/
合併第一個增量
[root@localhost ~]# innobackupex –apply-log –redo-only /backup/2014-09-22_10-33-00/ –incremental-dir=/backup/2014-09-22_10-37-50/
最後一個增量恢復,可以不用加–redo-only了
將恢復的數據拷貝回去
[root@localhost ~]# innobackupex –copy-back /backup/2014-09-22_10-33-00/ #完全備份的目錄 [root@localhost ~]# cd /MySQL/data/ [root@localhost data]# chown -R mysql:mysql ./*
啓動mysql服務
MariaDB [(none)]> SET SESSION sql_log_bin=0; #關閉二進制日誌記錄 MariaDB [hellodb]> SOURCE /back/bk-2014-09-22-10:50:42.sql; #可以在另一個終端中導入 [root@localhost ~]# mysql < /backup/bk-2014-09-22-10:50:42.sql MariaDB [hellodb]> SET SESSION sql_log_bin=1;
此時,查看我們的數據庫
至此,我們關於MariaDB的三種備份方式及其恢復方法都已經介紹了,寫下此篇博文,其實,也是爲了強調數據的一個重要性,對於數據的備份與恢復要做到非常熟練。