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


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 如下:

[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.*這樣的文件,每啟動一次,就會增加一個或者多個。

 

[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開啟情況

 

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日志內容

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

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

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

 

[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),而不是服務器已經加載進內存的配置文件。

 

# 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 一些常用操作

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客戶端查看:
mysql> show master logs;  
02.+------------------+-----------+  
03.| Log_name         | File_size |  
04.+------------------+-----------+  
05.| mysql-bin.000001 |       107 |  
06.+------------------+-----------+  
  •  通過linux命令行直接查看(mysql數據目錄data)
[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 准備全量數據

 

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.備份前需要將數據庫加讀鎖,防止數據在備份時寫入。   

mysql> flush tables with read lock; 

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

mysql> flush logs;

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

[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.解除表鎖。 

mysql> unlock tables;  

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

 

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.備份前需要將數據庫加讀鎖,防止數據在備份時寫入。

mysql> flush tables with read lock;  

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

mysql> flush logs;

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

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

    d.解除表鎖。 

mysql> unlock tables;  

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

 

3.6 准備第二份增量數據

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

 

 

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

步驟如下:

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

mysql> flush tables with read lock; 

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

mysql> flush logs;  

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

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

    d.解除表鎖。 

mysql> unlock tables;  

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

 

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

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

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

此時數據庫數據被清空。

 

mysql> show databases;  
+--------------------+  
| Database           |  
+--------------------+  
| information_schema |  
| backup_full        |  
| mysql              |  
| performance_schema |  
| test               |  
+--------------------+  
   5 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
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:直接還原數據文件。
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 還原第一個增備文件

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

 

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命令行下執行:

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

 查看數據:

mysql> select * from backup_increment.increment;  
+------+------------+  
| c1   | c2         |  
+------+------------+  
|   11 | increment1 |  
|   12 | increment2 |  
|   13 | increment3 |  
|   14 | increment4 |  
|   15 | increment5 |  
+------+------------+  

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

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

在linux命令行下執行:

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

 查看數據:

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 ,感謝作者的貢獻 !!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM