DBA 必知的 MYSQL 備份與還原方法


一mysqldump 備份結合 binlog 日志恢復

說明:MySQL 備份一般采取全庫備份加日志備份的方式,例如每天執行一次全備份,每小時執行一次二進制日志備份。這樣在 MySQL 故障后可以使用全備份和日志備份將數據恢復到最后一個二進制日志備份前的任意位置或時間。

Binlog 功能默認是關閉的,沒有開啟。

查看 binlog,用 mysqlbinlog -v mysql-bin.000001

主從同步

恢復數據庫

開啟 binary log 功能:通過編輯 my.cnf 中的 log-bin 選項可以開啟二進制日志;形式如右:log-bin[=DIR/[filename]] ,注釋:每次重啟 mysql 服務或運行 mysql> flush logs;都會生成一個新的二進制日志文件,這些日志文件的 number 會不斷地遞增,除了生成上述的文件外還會生成一個名為 filename.index 的文件。這個文件中存儲所有二進制日志文件的清單又稱為二進制文件的索引。

說明:bin-log 因為是二進制文件,不能通過文件內容查看命令直接打開查看,mysql 提供兩種方式查看方式。

查看指定的二進制日志中的事件:

該命令還包含其他選項以便靈活查看:

總結:上述方式可以查看到服務器上存在的二進制日志文件及文件中的事件,但是想查看到文件中具體的內容並應於恢復場景還得借助 mysqlbinlog 這個工具。

語法格式:mysqlbinlog [options] log_file ...

輸出內容會因日志文件的格式以及 mysqlbinlog 工具使用的選項不同而略不同。

mysqlbinlog 的可用選項可參考 man 手冊。

說明:無論是本地二進制日志文件還是遠程服務器上的二進制日志文件,無論是行模式、語句模式還是混合模式的二進制日志文件,被 mysqlbinlog 工具解析后都可直接應用與MySQL Server 進行基於時間點、位置或數據庫的恢復。

下面我們就來演示如何使用 binlog 恢復之前刪除數據(id=2那條記錄)

注意:在實際生產環境中,如果遇到需要恢復數據庫的情況,不要讓用戶能訪問到數據庫,以避免新的數據插入進來,以及在主從的環境下,關閉主從。

delete from bdqn.test where id=2

# cd/usr/local/mysql/data/

# mysqlbinlog -v mysql-bin.000002

顯示結果如下:(復制的日志)

# at 219

#170316 21:52:28 server id 1 end_log_pos 287 CRC32 0xff83a85b Query thread_id=2 exec_time=0 error_code=0

SET TIMESTAMP=1489672348/*!*/;

SET @@session.pseudo_thread_id=2/*!*/;

SET @@session.foreign_key_checks=1,@@session.sql_auto_is_null=0, @@session.unique_checks=1,@@session.autocommit=1/*!*/;

SET @@session.sql_mode=1075838976/*!*/;

SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;

/*!\C utf8 *//*!*/;

SET@@session.character_set_client=33,@@session.collation_connection=33,

@@session.collation_server=33/*!*/;

SET @@session.lc_time_names=0/*!*/;

SET @@session.collation_database=DEFAULT/*!*/;

BEGIN

/*!*/;

# at 287

#170316 21:52:28 server id 1 end_log_pos 337 CRC32 0x343e7343 Table_map: `bdqn`.`test` mapped to number 108

# at 337

#170316 21:52:28 server id 1 end_log_pos 382 CRC32 0xa3d1ce0d Delete_rows: table id 108 flags: STMT_END_F

BINLOG '

nJjKWBMBAAAAMgAAAFEBAAAAAGwAAAAAAAEABGJkcW4ABHRlc3QAAgMPAjwAAkNzPjQ

=nJjKWCABAAAALQAAAH4BAAAAAGwAAAAAAAEAAgAC//wCAAAABGxpc2kNztGj

'/*!*/;

### DELETE FROM `bdqn`.`test`

### WHERE

### @1=2

### @2='lisi'

# at 382

#170316 21:52:28 server id 1 end_log_pos 413 CRC32 0x257e7073 Xid = 10

COMMIT/*!*/;

說明:可以從上圖可以看出來 delete 時間發生 position 是 287,事件結束 position 是413。

②恢復流程:直接用 bin-log 日志將數據庫恢復到刪除位置 287 前,然后跳過故障點,再進行恢復下面所有的操作,命令如下

由於之前沒有做過全庫備份,所以要使用所有 binlog 日志恢復,所以生產環境中需要很長時間恢復,導出相關 binlog 文件。

③刪除 bdqn 數據庫(刪除 bdqn 和恢復數據之前,要關閉 binlog 功能)

 
 
 

作用:mysqldump 是 mysql 自帶的備份和數據轉移的工具。

它只產生 sql 語句(即 sql 命令)封裝在文件,而不是真實的數據。

Mysqldump 是邏輯備份,不是物理備份,備份的是 SQL 語句,而不是數據文件。

Mysqldump 適用於小型數據庫,數據容量一般是在幾個 G 大小,當數據量很大的情況下,不建議使用 mysqldump。

導出對象:可以針對單個表、多個表、單個數據庫、多個數據庫、所有數據庫。

#mysqldump [選項] 庫名 [表名1] [表名2] … > /備份路徑/備份文件名

//導出指定數據庫的單個或多個表

#mysqldump [選項] --databases 庫名1 [庫名2] … > /備份路徑/備份文件名

//導出指定的數據庫或多個數據庫

#mysqldump [選項] --all-databases > /備份路徑/備份文件名

//導出所有的數據庫

#mysqldump -uroot -p123456 --flush-logs bdqn > /opt/bdqn.sql

//導出數據庫bdqn,其中“—flush-logs”這個選項是完整備份完畢后開啟一個新的binlog

#mysql -uroot -p123456 bdqn < /opt/bdqn.sql

//從備份文件導入數據庫bdqn

下面用一個具體的實驗說明用mysqldump實現全庫備份+binlog的數據恢復

 
 

4)開始全庫備份(注意:全庫備份不會備份 binlog 日志文件)

 

5)備份 mysqldump 全庫備份之前的所有的 binlog 日志文件(注意:真是生產環境中可能不止一個 binlog 文件)

6)因為全庫備份之前的 binlog 已經備份了,現在就刪除它們(即新產生的 binlog 之前的所有的 binlog 刪除)

①使用 mysqldump 的備份進行全庫恢復(即恢復到全部備份時候的所有數據)

②分析新開啟的 binlog 日志文件(我這里是 mysql-bin.000002)里面誤操作的事件的起始位置和終止位置,只要跳過這一段事件即可

復制的日志:

# at 219

#170318 21:14:42 server id 1 end_log_pos 291 CRC32 0xddbf8eff Query thread_id=5 exec_time=0 error_code=0

SET TIMESTAMP=1489842882/*!*/;

SET @@session.pseudo_thread_id=5/*!*/;

SET @@session.foreign_key_checks=1,@@session.sql_auto_is_null=0, @@session.unique_checks=1,@@session.autocommit=1/*!*/;

SET @@session.sql_mode=1075838976/*!*/;

SET @@session.auto_increment_increment=1,@@session.auto_increment_offset=1/*!*/;

/*!\C utf8 *//*!*/;

SET @@session.character_set_client=33,@@session.collation_connection=33,@@session.

collation_server=33/*!*/;

SET @@session.lc_time_names=0/*!*/;

SET @@session.collation_database=DEFAULT/*!*/;

BEGIN

/*!*/;

# at 291

#170318 21:14:42 server id 1 end_log_pos 339 CRC32 0x4a9ec8f2 Table_map: `bdqn`.`it` mapped to number 108

# at 339

#170318 21:14:42 server id 1 end_log_pos 388 CRC32 0x2e8a3da8 Delete_rows: table id 108 flags: STMT_END_F

BINLOG '

wjLNWBMBAAAAMAAAAFMBAAAAAGwAAAAAAAEABGJkcW4AAml0AAIDDwI8AALyyJ5K

wjLNWCABAAAAMQAAAIQBAAAAAGwAAAAAAAEAAgAC//wBAAAACHpoYW5nc2FuqD2KLg

=='/*!*/;

### DELETE FROM `bdqn`.`it`

### WHERE

### @1=1

### @2='zhangsan'

# at 388

#170318 21:14:42 server id 1 end_log_pos 419 CRC32 0xa1c06a4f Xid = 43

COMMIT/*!*/;

③開始使用全庫備份后的增量備份的 binlog 日志文件備份文件進行對全庫恢復后的增量數據的恢復

總結:從上圖顯示可以看出數據恢復到正常狀態,實際生產環境中 mysql 數據庫的備份是周期性重復操作,所有通常是要編寫腳本實現,通過 crond 計划任務周期性執行備份腳本。

周日凌晨1點全庫備份;

周一到周六凌晨每隔4個小時增量備份一次

設置 crontab 任務,每天執行備份腳本:

2)編寫 mysqlfullbackup.sh 腳本(即 mysql 全庫備份腳本)

3)編寫 mysqldailybackup.sh 腳本(即 mysql 增量備份腳本)

發送郵件測試:

 

安裝 libmysqlclient.so.18

 
 

再次測試:

 

二使用 xtrabackup 進行 MySQL 數據庫備份

前面介紹mysqldump 備份方式是采用邏輯備份,其最大的缺陷就是備份和恢復速度都慢,對於一個小於 50G 的數據庫而言,這個速度還是能接受的,但如果數據庫非常大,那再使用 mysqldump 備份就不太適合了。

這時就需要一種好用又高效的工具,xtrabackup就是其中一款,號稱免費版的 InnoDB HotBackup。

目前主流的有兩個工具可以實現物理熱備:ibbackup 和 xtrabackup;

ibbackup 是商業軟件,需要授權,非常昂貴。

xtrabackup 功能比 ibbackup 還要強大,但卻是開源的。因此我們這里就來介紹 xtrabackup 的使用。

xtrabackup:專用於備份 InnoDB 和 XtraDB 引擎的數據;

innobackupex:這是一個 perl 腳本,在執行過程中會調用 xtrabackup 命令,這樣用該命令即可以實現備份 InnoDB,也可以備份 MyISAM 引擎的對象。

(1)備份過程快速、可靠;

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

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

(4)自動實現備份檢驗;

(5)還原速度快。

官方鏈接地址:

http://www.percona.com/software/percona-xtrabackup;

可以下載源碼編譯安裝,也可以下載適合的 RPM 包或使用 yum 進行安裝或者下載二進制源碼包。

wget https://www.percona.com/downloads/XtraBackup/Percona-XtraBackup-2.4.4/binary/tarball/percona-xtrabackup-2.4.4-Linux-x86_64.tar.gz

Xtrabackup 中主要包含兩個工具:

xtrabackup:是用於熱備份 innodb,xtradb 表中數據的工具,支持在線熱備份,可以在不加鎖的情況下備份 Innodb 數據表,不過此工具不能操作 Myisam 引擎表;

innobackupex:是將 xtrabackup 進行封裝的 perl 腳本,能同時處理 Innodb 和 Myisam,但在處理 Myisam 時需要加一個讀鎖。

由於操作 Myisam 時需要加讀鎖,這會堵塞線上服務的寫操作,而 Innodb 沒有這樣的限制,所以數據庫中 Innodb 表類型所占的比例越大,則越有利。

#wget https://www.percona.com/downloads/percona-toolkit/2.2.19/RPM/percona-toolkit-2.2.19-1.noarch.rpm

至此就完成了xtrabackup的安裝,下面就可以啟動備份了。

 

2)創建備份用的目錄(full:全備存放的目錄;inc:增量備份存放的目錄)

 
 
 

在使用 innobackupex 進行備份時,還可以使用 --no-timestamp 選項來阻止命令自動創建一個以時間命名的目錄;如此一來,innobackupex 命令將會創建一個 BACKUP-DIR 目錄來存儲備份數據。

還可以加 —database 選項指定要備份的數據庫,這里指定的數據庫只對 MyISAM 表有效,對於 InnoDB 數據來說都是全備(所有數據庫中的 InnoDB 數據都進行了備份,不是只備份指定的數據庫,恢復時也一樣)。

 

下面我們大體看一下這幾個文件:

 
 

說明:xtrabackup_binlog_pos_innodb 和 xtrabackup_binary 在這個版本里面沒有了,因為版本較新,這兩個文件在新版給刪除了,只存在於老版本。

 
 
 
 

我這里直接使用刪除數據目錄文件來模擬損壞。

一般情況下,在備份完成后,數據尚且不能用於恢復操作,因為備份的數據中可能會包含尚未提交的事務或已經提交但尚未同步至數據文件中的事務。因此,此時數據文件仍處理不一致狀態。“准備”的主要作用正是通過回滾未提交的事務及同步已經提交的事務至數據文件也使得數據文件處於一致性狀態。

在准備(prepare)過程結束后,InnoDB 表數據已經前滾到整個備份結束的點,而不是回滾到 xtrabackup 剛開始時的點。

innobakupex 命令的 --apply-log 選項可用於實現上述功能。如下面的命令:

--apply-log 指明是將日志應用到數據文件上,完成之后將備份文件中的數據恢復到數據庫中:

在實現“准備”的過程中,innobackupex通常還可以使用--use-memory選項來指定其可以使用的內存的大小,默認通常為100M。如果有足夠的內存可用,可以多划分一些內存給prepare的過程,以提高其完成速度。

說明:innobackupex 命令的 --copy-back 選項用於執行恢復操作,其通過復制所有數據相關的文件至 mysql 服務器 DATADIR 目錄中來執行恢復過程。innobackupex 通過backup-my.cnf 來獲取 DATADIR 目錄的相關信息。

⑧正式開始還原增量備份

⑨重新啟動二進制日志並驗證還原數據

附:Xtrabackup 的“流”及“備份壓縮”功能

作用:Xtrabackup 對備份的數據文件支持“流”功能,即可以將備份的數據通過 STDOUT 傳輸給 tar 程序進行歸檔,而不是默認的直接保存至某備份目錄中。

要使用此功能,僅需要使用 --stream 選項即可。如:

看不清截圖的可以看下面復制粘貼的命令:

# innobackupex --user=root --password="123456"--stream=tar /opt/mysqlbackup/full/ | gzip >/opt/mysqlbackup/full/full_`date+%F_%H%M%S`.tar.gz

(再補充一句,現實生產環境中,基本上都要用流與備份壓縮功能,因為這樣可以很大程度上節省空間)

鏈接:http://zpf666.blog.51cto.com/11248677/1913451


免責聲明!

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



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