超過 4GB 的大表每日全量備份極其痛苦,Binlog 又可能達 50-60GB/天 影響 IOPS。本文提出「全量基線 + 觸發器邏輯增量」方案:利用 AFTER INSERT/UPDATE/DELETE 觸發器捕獲變更寫入三張日誌表,定期導出 SQL 實現增量備份,避開 Binlog 效能代價。
-- 1. 原始業務表
CREATE TABLE wubx (
id INT AUTO_INCREMENT PRIMARY KEY,
user_id INT NOT NULL DEFAULT 0,
friend_id INT NOT NULL DEFAULT 0,
dir_id INT NOT NULL DEFAULT 0,
created INT NOT NULL DEFAULT 0
) ENGINE=InnoDB;
-- 2. 三張邏輯日誌表(結構同業務表,刪除日誌僅存主鍵)
CREATE TABLE wubx_ii LIKE wubx; -- INSERT 日誌
CREATE TABLE wubx_uu LIKE wubx; -- UPDATE 日誌(REPLACE INTO 去重)
CREATE TABLE wubx_dd (id INT PRIMARY KEY); -- DELETE 日誌
DELIMITER //
-- INSERT 觸發器
CREATE TRIGGER wubx_ii AFTER INSERT ON wubx
FOR EACH ROW BEGIN
INSERT INTO wubx_ii SET
id = NEW.id, user_id = NEW.user_id, friend_id = NEW.friend_id,
dir_id = NEW.dir_id, created = NEW.created;
END//
-- UPDATE 觸發器(REPLACE 保留最新狀態)
CREATE TRIGGER wubx_uu AFTER UPDATE ON wubx
FOR EACH ROW BEGIN
REPLACE INTO wubx_uu SET
id = NEW.id, user_id = NEW.user_id, friend_id = NEW.friend_id,
dir_id = NEW.dir_id, created = NEW.created;
END//
-- DELETE 觸發器
CREATE TRIGGER wubx_dd AFTER DELETE ON wubx
FOR EACH ROW BEGIN
INSERT INTO wubx_dd VALUES (OLD.id);
END//
DELIMITER ;
INSERT INTO wubx VALUES (NULL, 1, 10, 1, 1198464252);
INSERT INTO wubx VALUES (NULL, 1, 11, 1, 1198464252);
INSERT INTO wubx VALUES (NULL, 1, 2, 1, 1198464252);
INSERT INTO wubx VALUES (NULL, 2, 10, 1, 1198464252);
INSERT INTO wubx VALUES (NULL, 2, 12, 1, 1198464252);
INSERT INTO wubx VALUES (NULL, 3, 12, 1, 1198464252);
UPDATE wubx SET dir_id = 5 WHERE user_id = 3;
UPDATE wubx SET dir_id = 4 WHERE user_id = 3;
DELETE FROM wubx WHERE user_id = 2 AND friend_id = 12;
-- 1. INSERT 操作 → REPLACE INTO(冪等)
mysql -e "SELECT CONCAT('REPLACE INTO wubx SET id=', id, ',user_id=', user_id,
',friend_id=', friend_id, ',dir_id=', dir_id, ',created=', created, ';')
FROM wubx_ii" >> backup_ii.sql
-- 2. UPDATE 操作 → UPDATE ... WHERE id=
mysql -e "SELECT CONCAT('UPDATE wubx SET user_id=', user_id, ',friend_id=', friend_id,
',dir_id=', dir_id, ',created=', created, ' WHERE id=', id, ';')
FROM wubx_uu" >> backup_uu.sql
-- 3. DELETE 操作 → DELETE ... WHERE id=
mysql -e "SELECT CONCAT('DELETE FROM wubx WHERE id=', id, ';')
FROM wubx_dd" >> backup_dd.sql
mysqldump 或檔案複製)。backup_ii.sql、backup_uu.sql、backup_dd.sql。CHECKSUM TABLE wubx 對比主從。-- 定時任務:每小時導出增量、清理已備份日誌
DELIMITER //
CREATE PROCEDURE flush_incremental_backup()
BEGIN
-- 導出 SQL(略,同上)
-- 清理已備份資料,保留未備份窗口
DELETE FROM wubx_ii WHERE id <= @last_backup_max_id;
DELETE FROM wubx_uu WHERE id <= @last_backup_max_id;
DELETE FROM wubx_dd WHERE id <= @last_backup_max_id;
END//
DELIMITER ;
| 方案 | 優點 | 缺點 | 適用場景 |
|---|---|---|---|
| 全量 + Binlog | 標準、工具成熟、點對點恢復 | Binlog 巨大、IOPS 高、佔磁碟 | 中小表、已有主從架構 |
| 全量 + 觸發器邏輯增量 | 無 Binlog 壓力、增量 SQL 可讀、可跨版本恢復 | 觸發器微小寫入開銷、需維護日誌表清理 | 大表(>10GB)、不想開 Binlog、異構遷移 |
| xtrabackup 物理備份 | 非阻塞、速度快、支援增量 | 需 Percona 工具、恢復需同版本 | 生產標準備份、大表首選 |