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

一、簡介

1.1 增量備份簡介

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

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

    1.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日誌 

    在my.cnf或my.ini中增加

[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@cpk 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%';
+---------------------------------+-------+
| Variable_name                   | Value |
+---------------------------------+-------+
| log_bin                         | ON    |
| log_bin_trust_function_creators | OFF   |
+---------------------------------+-------+
mysql> show variables like 'binlog%';
+-----------------------------------------+-------+
| Variable_name                           | Value |
+-----------------------------------------+-------+
| binlog_cache_size                       | 32768 |
| binlog_direct_non_transactional_updates | OFF   |
| binlog_format                           | ROW |
| binlog_stmt_cache_size                  | 32768 |
+-----------------------------------------+-------+


    2.2 查看binlog日誌內容

[root@cpk data]# mysqlbinlog /var/lib/mysql/mysql-bin.000001 ;
mysqlbinlog: unknown variable 'default-character-set=utf8'


    這裏我們碰到了mysqlbinlog的一個bug,解決方法有兩個:
    方法一:使用--no-defaults選項 

[root@cpk data]# mysqlbinlog --no-defaults /var/lib/mysql/mysql-bin.000001 


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

# 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文件

(1)通過mysql客戶端查看

mysql> show master logs;
+------------------+-----------+
| Log_name         | File_size |
+------------------+-----------+
| mysql-bin.000001 |       120 |
+------------------+-----------+

(2)通過linux命令行直接查看(mysql數據目錄data)

[root@cpk 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;
mysql> use backup;
mysql> create table full (c1 int(10), c2 varchar(10));
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命令行下執行:

mysqldump  -u用戶名 -p密碼  數據庫名 表名 > /opt/backup/backup_full.sql
[root@cpk backup]# mysqldump -uroot -pjesse backup full > /opt/backup/backup_full.sql

  d.解除表鎖。

mysql> unlock tables;

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

3.4 準備第一份增量數據

mysql> use backup;
mysql> create table increment (c1 int(10), c2 varchar(20));
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@cpk backup]# mysqlbinlog  mysql-bin.000002 > /opt/backup/increment1.txt

d.解除表鎖。

mysql> unlock tables;

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

3.6 準備第二份增量數據

mysql> use backup;
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@cpk backup]# mysqlbinlog /var/lib/mysql/mysql-bin.000003 > /opt/backup/increment2.txt

   d.解除表鎖。

mysql> unlock tables;

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

 

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

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

mysql> use backup;
mysql> drop table full;
mysql> drop table increment;

此時數據庫數據被清空。

mysql> select * from backup.full;
ERROR 1146 (42S02): Table 'backup.full' doesn't exist
mysql> select * from backup.increment;
ERROR 1146 (42S02): Table 'backup.increment' doesn't exist

4.1 還原全備數據

    方法1:進入數據庫,通過source

mysql> use backup;
mysql> source /opt/backup/backup_full.sql;
mysql> select * from 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密碼  數據庫名  <  /opt/buckup/backup_full.sql

[root@cpk backup]# mysql -uroot -pjesse backup < /opt/buckup/backup_full.sql
mysql> select * from backup.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 /opt/backup/increment1.txt;
mysql> select * from backup.increment;
+------+------------+
| c1   | c2         |
+------+------------+
|   11 | increment1 |
|   12 | increment2 |
|   13 | increment3 |
|   14 | increment4 |
|   15 | increment5 |
+------+------------+

  方法二:通過binlog直接還原

    在linux命令行下執行:

mysqlbinlog  binlog文件名 | mysql -u用戶名 -p密碼
[root@cpk backup]# mysqlbinlog  /var/lib/mysql/mysql-bin.000002 | mysql -uroot -pjesse

  查看數據:

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

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

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

    在linux命令行下執行:

mysqlbinlog  binlog文件名 | mysql -u用戶名 -p密碼
[root@cpk backup]# mysqlbinlog  /var/lib/mysql/mysql-bin.000003 | mysql -uroot -pjesse

  查看數據:

mysql> select * from backup.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 ,感謝作者的貢獻 !!

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