學會用各種姿勢備份MySQL數據庫

學會用各種姿勢備份MySQL數據庫

原文地址:http://www.cnblogs.com/liangshaoye/p/5464794.html

前言

我們試着想一想, 在生產環境中什麼最重要?如果我們服務器的硬件壞了可以維修或者換新, 軟件問題可以修復或重新安裝, 但是如果數據沒了呢?這可能是最恐怖的事情了吧, 我感覺在生產環境中應該沒有什麼比數據跟更爲重要. 那麼我們該如何保證數據不丟失、或者丟失後可以快速恢復呢?只要看完這篇, 大家應該就能對MySQL中實現數據備份和恢復能有一定的瞭解。

爲什麼需要備份數據?

其實在前言中也大概說明了爲什麼要備份數據, 但是我們還是應該具體瞭解一下爲什麼要備份數據

在生產環境中我們數據庫可能會遭遇各種各樣的不測從而導致數據丟失, 大概分爲以下幾種.

  • 硬件故障

  • 軟件故障

  • 自然災害

  • 黑客攻擊

  • 誤操作 (佔比最大)

所以, 爲了在數據丟失之後能夠恢復數據, 我們就需要定期的備份數據, 備份數據的策略要根據不同的應用場景進行定製, 大致有幾個參考數值, 我們可以根據這些數值從而定製符合特定環境中的數據備份策略

  • 能夠容忍丟失多少數據

  • 恢復數據需要多長時間

  • 需要恢復哪一些數據

數據的備份類型

數據的備份類型根據其自身的特性主要分爲以下幾組

  • 完全備份

  • 部分備份

    完全備份指的是備份整個數據集( 即整個數據庫 )、部分備份指的是備份部分數據集(例如: 只備份一個表)

而部分備份又分爲以下兩種

  • 增量備份

  • 差異備份

    增量備份指的是備份自上一次備份以來(增量或完全)以來變化的數據; 特點: 節約空間、還原麻煩 
    差異備份指的是備份自上一次完全備份以來變化的數據 特點: 浪費空間、還原比增量備份簡單

示意圖

MySQL備份數據的方式

MySQl中我們備份數據一般有幾種方式

  • 熱備份

  • 溫備份

  • 冷備份

    熱備份指的是當數據庫進行備份時, 數據庫的讀寫操作均不是受影響 
    溫備份指的是當數據庫進行備份時, 數據庫的讀操作可以執行, 但是不能執行寫操作 
    冷備份指的是當數據庫進行備份時, 數據庫不能進行讀寫操作, 即數據庫要下線

MySQL中進行不同方式的備份還要考慮存儲引擎是否支持

  • MyISAM

    熱備 ×

    溫備 √

    冷備 √

  • InnoDB

    熱備 √

    溫備 √

    冷備 √

    我們在考慮完數據在備份時, 數據庫的運行狀態之後還需要考慮對於MySQL數據庫中數據的備份方式

    物理備份一般就是通過tar,cp等命令直接打包複製數據庫的數據文件達到備份的效果 
    邏輯備份一般就是通過特定工具從數據庫中導出數據並另存備份(邏輯備份會丟失數據精度)

    • 物理備份

    • 邏輯備份

備份需要考慮的問題

定製備份策略前, 我們還需要考慮一些問題

我們要備份什麼?

一般情況下, 我們需要備份的數據分爲以下幾種

  • 數據

  • 二進制日誌, InnoDB事務日誌

  • 代碼(存儲過程、存儲函數、觸發器、事件調度器)

  • 服務器配置文件

備份工具

這裏我們列舉出常用的幾種備份工具 
mysqldump : 邏輯備份工具, 適用於所有的存儲引擎, 支持溫備、完全備份、部分備份、對於InnoDB存儲引擎支持熱備 
cp, tar 等歸檔複製工具: 物理備份工具, 適用於所有的存儲引擎, 冷備、完全備份、部分備份 
lvm2 snapshot: 幾乎熱備, 藉助文件系統管理工具進行備份 
mysqlhotcopy: 名不副實的的一個工具, 幾乎冷備, 僅支持MyISAM存儲引擎 
xtrabackup: 一款非常強大的InnoDB/XtraDB熱備工具, 支持完全備份、增量備份, 由percona提供

設計合適的備份策略

針對不同的場景下, 我們應該制定不同的備份策略對數據庫進行備份, 一般情況下, 備份策略一般爲以下三種

  • 直接cp,tar複製數據庫文件

  • mysqldump+複製BIN LOGS

  • lvm2快照+複製BIN LOGS

  • xtrabackup

以上的幾種解決方案分別針對於不同的場景

  1. 如果數據量較小, 可以使用第一種方式, 直接複製數據庫文件

  2. 如果數據量還行, 可以使用第二種方式, 先使用mysqldump對數據庫進行完全備份, 然後定期備份BINARY LOG達到增量備份的效果

  3. 如果數據量一般, 而又不過分影響業務運行, 可以使用第三種方式, 使用lvm2的快照對數據文件進行備份, 而後定期備份BINARY LOG達到增量備份的效果

  4. 如果數據量很大, 而又不過分影響業務運行, 可以使用第四種方式, 使用xtrabackup進行完全備份後, 定期使用xtrabackup進行增量備份或差異備份

實戰演練

使用cp進行備份

我們這裏使用的是使用yum安裝的mysql-5.1的版本, 使用的數據集爲從網絡上找到的一個員工數據庫

查看數據庫的信息

向數據庫施加讀鎖

1
mysql> FLUSH TABLES WITH READ LOCK;    #向所有表施加讀鎖
2
Query OK, 0 rows affected (0.00 sec)
3

備份數據文件

模擬數據丟失並恢復

1
[root@node1 ~]# rm -rf /var/lib/mysql/*    #刪除數據庫的所有文件
2
[root@node1 ~]# service mysqld restart   #重啓MySQL, 如果是編譯安裝的應該不能啓動, 如果rpm安裝則會重新初始化數據庫
3
4
5
mysql> SHOW DATABASES;    #因爲我們是rpm安裝的, 連接到MySQL進行查看, 發現數據丟失了!
6
+--------------------+
7
| Database           |
8
+--------------------+
9
| information_schema |
10
| mysql              |
11
| test               |
12
+--------------------+
13
3 rows in set (0.00 sec)
14
15
[root@node1 ~]# rm -rf /var/lib/mysql/*    #這一步可以不做
16
[root@node1 ~]# cp -a /backup/* /var/lib/mysql/    #將備份的數據文件拷貝回去
17
[root@node1 ~]# service mysqld restart  #重啓MySQL
18
19
20
#重新連接數據並查看
21
22
mysql> SHOW DATABASES;    #數據庫已恢復
23
+--------------------+
24
| Database           |
25
+--------------------+
26
| information_schema |
27
| employees          |
28
| mysql              |
29
| test               |
30
+--------------------+
31
4 rows in set (0.00 sec)
32
33
mysql> USE employees;      
34
35
mysql> SELECT COUNT(*) FROM employees;    #表的行數沒有變化
36
+----------+
37
| COUNT(*) |
38
+----------+
39
|   300024 |
40
+----------+
41
1 row in set (0.06 sec)
42
43
44
##完成
45

使用mysqldump+複製BINARY LOG備份

我們這裏使用的是使用yum安裝的mysql-5.1的版本, 使用的數據集爲從網絡上找到的一個員工數據庫

我們通過mysqldump進行一次完全備份, 再修改表中的數據, 然後再通過binary log進行恢復 二進制日誌需要在mysql配置文件中添加 log_bin=on 開啓

mysqldump命令介紹

mysqldump是一個客戶端的邏輯備份工具, 可以生成一個重現創建原始數據庫和表的SQL語句, 可以支持所有的存儲引擎, 對於InnoDB支持熱備

官方文檔介紹

查看數據庫的信息

1
mysql> SHOW DATABASES;    #查看當前的數據庫, 我們的數據庫爲employees
2
+--------------------+
3
| Database           |
4
+--------------------+
5
| information_schema |
6
| employees          |
7
| mysql              |
8
| test               |
9
+--------------------+
10
4 rows in set (0.00 sec)
11
12
mysql> USE employees;
13
Database changed
14
mysql> SHOW TABLES;         #查看當前庫中的表
15
+---------------------+
16
| Tables_in_employees |
17
+---------------------+
18
| departments         |
19
| dept_emp            |
20
| dept_manager        |
21
| employees           |
22
| salaries            |
23
| titles              |
24
+---------------------+
25
6 rows in set (0.00 sec)
26
27
mysql> SELECT COUNT(*) FROM employees;   #由於篇幅原因, 我們這裏只看一下employees的行數爲300024
28
+----------+
29
| COUNT(*) |
30
+----------+
31
|   300024 |
32
+----------+
33
1 row in set (0.05 sec)
34
35

使用mysqldump備份數據庫

使用lvm2快照備份數據

做實驗之前我們先回顧一下lvm2-snapshot的知識

LVM快照簡單來說就是將所快照源分區一個時間點所有文件的元數據進行保存,如果源文件沒有改變,那麼訪問快照卷的相應文件則直接指向源分區的源文件,如果源文件發生改變,則快照卷中與之對應的文件不會發生改變。快照卷主要用於輔助備份文件。 這裏只簡單介紹,點擊查看詳細介紹

部署lvm環境

1
添加硬盤; 這裏我們直接實現SCSI硬盤的熱插拔, 首先在虛擬機中添加一塊硬盤, 不重啓
2
3
[root@node1 ~]# ls /dev/sd*   #只有以下幾塊硬盤, 但是我們不重啓可以讓系統識別新添加的硬盤
4
/dev/sda  /dev/sda1  /dev/sda2
5
6
[root@node1 ~]# echo '- - -' > /sys/class/scsi_host/host0/scan 
7
[root@node1 ~]# echo '- - -' > /sys/class/scsi_host/host1/scan 
8
[root@node1 ~]# echo '- - -' > /sys/class/scsi_host/host2/scan 
9
10
[root@node1 ~]# ls /dev/sd*    #看!sdb識別出來了
11
/dev/sda  /dev/sda1  /dev/sda2  /dev/sdb
12
13
14
[root@node1 ~]# fdisk /dev/sdb   #分區
15
Device contains neither a valid DOS partition table, nor Sun, SGI or OSF disklabel
16
Building a new DOS disklabel with disk identifier 0xd353d192.
17
Changes will remain in memory only, until you decide to write them.
18
After that, of course, the previous content won't be recoverable.
19
20
Warning: invalid flag 0x0000 of partition table 4 will be corrected by w(rite)
21
22
WARNING: DOS-compatible mode is deprecated. It's strongly recommended to
23
         switch off the mode (command 'c') and change display units to
24
         sectors (command 'u').
25
26
Command (m for help): n
27
Command action
28
   e   extended
29
   p   primary partition (1-4)
30
p
31
Partition number (1-4): 1
32
First cylinder (1-2610, default 1): 
33
Using default value 1
34
Last cylinder, +cylinders or +size{K,M,G} (1-2610, default 2610): +15G
35
36
Command (m for help): t
37
Selected partition 1
38
Hex code (type L to list codes): 8e
39
Changed system type of partition 1 to 8e (Linux LVM)
40
41
Command (m for help): w
42
The partition table has been altered!
43
44
Calling ioctl() to re-read partition table.
45
Syncing disks.
46
You have new mail in /var/spool/mail/root
47
[root@node1 ~]# partx -a /dev/sdb
48
BLKPG: Device or resource busy
49
error adding partition 1
50
51
##創建邏輯卷
52
[root@node1 ~]# pvcreate /dev/sdb1
53
  Physical volume "/dev/sdb1" successfully created
54
[root@node1 ~]# vgcreate myvg /dev/sdb1 
55
  Volume group "myvg" successfully created
56
[root@node1 ~]# lvcreate -n mydata -L 5G myvg 
57
  Logical volume "mydata" created.
58
59
[root@node1 ~]# mkfs.ext4 /dev/mapper/myvg-mydata   #格式化
60
[root@node1 ~]# mkdir /lvm_data
61
[root@node1 ~]# mount /dev/mapper/myvg-mydata /lvm_data  #掛載到/lvm_data
62
63
64
[root@node1 ~]# vim /etc/my.cnf    #修改mysql配置文件的datadir如下
65
66
datadir=/lvm_data
67
68
[root@node1 ~]# service mysqld restart  #重啓MySQL
69
70
####重新導入employees數據庫########略過####
71
72

查看數據庫的信息

創建快照卷並備份

1
mysql> FLUSH TABLES WITH READ LOCK;     #鎖定所有表
2
Query OK, 0 rows affected (0.00 sec)
3
4
[root@node1 lvm_data]# lvcreate -L 1G -n mydata-snap -p r -s /dev/mapper/myvg-mydata   #創建快照卷
5
  Logical volume "mydata-snap" created.
6
7
mysql> UNLOCK TABLES;  #解鎖所有表
8
Query OK, 0 rows affected (0.00 sec)
9
10
[root@node1 lvm_data]# mkdir /lvm_snap  #創建文件夾
11
[root@node1 lvm_data]# mount /dev/myvg/mydata-snap /lvm_snap/  #掛載snap
12
mount: block device /dev/mapper/myvg-mydata--snap is write-protected, mounting read-only
13
14
[root@node1 lvm_data]# cd /lvm_snap/
15
[root@node1 lvm_snap]# ls
16
employees  ibdata1  ib_logfile0  ib_logfile1  mysql  mysql-bin.000001  mysql-bin.000002  mysql-bin.000003  mysql-bin.index  test
17
[root@node1 lvm_snap]# tar cf /tmp/mysqlback.tar *  #打包文件到/tmp/mysqlback.tar
18
19
[root@node1 ~]# umount /lvm_snap/  #卸載snap
20
[root@node1 ~]# lvremove myvg mydata-snap  #刪除snap
21
22
23

恢復數據

使用Xtrabackup備份

爲了更好地演示, 我們這次使用mariadb-5.5的版本, 使用xtrabackup使用InnoDB能夠發揮其最大功效, 並且InnoDB的每一張表必須使用單獨的表空間, 我們需要在配置文件中添加 innodb_file_per_table = ON 來開啓

下載安裝xtrabackup

1
我們這裏通過wget percona官方的rpm包進行安裝
2
[root@node1 ~]# wget https://www.percona.com/downloads/XtraBackup/Percona-XtraBackup-2.3.4/binary/redhat/6/x86_64/percona-xtrabackup-2.3.4-1.el6.x86_64.rpm   
3
[root@node1 ~]# yum localinstall percona-xtrabackup-2.3.4-1.el6.x86_64.rpm   #需要EPEL源
4

xtrabackup介紹

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

  1. 備份過程快速、可靠;

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

  3. 能夠基於壓縮等功能節約磁盤空間和流量;

  4. 自動實現備份檢驗;

  5. 還原速度快;

摘自馬哥的文檔

xtrabackup實現完全備份

我們這裏使用xtrabackup的前端配置工具innobackupex來實現對數據庫的完全備份

使用innobackupex備份時, 會調用xtrabackup備份所有的InnoDB表, 複製所有關於表結構定義的相關文件(.frm)、以及MyISAMMERGECSVARCHIVE表的相關文件, 同時還會備份觸發器和數據庫配置文件信息相關的文件, 這些文件會被保存至一個以時間命名的目錄.

備份過程

一般情況, 備份完成後, 數據不能用於恢復操作, 因爲備份的數據中可能會包含尚未提交的事務或已經提交但尚未同步至數據文件中的事務。因此, 此時的數據文件仍不一致, 所以我們需要”準備”一個完全備份

1
[root@node1 ~]# innobackupex --apply-log /extrabackup/2016-04-27_07-30-48/  #指定備份文件的目錄
2
3
#一般情況下下面三行結尾代表成功*****************
4
InnoDB: Starting shutdown...
5
InnoDB: Shutdown completed; log sequence number 369661462
6
160427 07:40:11 completed OK!
7
8
[root@node1 ~]# cd /extrabackup/2016-04-27_07-30-48/
9
[root@node1 2016-04-27_07-30-48]# ls -hl  #查看備份文件
10
total 31M
11
-rw-r----- 1 root root  386 Apr 27 07:30 backup-my.cnf
12
drwx------ 2 root root 4.0K Apr 27 07:30 employees
13
-rw-r----- 1 root root  18M Apr 27 07:40 ibdata1
14
-rw-r--r-- 1 root root 5.0M Apr 27 07:40 ib_logfile0
15
-rw-r--r-- 1 root root 5.0M Apr 27 07:40 ib_logfile1
16
drwx------ 2 root root 4.0K Apr 27 07:30 mysql
17
drwx------ 2 root root 4.0K Apr 27 07:30 performance_schema
18
drwx------ 2 root root 4.0K Apr 27 07:30 test
19
-rw-r----- 1 root root   27 Apr 27 07:30 xtrabackup_binlog_info
20
-rw-r--r-- 1 root root   29 Apr 27 07:40 xtrabackup_binlog_pos_innodb
21
-rw-r----- 1 root root  117 Apr 27 07:40 xtrabackup_checkpoints
22
-rw-r----- 1 root root  470 Apr 27 07:30 xtrabackup_info
23
-rw-r----- 1 root root 2.0M Apr 27 07:40 xtrabackup_logfile
24
25

恢復數據

增量備份

1
#########創建連兩個數據庫以供測試#####################
2
MariaDB [(none)]> CREATE DATABASE TEST1;
3
Query OK, 1 row affected (0.00 sec)
4
5
MariaDB [(none)]> CREATE DATABASE TEST2;
6
Query OK, 1 row affected (0.00 sec)
7
8
[root@node1 ~]# innobackupex --incremental /extrabackup/ --incremental-basedir=/extrabackup/2016-04-27_07-30-48/ 
9
10
[root@node1 ~]# ls /extrabackup/2016-04-27_07-57-22/ #查看備份文件
11
total 96
12
-rw-r----- 1 root root   386 Apr 27 07:57 backup-my.cnf
13
drwx------ 2 root root  4096 Apr 27 07:57 employees
14
-rw-r----- 1 root root 49152 Apr 27 07:57 ibdata1.delta
15
-rw-r----- 1 root root    44 Apr 27 07:57 ibdata1.meta
16
drwx------ 2 root root  4096 Apr 27 07:57 mysql
17
drwx------ 2 root root  4096 Apr 27 07:57 performance_schema
18
drwx------ 2 root root  4096 Apr 27 07:57 test
19
drwx------ 2 root root  4096 Apr 27 07:57 TEST1
20
drwx------ 2 root root  4096 Apr 27 07:57 TEST2
21
-rw-r----- 1 root root    21 Apr 27 07:57 xtrabackup_binlog_info
22
-rw-r----- 1 root root   123 Apr 27 07:57 xtrabackup_checkpoints
23
-rw-r----- 1 root root   530 Apr 27 07:57 xtrabackup_info
24
-rw-r----- 1 root root  2560 Apr 27 07:57 xtrabackup_logfile
25
26

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

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

整理增量備份

恢復數據

1
[root@node1 ~]# rm -rf /data/*   #刪除數據
2
3
[root@node1 ~]# innobackupex --copy-back /extrabackup/2016-04-27_07-30-48/     #整理增量備份之後可以直接通過全量備份還原
4
5
[root@node1 ~]# chown -R mysql.mysql /data/
6
[root@node1 ~]# ls /data/ -l
7
total 28732
8
-rw-rw---- 1 mysql mysql     8192 Apr 27 08:05 aria_log.00000001
9
-rw-rw---- 1 mysql mysql       52 Apr 27 08:05 aria_log_control
10
drwx------ 2 mysql mysql     4096 Apr 27 08:05 employees
11
-rw-r----- 1 mysql mysql 18874368 Apr 27 08:05 ibdata1
12
-rw-r----- 1 mysql mysql  5242880 Apr 27 08:05 ib_logfile0
13
-rw-r----- 1 mysql mysql  5242880 Apr 27 08:05 ib_logfile1
14
drwx------ 2 mysql mysql     4096 Apr 27 08:05 mysql
15
-rw-rw---- 1 mysql mysql      245 Apr 27 08:05 mysql-bin.000001
16
-rw-rw---- 1 mysql mysql       19 Apr 27 08:05 mysql-bin.index
17
-rw-r----- 1 mysql mysql     1812 Apr 27 08:05 node1.anyisalin.com.err
18
-rw-rw---- 1 mysql mysql        5 Apr 27 08:05 node1.anyisalin.com.pid
19
drwx------ 2 mysql mysql     4096 Apr 27 08:05 performance_schema
20
drwx------ 2 mysql mysql     4096 Apr 27 08:05 test
21
drwx------ 2 mysql mysql     4096 Apr 27 08:05 TEST1
22
drwx------ 2 mysql mysql     4096 Apr 27 08:05 TEST2
23
-rw-r----- 1 mysql mysql       29 Apr 27 08:05 xtrabackup_binlog_pos_innodb
24
-rw-r----- 1 mysql mysql      530 Apr 27 08:05 xtrabackup_info
25
26
MariaDB [(none)]> SHOW DATABASES;  #數據還原
27
+--------------------+
28
| Database           |
29
+--------------------+
30
| information_schema |
31
| TEST1              |
32
| TEST2              |
33
| employees          |
34
| mysql              |
35
| performance_schema |
36
| test               |
37
+--------------------+
38
7 rows in set (0.00 sec)
39
40
#關於xtrabackup還有很多強大的功能沒有敘述、有興趣可以去看官方文檔
41

總結

備份方法 備份速度 恢復速度 便捷性 功能 一般用於
cp 一般、靈活性低 很弱 少量數據備份
mysqldump 一般、可無視存儲引擎的差異 一般 中小型數據量的備份
lvm2快照 一般、支持幾乎熱備、速度快 一般 中小型數據量的備份
xtrabackup 較快 較快 實現innodb熱備、對存儲引擎有要求 強大 較大規模的備份

其實我們還可以通過Master-Slave Replication 進行數據備份、由於本文篇幅過長、遂放在下篇和大家分享

作者水平很低, 如果有錯誤及時指出, 如果你覺得本文寫的好請點一波贊~(≧▽≦)/~ 
作者: AnyISaIln QQ: 1449472454 
感謝: MageEdu

轉載請註明:linux運維部落 » 學會用各種姿勢備份MySQL數據庫

學會用各種姿勢備份MySQL數據庫


發佈了37 篇原創文章 · 獲贊 10 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章