xtrabackup 2.4 單庫備份恢復 (指定數據庫備份和恢復)完整教程
需求:
數據庫A存在app1數據庫,需要通過xtrabackup將此數據庫遷移到數據庫B,數據庫B已經存在其他數據庫數據,要求傳輸過程不能對B數據庫的數據造成損失。
根據需求,我將采用“傳輸表空間”(Transportable Tablespaces)的方式來完成這個任務,這是實現部分恢復(Partial Restore)最安全、最高效的方法。
本次測試數據庫版本為MySQL 5.7
重要:準備工作與前提條件
在開始之前,請務必確認以下幾點,否則恢復過程會失敗:
-
備份與演練:在對生產環境進行任何操作之前,強烈建議在一個測試環境中完整演練一遍。同時,請確保服務器B已有完整的、可用的備份。
-
XtraBackup 版本:確保在服務器A(或任何可以訪問A數據庫的機器)上安裝了 Percona XtraBackup 2.4 版本。
-
MySQL 用戶權限:準備一個在服務器A和B上都擁有足夠權限的MySQL用戶(例如
RELOAD,PROCESS,LOCK TABLES,REPLICATION CLIENT等),或者直接使用root用戶。 -
磁盤空間:確保備份目錄、服務器B的臨時目錄和最終數據目錄都有足夠的磁盤空間。
-
innodb_file_per_table:這是最關鍵的前提條件。app1數據庫中所有需要恢復的 InnoDB 表都必須是獨立表空間。請在服務器A和B上都執行以下SQL查詢進行檢查:SHOW VARIABLES LIKE 'innodb_file_per_table';必須確保其值為
ON。如果A服務器上此值為OFF,XtraBackup 無法進行表級別的導出/導入。如果B服務器上此值為OFF,則無法導入表空間。對于MySQL 5.7,該值通常默認為ON。
操作流程
整個過程分為四個主要階段:備份 (A) -> 準備 (A) -> 傳輸 -> 恢復 (B)
階段一:在服務器 A 上執行部分備份
此步驟只備份 app1 數據庫。
-
登錄到服務器A。
-
創建一個用于存放備份的目錄,例如:
mkdir -p /data/backups/app1 -
執行備份命令。
--databases參數是關鍵,它告訴 XtraBackup 只備份指定的數據庫。xtrabackup --backup \ --target-dir=/data/backups/app1 \ --user=your_user \ --password=your_password \ --databases="app1"--target-dir: 指定備份文件的存放路徑。--user/--password: 你的MySQL用戶名和密碼。--databases="app1": 核心參數,指定只備份app1數據庫。如果要備份多個,可以用空格隔開,如"db1 db2"。
操作完成后,
/data/backups/app1目錄下會包含app1數據庫的數據文件和備份元數據。
階段二:準備備份以供導出
這個“準備”步驟非常關鍵。我們需要使用 --export 選項,它會為每個 InnoDB 表生成一個 .cfg 元數據文件,這是在服務器B上導入表空間所必需的。
-
在服務器A上,對剛剛創建的備份執行 "prepare" 操作:
xtrabackup --prepare --export \ --target-dir=/data/backups/app1--prepare: 應用事務日志,使數據文件達到一致狀態。--export: 核心參數,為傳輸表空間做準備,生成.exp和.cfg文件。
-
操作完成后,你可以檢查備份目錄下的
app1子目錄,會看到每個表都有.ibd,.cfg文件。
階段三:將備份文件傳輸到服務器 B
將準備好的備份目錄從服務器A安全地復制到服務器B。
-
使用
scp或rsync命令進行傳輸。rsync更優,支持斷點續傳。# 在服務器A上執行 rsync -avzP /data/backups/app1/ your_user@<服務器B的IP>:/data/restore/- 這會將
app1目錄完整地復制到服務器B的/data/restore/目錄下。
- 這會將
階段四:在服務器 B 上恢復數據庫
這是最精細操作的階段,我們將一步步地將 app1 數據庫導入到服務器B中,而完全不影響B上現有的其他數據庫。
-
在服務器B上創建空的
app1數據庫,編碼需要自定義,這里進行了簡化。
登錄服務器B的MySQL:CREATE DATABASE app1; -
在服務器B上為
app1創建表結構。
我們需要先創建表的“空殼”(即表結構),然后才能導入數據。最簡單的方法是從服務器A導出純表結構。- 在服務器A上執行:
mysqldump --no-data --routines --triggers --events \ -u your_user -p your_password app1 > /tmp/app1_schema.sql - 將
app1_schema.sql文件從服務器A復制到服務器B。 - 在服務器B上導入表結構:
mysql -u your_user -p your_password app1 < /path/to/app1_schema.sql
現在,服務器B上有了一個名為
app1的數據庫,里面包含了所有表,但這些表都是空的。 - 在服務器A上執行:
-
解綁表空間(Discard Tablespace)。
對于app1數據庫中的每一張表,我們需要先解除它與當前空.ibd文件的關聯,為導入做準備。- 登錄服務器B的MySQL,并對每一張表執行:
ALTER TABLE app1.your_table_name DISCARD TABLESPACE; - 如果表很多,可以運行以下SQL生成所有命令,然后復制執行:
SELECT CONCAT('ALTER TABLE ', table_schema, '.', table_name, ' DISCARD TABLESPACE;') FROM information_schema.tables WHERE table_schema = 'app1';
- 登錄服務器B的MySQL,并對每一張表執行:
-
復制數據文件 (
.ibd) 和元數據文件 (.cfg)。- 首先,找到服務器B的MySQL數據目錄(datadir):
通常是SHOW VARIABLES LIKE 'datadir';/var/lib/mysql/。 - 將之前從服務器A傳過來的備份文件復制到B的數據目錄中對應的
app1文件夾下。# 在服務器B的shell中執行 cp /data/restore/app1/*.ibd /var/lib/mysql/app1/ cp /data/restore/app1/*.cfg /var/lib/mysql/app1/
- 首先,找到服務器B的MySQL數據目錄(datadir):
-
修正文件權限。
這是非常容易被忽略但至關重要的一步。新復制的文件屬主必須是mysql用戶。chown -R mysql:mysql /var/lib/mysql/app1/ -
導入表空間(Import Tablespace)。
現在,將這些新的數據文件關聯到表結構上。- 登錄服務器B的MySQL,并對每一張表執行:
ALTER TABLE app1.your_table_name IMPORT TABLESPACE; - 同樣,你可以用SQL批量生成所有命令:
SELECT CONCAT('ALTER TABLE ', table_schema, '.', table_name, ' IMPORT TABLESPACE;') FROM information_schema.tables WHERE table_schema = 'app1';
- 登錄服務器B的MySQL,并對每一張表執行:
-
檢查和授權。
- 檢查數據是否恢復成功。
USE app1; SHOW TABLES; SELECT COUNT(*) FROM your_table_name; - 數據本身已經恢復,但服務器B上的用戶可能還沒有訪問
app1數據庫的權限。根據需要為相關用戶授權。GRANT ALL PRIVILEGES ON app1.* TO 'some_user'@'localhost'; FLUSH PRIVILEGES;
- 檢查數據是否恢復成功。
總結
通過以上步驟,已經成功地將服務器A的 app1 數據庫,在不影響服務器B任何現有數據的情況下,完整地遷移了過去。整個過程的核心是利用了 Percona XtraBackup 的 --databases 部分備份功能和 --export 傳輸表空間功能。
如果需要對單表進行備份和恢復 可以采用如下命令,恢復過程大同小異
xtrabackup --backup --datadir=/var/lib/mysql --target-dir=/data/backups/ \
--tables="^test[.].*"

浙公網安備 33010602011771號