MySQL數據庫備份還原(基於binlog的增量備份)

一、簡介

1、增量備份

     增量備份 是指在一次全備份或上一次增量備份後,以後每次的備份只需備份與前一次相比增加或者被修改的文件。這就意味着,第一次增量備份的對象是進行全備後所產生的增加和修改的文件;第二次增量備份的對象是進行第一次增量備份後所產生的增加和修改的文件,如此類推。這種備份方式最顯著的優點就是:沒有重複的備份數據,因此備份的數據量不大,備份所需的時間很短。但增量備份的數據恢復是比較麻煩的。您必須具有上一次全備份和所有增量備份磁帶(一旦丟失或損壞其中的一個增量,就會造成恢復的失敗),並且它們必須沿着從全備份到依次增量備份的時間順序逐個反推恢復,因此這就極大地延長了恢復時間。

      假如我們有一個數據庫,有20G的數據,每天會增加10M的數據,數據庫每天都要全量備份一次,這樣的話服務器的壓力比較大,因此我們只需要備份增加的這部分數據,這樣減少服務器的負擔。

2、binlog簡介

binlog日誌由配置文件的 log-bin 選項負責啓用,MySQL服務器將在數據根目錄創建兩個新文 件XXX-bin.001和xxx-bin.index,若配置選項沒有給出文件名,Mysql將使用主機名稱命名這兩個文件,其中.index文件包含一份全體日誌文件的清單。  

      Mysql會把用戶對所有數據庫的內容和結構的修改情況記入XXX-bin.n文件,而不會記錄 SELECT和沒有實際更新的UPDATE語句。
       當MySQL數據庫停止或重啓時,服務器會把日誌文件記入下一個日誌文件,Mysql會在重啓時生成一個新的binlog日誌文件,文件序號遞增,此外,如果日誌文件超過max_binlog_size系統變量配置的上限時,也會生成新的日誌文件。

二、binlog日誌操作

2.1、開啓binlog日誌

修改 MySQL 的配置文件my.cnf 如下:

1
2
3
[mysqld] 
log-bin = mysql-bin 
binlog_format = row 

 其中:log-bin若不顯示指定存儲目錄,則默認存儲在mysql的data目錄下 

    binlog_format的幾種格式:(STATEMENT,ROW和MIXED),

 STATEMENT:基於SQL語句的複製(statement-based replication, SBR)    

ROW:基於行的複製(row-based replication, RBR)    

MIXED:混合模式複製(mixed-based replication, MBR)

    啓動後會產生mysql-bin.*這樣的文件,每啓動一次,就會增加一個或者多個。

 

1
2
3
4
[root@localhost data]# ls -l| grep mysql-bin 
02.-rw-rw----. 1 mysql mysql       107 Jul  5 11:19 mysql-bin.000001 
03.-rw-rw----. 1 mysql mysql        19 Jul  5 11:19 mysql-bin.index 
04.[root@localhost data]#
  • 查看binlog開啓情況

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
mysql> show variables like 'log_bin%'
02.+---------------------------------+-------+ 
03.| Variable_name                   | Value | 
04.+---------------------------------+-------+ 
05.| log_bin                         | ON    
06.| log_bin_trust_function_creators | OFF   
07.+---------------------------------+-------+ 
08.mysql> show variables like 'binlog%'
09.+-----------------------------------------+-------+ 
10.| Variable_name                           | Value | 
11.+-----------------------------------------+-------+ 
12.| binlog_cache_size                       | 32768 | 
13.| binlog_direct_non_transactional_updates | OFF   
14.| binlog_format                           | ROW | 
15.| binlog_stmt_cache_size                  | 32768 | 
16.+-----------------------------------------+-------+ 

 

 

2.2、查看binlog日誌內容

1
2
[root@localhost data]# mysqlbinlog /usr/local/mysql/data/mysql-bin.000001 ; 
02.mysqlbinlog: unknown variable 'default-character-set=utf8' 

 這裏我們碰到了mysqlbinlog的一個bug,解決方法有兩個:

  • 方法一:使用--no-defaults選項

 

1
[root@localhost data]# mysqlbinlog --no-defaults /usr/local/mysql/data/mysql-bin.000001  

 

  • 方法二:將my.cnf中[client]選項組中default-character-set=utf8選項臨時屏蔽掉(該選項即時生效,不用重啓數據庫),使用完mysqlbinlog命令時在恢復。因爲使用mysqlbinlog工具查看二進制日誌時會重新讀取的mysql的配置文件my.cnf(windows下是my.ini),而不是服務器已經加載進內存的配置文件。

 

1
2
3
4
5
6
7
8
9
# at 188 
#140705 11:23:55 server id 1  end_log_pos 271   Query   thread_id=1 exec_time=0 error_code=0 
SET TIMESTAMP=1404573835/*!*/; 
create database test 
/*!*/; 
DELIMITER ; 
# End of log file 
ROLLBACK /* added by mysqlbinlog */; 
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; 

包含以下要素:

    Position:位於文件中的位置,即第一行的(#at 4)和第二行的(log_pos 4),說明該事件記錄從文件第4字節開始。      

    Timestamp:事件發生的時間戳,即第二行的(#070813 14:16:36)    

    Exec_time:事件的執行花費時間    

    Error_code:錯誤碼     

    Type 事件類型:     

           Master ID:創建二進制事件的主機服務器ID     

           Master Pos:事件在原始二進制文件中的位置 

           Flags:標誌信息

 

2.3 一些常用操作

1
2
3
4
5
mysql> show master logs;  #查看數據庫所有日誌文件。 
mysql> show binlog events \g;  #查看當前使用的binlog文件信息。 
mysql> show binlog events in 'mysql-bin.000016';  #查看指定的binlog文件信息。 
mysql> flush logs;  #將內存中log日誌寫磁盤,保存在當前binlog文件中,併產生一個新的binlog日誌文件。 
mysql> flush logs; reset master;  #刪除所有二進制日誌,並重新(mysql-bin.000001)開始記錄。

 

三、MySQL備份實例(全備 + 基於 binlog的增備)

   示例採用小數據量進行模擬,包含一份全備及兩份增備,主要演示下備份還原過程,工程中可根據數據實際情況進行備份還原策略調整。

3.1 查看當前數據庫binlog文件

  • 通過mysql客戶端查看:
1
2
3
4
5
6
mysql> show master logs; 
02.+------------------+-----------+ 
03.| Log_name         | File_size | 
04.+------------------+-----------+ 
05.| mysql-bin.000001 |       107 | 
06.+------------------+-----------+ 
  •  通過linux命令行直接查看(mysql數據目錄data)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
[root@localhost data]# ll -h 
total 5.1G 
-rw-rw---- 1 mysql mysql 1.0G Jul 23 13:29 ibdata1 
-rw-rw---- 1 mysql mysql 2.0G Jul 18 14:12 ibdata2 
-rw-rw---- 1 mysql mysql 1.0G Jul 23 13:29 ib_logfile0 
-rw-rw---- 1 mysql mysql 1.0G Jul 23 13:29 ib_logfile1 
drwxr-xr-x 2 mysql mysql 4.0K Jul 18 13:52 mysql 
-rw-rw---- 1 mysql mysql  107 Jul 23 13:29 mysql-bin.000001 
-rw-rw---- 1 mysql mysql   19 Jul 23 13:29 mysql-bin.index 
srwxrwxrwx 1 mysql mysql    0 Jul 18 14:14 mysql.sock 
drwx------ 2 mysql mysql 4.0K Jul 18 14:01 performance_schema 
-rw-rw---- 1 mysql mysql  483 Jul 23 13:29 R820-08.err 
-rw-rw---- 1 mysql mysql    5 Jul 18 14:14 R820-08.pid 
drwx------ 2 mysql mysql   19 Jul 22 23:15 test 

 目前只有一個binlog文件mysql-bin.000001。

 

 

3.2 準備全量數據

 

1
2
3
4
mysql> create database backup_full; 
mysql> create table full (c1 int(10), c2 varchar(20)) engine=innodb; 
mysql> insert into full values (1, 'full1'),(2, 'full2'),(3, 'full3'),(4, 'full4'), 
           (5, 'full5'),(6, 'full6'),(7, 'full7'),(8, 'full8'),(9, 'full9'),(10, 'full10'); 

3.3 將全量數據進行備份

步驟如下:

    a.備份前需要將數據庫加讀鎖,防止數據在備份時寫入。   

1
mysql> flush tables with read lock;

   b.通過命令flush logs;將log日誌刷盤,寫入當前binlog(mysql-bin.000001),在生成一個新的binlog(mysql-bin.000002)爲增備做準備。 

1
mysql> flush logs;

    c.進行數據備份。在linux命令行下執行:

1
2
[root]mysqldump  -u用戶名 -p密碼 -hIP地址 -P端口 數據庫名 > /tmp/backup_full.sql 
[root]mysqldump  -uroot -pjesse -h127.0.0.1 -P3355 buckup_full > /tmp/backup_full.sql 

    d.解除表鎖。 

1
mysql> unlock tables; 

 至此全量備份全部結束,將全量數據文件buckup_full.sql保存即可。數據庫再有新的數據更新會記錄在新的binlog(mysql-bin.000002)裏面。

 

3.4 準備第一份增量數據

 

1
2
3
4
mysql> create database backup_increment; 
mysql> use backup_increment; 
mysql> create table increment (c1 int(10), c2 varchar(20)) engine=innodb; 
mysql> insert into increment values (11, 'increment1'),(12, 'increment2'),(13, 'increment3'),(14, 'increment4'),(15, 'increment5'); 

 

3.5 將第一份增量數據進行備份

步驟如下:

    a.備份前需要將數據庫加讀鎖,防止數據在備份時寫入。

1
mysql> flush tables with read lock; 

   b.通過命令flush logs;將log日誌刷盤,寫入當前binlog(mysql-bin.000002),在生成一個新的binlog(mysql-bin.000003)爲下次增備做準備。 

1
mysql> flush logs;

    c.將binlog第一個增備文件mysql-bin.000002直接複製保存即可。        也可以將二進制文件導出到文本文件保存,在linux命令行下執行

1
[root ]mysqlbinlog  mysql-bin.000002 > /tmp/increment1.txt 

    d.解除表鎖。 

1
mysql> unlock tables; 

 至此第一個增量備份全部結束,將增量binlog文件mysql-bin.000002或者有binlog文件導出的文本文件/tmp/increment1.txt保存即可。數據庫再有新的數據更新會記錄在新的binlog(mysql-bin.000003)裏面。

 

3.6 準備第二份增量數據

1
2
mysql> use backup_increment; 
mysql> insert into increment values (16, 'increment16'),(17, 'increment17'),(18, 'increment18'),(19, 'increment19'),(20, 'increment20');

 

 

3.7 將第二份增量數據進行備份

步驟如下:

    a.備份前需要將數據庫加讀鎖,防止數據在備份時寫入。

1
mysql> flush tables with read lock;

    b.通過命令flush logs;將log日誌刷盤,寫入當前binlog(mysql-bin.000003),在生成一個新的binlog(mysql-bin.000004)爲下次增備做準備。 

1
mysql> flush logs; 

    c.將binlog第一個增備文件mysql-bin.000003直接複製保存即可。        也可以將二進制文件導出到文本文件保存,在linux命令行下執行

1
[root]mysqlbinlog  mysql-bin.000003 > /tmp/increment2.txt 

    d.解除表鎖。 

1
mysql> unlock tables; 

 至此第二個增量備份全部結束,將增量binlog文件mysql-bin.000003或者有binlog文件導出的文本文件/tmp/increment2.txt保存即可。數據庫再有新的數據更新會記錄在新的binlog(mysql-bin.000004)裏面。

 

四、mysql還原實例分析(全備還原+基於binlog的增備還原)

模擬數據庫故障,即刪除全備數據及增備數據庫。

1
2
mysql> drop table backup_full.full
mysql> drop database backup_increment;

此時數據庫數據被清空。

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
mysql> show databases; 
+--------------------+ 
Database           
+--------------------+ 
| information_schema | 
| backup_full        | 
| mysql              | 
| performance_schema | 
| test               | 
+--------------------+ 
   rows in set (0.00 sec) 
 
mysql> select from backup_full.full
ERROR 1146 (42S02): Table 'backup_full.full' doesn't exist 
mysql> select * from backup_increment.increment; 
ERROR 1146 (42S02): Table 'backup_increment.increment' doesn't exist 

4.1 還原全備數據

  •  方法1:進入數據庫,通過source
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
mysql> use backup_full; 
mysql> source /tmp/backup_full.sql; 
mysql> select from backup_full.full
+------+--------+ 
| c1   | c2     | 
+------+--------+ 
|    1 | full1  | 
|    2 | full2  | 
|    3 | full3  | 
|    4 | full4  | 
|    5 | full5  | 
|    6 | full6  | 
|    7 | full7  | 
|    8 | full8  | 
|    9 | full9  | 
|   10 | full10 | 
+------+--------+ 

 全量數據還原成功。

  •  方法2:直接還原數據文件。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
mysql -u用戶名 -p密碼  -hIP地址    -P端口 數據庫名     < /tmp/buckup_full.sql 
mysql -uroot   -pjesse -h127.0.0.1 -P3355 backup_full  < /tmp/buckup_full.sql 
mysql> select from backup_full.full
+------+--------+ 
| c1   | c2     | 
+------+--------+ 
|    1 | full1  | 
|    2 | full2  | 
|    3 | full3  | 
|    4 | full4  | 
|    5 | full5  | 
|    6 | full6  | 
|    7 | full7  | 
|    8 | full8  | 
|    9 | full9  | 
|   10 | full10 | 
+------+--------+

 

4.2 還原第一個增備文件

  •  方法一:通過文本文件還原

 

1
2
3
4
5
6
7
8
9
10
11
mysql> source /tmp/increment1.txt; 
mysql> select from backup_increment.increment; 
+------+------------+ 
| c1   | c2         | 
+------+------------+ 
|   11 | increment1 | 
|   12 | increment2 | 
|   13 | increment3 | 
|   14 | increment4 | 
|   15 | increment5 | 
+------+------------+

 

  • 方法二:通過binlog直接還原

在linux命令行下執行:

1
2
[root]mysqlbinlog  binlog文件名 | mysql -u用戶名 -p密碼 -hIP地址 -P端口 
[root]mysqlbinlog  mysql-bin.000002 | mysql -uroot -pjesse -h127.0.0.1 -P3355 

 查看數據:

1
2
3
4
5
6
7
8
9
10
mysql> select from backup_increment.increment; 
+------+------------+ 
| c1   | c2         | 
+------+------------+ 
|   11 | increment1 | 
|   12 | increment2 | 
|   13 | increment3 | 
|   14 | increment4 | 
|   15 | increment5 | 
+------+------------+ 

 第一份增量數據還原成功!

4.3 還原第二個增備文件(方法同上)

在linux命令行下執行:

1
2
[root]mysqlbinlog  binlog文件名 | mysql -u用戶名 -p密碼 -hIP地址 -P端口 
[root]mysqlbinlog  mysql-bin.000003 | mysql -uroot -pjesse -h127.0.0.1 -P3355 

 查看數據:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
mysql> select from backup_increment.increment; 
+------+-------------+ 
| c1   | c2          | 
+------+-------------+ 
|   11 | increment1  | 
|   12 | increment2  | 
|   13 | increment3  | 
|   14 | increment4  | 
|   15 | increment5  | 
|   16 | increment16 | 
|   17 | increment17 | 
|   18 | increment18 | 
|   19 | increment19 | 
|   20 | increment20 | 
+------+-------------+ 

 至此數據全部還原成功!


 以上內容來自 http://blog.csdn.net/jesseyoung/article/details/37106035 ,感謝作者的貢獻 !!

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