為了發揮效用,備份必須定期排程。完整備份(時間點資料快照)可以使用數個工具在 MySQL 中完成。例如,MySQL Enterprise Backup 可以執行整個執行個體的實體備份,並針對在備份 InnoDB
資料檔案時,將額外負荷降至最低並避免中斷進行最佳化;mysqldump 提供線上邏輯備份。本討論使用 mysqldump。
假設我們在星期日下午 1 點負載較低時,使用以下命令對所有資料庫中的所有 InnoDB
表格進行完整備份
$> mysqldump --all-databases --source-data --single-transaction > backup_sunday_1_PM.sql
mysqldump產生的 .sql
檔案包含一組 SQL INSERT
陳述式,可用於稍後重新載入傾印的表格。
此備份操作會在傾印開始時取得所有表格的全域讀取鎖定(使用 FLUSH TABLES WITH READ LOCK
)。一旦取得此鎖定,就會讀取二進制日誌坐標,並釋放鎖定。如果在發出 FLUSH
陳述式時有長時間執行的更新陳述式,則備份操作可能會暫停直到這些陳述式完成。之後,傾印會變成無鎖定,且不會干擾表格上的讀取和寫入。
先前假設要備份的表格是 InnoDB
表格,因此 --single-transaction
使用一致的讀取,並保證 mysqldump 看到的資料不會變更。(其他用戶端對 InnoDB
表格所做的變更不會被 mysqldump 程序看到。)如果備份操作包含非交易表格,則一致性要求它們在備份期間不會變更。例如,對於 mysql
資料庫中的 MyISAM
表格,在備份期間不得對 MySQL 帳戶進行管理變更。
完整備份是必要的,但建立完整備份並不總是方便。它們會產生大型備份檔案,且需要時間產生。它們並非最佳化,因為每個連續的完整備份都包含所有資料,即使是自上次完整備份以來未變更的部分。更有效的方式是先進行初始完整備份,然後進行增量備份。增量備份較小,且產生所需時間較少。權衡之處在於,在還原時,您無法僅透過重新載入完整備份來還原資料。您還必須處理增量備份才能還原增量變更。
若要進行增量備份,我們需要儲存增量變更。在 MySQL 中,這些變更會以二進制日誌表示,因此應該始終使用 --log-bin
選項啟動 MySQL 伺服器,以啟用該日誌。啟用二進制日誌記錄後,伺服器會在更新資料時將每個資料變更寫入檔案。查看已執行數天的 MySQL 伺服器的資料目錄,我們會發現這些 MySQL 二進制日誌檔案
-rw-rw---- 1 guilhem guilhem 1277324 Nov 10 23:59 gbichot2-bin.000001
-rw-rw---- 1 guilhem guilhem 4 Nov 10 23:59 gbichot2-bin.000002
-rw-rw---- 1 guilhem guilhem 79 Nov 11 11:06 gbichot2-bin.000003
-rw-rw---- 1 guilhem guilhem 508 Nov 11 11:08 gbichot2-bin.000004
-rw-rw---- 1 guilhem guilhem 220047446 Nov 12 16:47 gbichot2-bin.000005
-rw-rw---- 1 guilhem guilhem 998412 Nov 14 10:08 gbichot2-bin.000006
-rw-rw---- 1 guilhem guilhem 361 Nov 14 10:07 gbichot2-bin.index
每次重新啟動時,MySQL 伺服器都會使用序列中的下一個數字建立新的二進制日誌檔案。在伺服器執行時,您也可以透過發出 FLUSH LOGS
SQL 陳述式或使用 mysqladmin flush-logs 命令手動告知伺服器關閉目前的二進制日誌檔案並開始新的檔案。mysqldump 也具有清除日誌的選項。資料目錄中的 .index
檔案包含目錄中所有 MySQL 二進制日誌的清單。
MySQL 二進制日誌對於還原很重要,因為它們構成增量備份的集合。如果您確定在進行完整備份時清除日誌,則之後建立的二進制日誌檔案會包含自備份以來所做的所有資料變更。讓我們稍微修改先前的 mysqldump 命令,以便在完整備份時清除 MySQL 二進制日誌,並使傾印檔案包含新的目前二進制日誌的名稱
$> mysqldump --single-transaction --flush-logs --source-data=2 \
--all-databases > backup_sunday_1_PM.sql
執行此命令後,資料目錄會包含新的二進制日誌檔案 gbichot2-bin.000007
,因為 --flush-logs
選項會導致伺服器清除其日誌。--source-data
選項會使 mysqldump 將二進制日誌資訊寫入其輸出,因此產生的 .sql
傾印檔案會包含這些行
-- Position to start replication or point-in-time recovery from
-- CHANGE REPLICATION SOURCE TO SOURCE_LOG_FILE='gbichot2-bin.000007',SOURCE_LOG_POS=4;
由於 mysqldump 命令進行了完整備份,這些行表示兩件事
傾印檔案包含寫入
gbichot2-bin.000007
二進制日誌檔案或更高版本之前所做的所有變更。備份後記錄的所有資料變更都不在傾印檔案中,而是在
gbichot2-bin.000007
二進制日誌檔案或更高版本中。
在星期一下午 1 點,我們可以透過清除日誌以開始新的二進制日誌檔案來建立增量備份。例如,執行 mysqladmin flush-logs 命令會建立 gbichot2-bin.000008
。星期日下午 1 點的完整備份與星期一下午 1 點之間的所有變更都會寫入 gbichot2-bin.000007
。此增量備份很重要,因此最好將其複製到安全的位置。(例如,將其備份到磁帶或 DVD 上,或將其複製到另一部電腦。)在星期二下午 1 點,執行另一個 mysqladmin flush-logs 命令。星期一下午 1 點到星期二下午 1 點之間的所有變更都會寫入 gbichot2-bin.000008
(也應該將其複製到安全的地方)。
MySQL 二進制日誌會佔用磁碟空間。為了釋放空間,您需要不時清除它們。一種方法是刪除不再需要的二進制日誌,例如在我們進行完整備份時。
$> mysqldump --single-transaction --flush-logs --source-data=2 \
--all-databases --delete-source-logs > backup_sunday_1_PM.sql
如果您的伺服器是複寫來源伺服器,使用 mysqldump --delete-source-logs
刪除 MySQL 二進制日誌可能會有危險,因為複本可能尚未完全處理二進制日誌的內容。 PURGE BINARY LOGS
陳述式的說明解釋了在刪除 MySQL 二進制日誌之前應該驗證哪些內容。請參閱 第 15.4.1.1 節,「PURGE BINARY LOGS 陳述式」。