MySQL數據庫的三種備份恢復方式

   數據庫的備份與恢復也是系統運維工程師必備的技能之一,下面介紹幾種mysql數據庫備份工具及其實現。


   一、mysqldump備份恢復實例

   二、爲數據文件所在邏輯卷創建快照卷的方式進行備份恢復實例

   三、使用Xtrabackup進行增量備份和恢復實例


mysqldump

   可以把整個數據庫裝載到一個單獨的文本文件中。這個文件包含有所有重建您的數據庫所需要的SQL命令。這個命令取得所有的模式,並且將其轉換成DDL語法(CREATE語句,即數據庫定義語句),取得所有的數據,並且從這些數據中創建INSERT語句。這個工具將您的數據庫中所有的設計倒轉。因爲所有的東西都被包含到了一個文本文件中。這個文本文件可以用一個簡單的批處理和一個合適SQL語句導回到MySQL中。可以備份整個服務器、單個或部分數據庫,單個或部分表,以及表中的部分行;存儲過程、存儲函數、觸發器等,可以自動記錄備份時的二進制日誌文件以及相應的position;d於Innodb可以基於單事務模式進行熱備。


常用選項:

-A --all-databases 備份整個服務器

--add-drop-database 添加drop,防止報錯。

-C --compress,實現壓縮,用於網絡傳輸

-E --events 備份時間調度器;

-R --routines;備份存儲過程和存儲函數;

-d --no-data;只備份表結構,不備份數據;

-B   --databases ;指定單個或多個數據庫,以空格隔開;不指定默認備份整個數據庫服務器,不加此選項跟一個數據庫,則不會有創建此數據庫的語句,恢復時需自行創建;

備份之前先要請求讀鎖,可以使用選項:

-x, --lock-all-tables

如果只備份單張表,可以使用:

-l, --lock-tables

能夠記錄在備份時,記錄二進制日誌文件所處的位置;

--master-data=2

-- CHANGE MASTER TOMASTER_LOG_FILE='mysql-bin.000004', MASTER_LOG_POS=1755;

mysql中請求數據庫的讀鎖;

mysql>  FLUSH TABLES WITH READ LOCK;

備份完成後,撤銷讀鎖:

mysql> UNLOCKTABLES;

對於InnoDB數據庫文件,還要注意觀察將buffer pool中的數據完全同步到數據庫中;(建議使用--single-transaction選項);

mysql> SHOW ENGINE InnoDB STATUS\G

在生產環境中注意觀察bufferpoolFILE I/O是否還有數據;

----------------------

BUFFER POOL AND MEMORY

----------------------

Total memory allocated137363456; in additional pool allocated 0

Dictionary memoryallocated 62417

Buffer pool size   8191

Free buffers       7990

Database pages     200

Old database pages 0

Modified db pages  0

Pending reads 0

Pending writes: LRU 0,flush list 0, single page 0

Pages made young 0, notyoung 0

0.00 youngs/s, 0.00non-youngs/s

Pages read 154, created46, written 276

0.00 reads/s, 0.00creates/s, 0.00 writes/s

No buffer pool pagegets since the last printout

Pages read ahead0.00/s, evicted without access 0.00/s, Random read ahead 0.00/s

LRU len: 200, unzip_LRUlen: 0

I/O sum[0]:cur[0],unzip sum[0]:cur[0]

--------

FILE I/O

--------

I/O thread 0 state:waiting for i/o request (insert buffer thread)

I/O thread 1 state:waiting for i/o request (log thread)

I/O thread 2 state:waiting for i/o request (read thread)

I/O thread 3 state:waiting for i/o request (read thread)

I/O thread 4 state:waiting for i/o request (read thread)

I/O thread 5 state:waiting for i/o request (read thread)

I/O thread 6 state:waiting for i/o request (write thread)

I/O thread 7 state:waiting for i/o request (write thread)

I/O thread 8 state:waiting for i/o request (write thread)

I/O thread 9 state:waiting for i/o request (write thread)

Pending normal aioreads: 0 [0, 0, 0, 0] , aio writes: 0 [0, 0, 0, 0] ,

ibuf aio reads: 0, log i/o's: 0, sync i/o's: 0

Pending flushes (fsync)log: 0; buffer pool: 0

296 OS file reads, 395OS file writes, 258 OS fsyncs

0.00 reads/s, 0 avgbytes/read, 0.00 writes/s, 0.00 fsyncs/s


--single-transaction

創建一個單一的應用於整個數據庫的事務,爲每一個Innodb的表創建一個快照,基於此快照來進行熱備份,不需要同時使用--lock-all-tables


開始備份:

# mysqldump -uroot -B db1 db2 -x > /backup/db1_db2_full-`date +%F`.sql


採用完全備份+增量備份的方式進行:


1、完全備份:

[root@localhost~]#  mysqldump -uroot -p--single-transaction --events --master-data=2 --all-databases >/backup/alldb_full-`date +%F`.sql

[root@localhost ~]# ls/backup/

alldb_full-2013-09-07.sql


2、添加一些數據進行增量備份:

mysql> createdatabase db3;

ERROR 1223 (HY000):Can't execute the query because you have a conflicting read lock

mysql> unlocktables;

Query OK, 0 rowsaffected (0.00 sec)


mysql> create tablet1 (id int);

mysql> insert intot1 values (1),(2),(3);


查看二進制日誌中記錄的位置:

mysql> show masterstatus;

+------------------+----------+--------------+------------------+

| File             | Position | Binlog_Do_DB |Binlog_Ignore_DB |

+------------------+----------+--------------+------------------+

| mysql-bin.000004|     1993 |              |                  |

+------------------+----------+--------------+------------------+


在alldb_full-2013-09-07.sql找到上次二進制日誌的最後的位置

-- CHANGE MASTER TOMASTER_LOG_FILE='mysql-bin.000004',MASTER_LOG_POS=1826;

[root@localhost ~]# mysqlbinlog--start-position=1826 --stop-position=1993 /mydata/data/mysql-bin.000004 >alldb_incre_`date +%F`.sql


在增加一些記錄:

mysql> create tabletb2 (identifier int);

Query OK, 0 rowsaffected (0.34 sec)


mysql> insert intotb2 values (1),(3),(5);

Query OK, 3 rowsaffected (0.00 sec)

Records: 3  Duplicates: 0 Warnings: 0

模擬數據庫出現故障,db3不小心被刪除

mysql> drop databasedb3;

Query OK, 2 rowsaffected (0.31 sec)

此時,該如何恢復:

1、恢復完全備份

2、恢復增量備份

3、將二進制日誌導出並恢復;

首先將二進制日誌導出

#找到刪除db3之前的位置:

[root@localhost ~]#mysqlbinlog /mydata/data/mysql-bin.000004

#130907 21:45:27 serverid 1  end_log_pos 2467  Xid = 3930

COMMIT/*!*/;  

# at 2467

#130907 21:45:27 serverid 1  end_log_pos 2546  Query  thread_id=8     exec_time=1     error_code=0

SETTIMESTAMP=1378561527/*!*/;

drop database db3

/*!*/;

DELIMITER ;

# End of log file

# 把從上次增量備份之後到db3刪除之前的二進制日誌導出到文件中;

[root@localhost ~]#mysqlbinlog --start-position=1993 --stop-position=2467 /mydata/data/mysql-bin.000004 > /tmp/recovery.sql

# 設置sql_log_bin=0,不記錄恢復的二進制日誌,滾動一下日誌;

mysql> SET sql_log_bin=0;

mysql> FLUSH LOGS;


# 導入備份文件,完全備份---> 增量備份---->最近的二進制日誌:

[root@localhost ~]#mysql -uroot -p < /backup/alldb_full-2013-09-07.sql

Enter password:

[root@localhost ~]#mysql -uroot -p < /backup/alldb_incre_2013-09-07.sql

Enter password:

[root@localhost ~]#mysql -uroot -p < /tmp/recovery.sql

Enter password:


最後SHOWDATABASES;查看恢復情況


恢復完成後,滾動一下日誌,並開啓二進制日誌

# FLUSHLOGS;

# mysql> SET sql_log_bin=1;


二、LVM快照卷備份:

1、準備工作,創建LVM用以存儲數據庫數據,編譯安裝時指定datadir/mydata/data

[root@localhost ~]#pvcreate /dev/sda3

 Physical volume "/dev/sda3"successfully created

[root@localhost ~]#pvcreate /dev/sda5

 Physical volume "/dev/sda5"successfully created

[root@localhost ~]#vgcreate myvg /dev/sda{3,5}

 Volume group "myvg" successfullycreated

[root@localhost ~]#lvcreate -L 10G -n mylv -p rw myvg

 Logical volume "mylv" created

[root@localhost ~]# lvs

 LV  VG   Attr      LSize Pool Origin Data%  Move LogCpy%Sync Convert

 mylv myvg -wi-a---- 10.00g                                            

 root vg0 -wi-ao--- 20.00g                                            

 swap vg0 -wi-ao---  2.00g                                            

 usr vg0  -wi-ao--- 10.00g                                            

 var vg0  -wi-ao--- 20.00g                                            

[root@localhost ~]#mke2fs -t ext4 -L MYDATA /dev/myvg/mylv

mke2fs 1.41.12(17-May-2010)

Filesystem label=MYDATA

OS type: Linux

Block size=4096 (log=2)

Fragment size=4096(log=2)

Stride=0 blocks, Stripewidth=0 blocks

655360 inodes, 2621440blocks

131072 blocks (5.00%)reserved for the super user

First data block=0

Maximum filesystemblocks=2684354560

80 block groups

32768 blocks per group,32768 fragments per group

8192 inodes per group

Superblock backupsstored on blocks:

       32768, 98304, 163840, 229376, 294912,819200, 884736, 1605632


Writing inode tables:done                            

Creating journal (32768blocks): done

Writing superblocks andfilesystem accounting information: done


This filesystem will beautomatically checked every 22 mounts or

180 days, whichevercomes first.  Use tune2fs -c or -i tooverride.

[root@localhost ~]#mkdir /mydata/data -pv

mkdir: createddirectory `/mydata'

mkdir: createddirectory `/mydata/data'

[root@localhost ~]#mount /dev/myvg/mylv /mydata/data/

[root@localhost ~]# ls/mydata/data/

lost+found


使用Innodb引擎時,建議將每個數據庫的文件單獨存在,不要將所有數據存在一個表空間內,可以調整參數

innodb_file_per_table=1,將此參數保存在/etc/my.cnf裏面的[mysqld]下面;


使用LVM snapshot備份的前提:事務日誌必須跟數據文件在同一個LV上;


開始備份:


請求讀鎖,並滾動日誌;

mysql> FLUSH TABLESWITH READ LOCK;
mysql> FLUSH LOGS;


記錄當前狀態

mysql> SHOW MASTERSTATUS;

+------------------+----------+--------------+------------------+

| File             | Position | Binlog_Do_DB |Binlog_Ignore_DB |

+------------------+----------+--------------+------------------+

| mysql-bin.000006|      107 |              |                  |

+------------------+----------+--------------+------------------+

1 row in set (0.00 sec)


爲數據所在的卷創建快照:
[root@localhost data]#lvcreate -L 200M -n mysql-snap -s -p r /dev/myvg/mylv


掛載快照卷,並將快照捲上的數據拷出;

[root@localhost data]#mount /dev/myvg/mysql-snap /mnt

mount: block device/dev/mapper/myvg-mysql--snap is write-protected, mounting read-only

[root@localhost data]#mkdir /backup

[root@localhost ~]# cp-Rp /mnt/* /backup/


拷貝完成之後,卸載並刪除快照卷

[root@localhost ~]#umount /mnt

[root@localhost ~]#lvremove /dev/myvg/my


解除讀鎖

mysql> UNLOCK TABLES;


數據庫又進行了一些操作,此時進行增量備份;

[root@localhost ~]#mysqlbinlog --start-position=107 /mydata/data/mysql-bin.000006 > /tmp/mysql\ >-snap.incremental1.sql;


過了一段時間後,模擬數據庫出現故障:

[root@localhost ~]#service mysqld stop

Shutting downMySQL....[  OK  ]

[root@localhost ~]# rm-rf /mydata/*

[root@localhost ~]# cp-pR /backup/* /mydata/

[root@localhost ~]#service mysqld start

Starting MySQL[  OK  ]

查看數據庫中的數據,只是完全備份後的狀態,此時再將二進制文件導入,即可恢復上次增量備份時的數據,如果像剛纔一樣把數據庫的所有內容,包括二進制日誌都刪除,那麼也只能恢復到上次增量備份時;所以二進制日誌對數據恢復非常重要,一定要妥善管理;

# mysql -uroot -p < /tmp/mysql-snap.incremental1.sql

數據恢復完成。



Xtrabackup 簡介


Xtrabackup是由percona提供的mysql數據庫備份工具,據官方介紹,這也是世界上惟一一款開源的能夠對innodb和xtradb數據庫進行熱備的工具。特點:
(1)備份過程快速、可靠;
(2)備份過程不會打斷正在執行的事務;
(3)能夠基於壓縮等功能節約磁盤空間和流量;
(4)自動實現備份檢驗;
(5)還原速度快;

獲取軟件:http://www.percona.com/software/percona-xtrabackup/

Xtrabackup備份基於LSN (日誌序列號),在備份時,既包含事務日誌,有包含數據文件,由於是熱備,有的事務還沒有提交,數據還沒有完全同步到磁盤上,xtrabackup恢復數據之前會做預處理,把事務日誌中已提交的事務同步至數據文件,未提交事務要rollback,但是在恢復時,先不要回滾。


軟件安裝

# yum localinstall percona-xtrabackup-2.1.4-656.rhel6.x86_64.rpm


開始備份

1、完全備份:

# mkdir/backup/fullbackup -pv

# innobackupex --no-timestamp /backup/fullback-`date +%F`

   --no-timestamp表示不使用自動生成的以日期爲目錄名的目錄

最後出現complete OK!表示成功;

innobackupex: Backupcreated in directory '/backup/fullback-2013-09-09'

innobackupex: MySQLbinlog position: filename 'mysql-bin.000001', position 107

130909 01:51:36  innobackupex: Connection to database serverclosed

130909 01:51:36  innobackupex: completed OK!


2、恢復數據前的準備:

“準備”的主要作用正是通過回滾未提交的事務及同步已經提交的事務至數據文件也使得數據文件處於一致性狀態。

# innobackupex--apply-log  /backup/fullback-2013-09-09/

130909 01:34:55  innobackupex: completed OK!

3、從一個完全備份中恢復:

首先模擬數據庫損壞

# servicemysqld stop

# rm -rf/mydata/data/*

# innobackupex--copy-back  /backup/fullback-2013-09-09/

130909 01:54:28  innobackupex: completed OK!

恢復完成後啓動數據庫,注意:修改此時數據目錄的權限:

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

# service mysqld start

完全備份並恢復完成!


Xtrabackup在進行增量備份和恢復時,其思路不同於其他備份工具

在每一次完全備份恢復之後,立即再做一次完全備份;

# innobackupex--no-timestamp /backup/fullback-`date +%F`

修改數據庫內容後,進行增量備份,使用--incremental選項,同時增量備份針對的對象要指明;

# innobackupex --incremental --no-timestamp /backup/first.incremental-`date +%F`--incremental-basedir=/backup/fullback-2013-09-09/

innobackupex: Backupcreated in directory '/backup/first.incremental-2013-09-09'

innobackupex: MySQLbinlog position: filename 'mysql-bin.000001', position 391

130909 02:08:02  innobackupex: Connection to database serverclosed

130909 02:08:02  innobackupex: completed OK!


第二次增量備份:

# innobackupex--incremental --no-timestamp /backup/second.incremental-`date +%F`--incremental-basedir=/backup/first.incremental-2013-09-09/

innobackupex: Backupcreated in directory '/backup/second.incremental-2013-09-09'

innobackupex: MySQLbinlog position: filename 'mysql-bin.000001', position 848

130909 02:13:06  innobackupex: Connection to database serverclosed

130909 02:13:06  innobackupex: completed OK!


隨後又進行了一些操作後,數據庫發生故障,那麼下一步開始恢復數據庫


1、準備完全備份:

# innobackupex--apply-log --redo-only /backup/fullback-2013-09-09/

xtrabackup: startingshutdown with innodb_fast_shutdown = 1

130909  2:19:57 InnoDB: Starting shutdown...

130909  2:19:57 InnoDB: Shutdown completed; log sequence number 1621004

130909 02:19:57  innobackupex: completed OK!


2、準備第一個增量備份:

# innobackupex--apply-log --redo-only /backup/fullback-2013-09-09/--incremental-dir=/backup/first.incremental-2013-09-09/

innobackupex: Copying'/backup/first.incremental-2013-09-09/performance_schema/events_waits_summary_global_by_event_name.frm'to'/backup/fullback-2013-09-09/performance_schema/events_waits_summary_global_by_event_name.frm'

130909 02:22:25  innobackupex: completed OK!


3、準備第二個增量備份:

# innobackupex--apply-log --redo-only /backup/fullback-2013-09-09/--incremental-dir=/backup/second.incremental-2013-09-09/

innobackupex: Copying'/backup/second.incremental-2013-09-09/performance_schema/events_waits_summary_global_by_event_name.frm'to'/backup/fullback-2013-09-09/performance_schema/events_waits_summary_global_by_event_name.frm'

130909 02:23:33  innobackupex: completed OK!


4、恢復完全備份,此時的完全備份文件已經將後面的兩次增量進行了“prepared”,所以只恢復完全備份即可

# innobackupex--copy-back /backup/fullback-2013-09-09/

innobackupex: Startingto copy InnoDB log files

innobackupex: in'/backup/fullback-2013-09-09'

innobackupex: back tooriginal InnoDB log directory '/mydata/data'

innobackupex: Finishedcopying back files.


130909 02:27:30  innobackupex: completed OK!


5、數據文件權限:

# chown-R mysql.mysql /mydata/data/*


6、最後利用二進制日誌恢復最後的內容:

找到備份文件中最後的二進制日誌位置

# cat/backup/fullback-2013-09-09/xtrabackup_binlog_info

mysql-bin.000001        848

# mysqlbinlog--start-position=848 /backup/mysql-bin.000001 > last.sql


先把二進制日誌關掉,然後再把日誌導入,隨後再開啓日誌;

# SET SESSION SQL_LOG_BIN=0;

# mysql < last.sql

# SET SESSION SQL_LOG_BIN=1;

增量備份恢復最終完成,



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章